From f0792f37862aebfc608c59d37f3d3cc21ef46589 Mon Sep 17 00:00:00 2001 From: profilesearch <222277199+profilesearch@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:49:50 -0700 Subject: [PATCH] refactor(frontend): simplify public marketplace experience --- .github/workflows/ci.yml | 2 + backend/test_deep_audit_regressions.py | 152 +++-- docs/design-system/public-shell.md | 28 +- frontend/404.html | 6 +- frontend/about.html | 6 +- frontend/agent-onboarding.html | 6 +- frontend/ai-agents-need-human-auditors.html | 6 +- frontend/ai-assistant-human-checks.html | 6 +- .../ai-human-qa/ai-agent-task-review.html | 6 +- .../ai-citation-source-verification.html | 6 +- .../ai-data-labeling-and-cleanup.html | 6 +- .../ai-hallucination-fact-checking.html | 6 +- .../ai-output-verification-checklist.html | 6 +- .../ai-human-qa/ai-website-qa-testing.html | 6 +- .../hire-human-ai-qa-reviewers.html | 6 +- .../human-in-the-loop-ai-quality-control.html | 6 +- frontend/ai-human-qa/index.html | 6 +- .../ai-human-qa/product-content-human-qa.html | 6 +- .../rag-groundedness-human-review.html | 6 +- .../ai-human-qa/support-reply-human-qa.html | 6 +- frontend/ai-integration.html | 14 +- frontend/ai-marketplace.html | 6 +- frontend/ai-qa-buyer-brief.html | 6 +- frontend/ai-qa-example-deliverables.html | 6 +- frontend/ai-qa-report-template.html | 6 +- frontend/ai-qa-reviewer-badges.html | 6 +- frontend/ai-qa-reviewer.html | 6 +- frontend/ai-qa-service-templates.html | 6 +- frontend/ai-qa-services.html | 6 +- frontend/ai-qa-share-cards.html | 6 +- frontend/ai-qa-task-generator.html | 6 +- frontend/ai-qa-trust-policy.html | 6 +- frontend/api-docs.html | 6 +- frontend/blog/ai-agent-marketplace-guide.html | 6 +- .../blog/ai-agents-changing-gig-economy.html | 6 +- frontend/blog/alternatives-to-fiverr.html | 6 +- frontend/blog/alternatives-to-freelancer.html | 6 +- frontend/blog/alternatives-to-toptal.html | 6 +- frontend/blog/alternatives-to-upwork.html | 6 +- .../blog/best-freelance-platforms-escrow.html | 6 +- .../best-platforms-advertise-side-gig.html | 6 +- ...mplete-guide-hiring-virtual-assistant.html | 6 +- .../fiverr-vs-upwork-vs-gohirehumans.html | 6 +- .../blog/freelance-vs-full-time-2026.html | 6 +- ...lancers-switching-lower-fee-platforms.html | 6 +- .../blog/gig-economy-statistics-2026.html | 6 +- frontend/blog/gohirehumans-vs-fiverr.html | 6 +- frontend/blog/hire-data-entry-specialist.html | 6 +- frontend/blog/hire-human-for-ai-tasks.html | 6 +- .../how-to-find-human-workers-ai-tasks.html | 6 +- frontend/blog/how-to-hire-ai-agent.html | 6 +- .../blog/how-to-hire-ai-agents-safely.html | 6 +- frontend/blog/human-as-a-service.html | 6 +- frontend/blog/index.html | 6 +- frontend/blog/marketplace-pulse-2026-w18.html | 6 +- frontend/blog/mcp-for-marketplaces.html | 6 +- .../blog/on-demand-workforce-platform.html | 6 +- frontend/blog/state-of-ai-workforce-2026.html | 6 +- .../blog/verified-freelancer-marketplace.html | 6 +- .../blog/where-to-list-services-online.html | 6 +- frontend/categories/data-entry.html | 6 +- frontend/categories/graphic-design.html | 6 +- frontend/categories/index.html | 6 +- frontend/categories/translation.html | 6 +- frontend/categories/virtual-assistant.html | 6 +- frontend/categories/web-development.html | 6 +- frontend/categories/writing.html | 6 +- frontend/changelog.html | 6 +- frontend/compare.html | 6 +- frontend/earn/get-paid-for-human-tasks.html | 14 +- frontend/earn/open-paid-tasks.html | 6 +- frontend/examples/sample-deliverables.html | 6 +- frontend/faq.html | 6 +- frontend/hire/ai-reviewers.html | 6 +- frontend/hire/hire-ai-agent.html | 6 +- frontend/hire/hire-ai-developer.html | 6 +- frontend/hire/hire-bookkeeper.html | 6 +- .../hire/hire-customer-support-agent.html | 6 +- frontend/hire/hire-data-entry-clerk.html | 6 +- frontend/hire/hire-data-entry-specialist.html | 6 +- frontend/hire/hire-freelance-writer.html | 6 +- frontend/hire/hire-frontend-developer.html | 6 +- frontend/hire/hire-graphic-designer.html | 6 +- frontend/hire/hire-seo-specialist.html | 6 +- frontend/hire/hire-social-media-manager.html | 6 +- frontend/hire/hire-translator.html | 6 +- frontend/hire/hire-video-editor.html | 6 +- frontend/hire/hire-virtual-assistant.html | 6 +- frontend/hire/hire-web-developer.html | 6 +- frontend/hire/index.html | 6 +- frontend/hire/lead-researchers.html | 6 +- frontend/hire/local-verification.html | 6 +- frontend/hire/phone-call-help.html | 6 +- frontend/hire/website-testers.html | 6 +- frontend/how-it-works.html | 14 +- frontend/ideas.html | 6 +- frontend/index.html | 622 +++++++----------- frontend/instagram.html | 6 +- frontend/managed-ai-qa.html | 6 +- frontend/partials/public-footer.html | 8 +- frontend/partials/public-nav.html | 6 +- frontend/post-a-small-task.html | 16 +- frontend/press.html | 6 +- frontend/pricing.html | 186 +----- frontend/proof-packs.html | 14 +- frontend/request-any-task.html | 6 +- frontend/request-managed-ai-qa.html | 6 +- frontend/roadmap.html | 6 +- frontend/services.html | 6 +- frontend/starter-offers.html | 133 ++-- frontend/stats.html | 14 +- frontend/style.css | 344 +++++++--- frontend/task-ideas.html | 6 +- frontend/tests/browser-regression.spec.js | 237 ++++++- frontend/tools/are-you-overpaying.html | 6 +- frontend/tools/fee-calculator.html | 6 +- frontend/tools/freelance-fee-calculator.html | 6 +- frontend/tools/index.html | 6 +- frontend/trust-safety.html | 176 ++--- .../ai-agent-human-in-the-loop-tasks.html | 6 +- .../use-cases/ai-output-fact-checking.html | 6 +- .../use-cases/data-cleanup-human-review.html | 6 +- .../hire-human-to-review-ai-output.html | 14 +- .../hire-human-to-test-signup-flow.html | 6 +- .../hire-someone-to-test-my-website.html | 6 +- .../human-ai-output-verification.html | 6 +- .../use-cases/human-fact-checkers-for-ai.html | 6 +- .../use-cases/human-qa-for-automations.html | 6 +- .../human-review-for-chatbot-responses.html | 6 +- frontend/use-cases/index.html | 14 +- .../lead-research-human-verification.html | 6 +- .../use-cases/lead-research-microtask.html | 6 +- .../use-cases/local-verification-tasks.html | 6 +- .../microtask-marketplace-for-businesses.html | 6 +- .../pay-someone-to-make-phone-calls.html | 6 +- .../source-checking-for-ai-research.html | 6 +- frontend/use-cases/verify-ai-research.html | 6 +- frontend/use-cases/website-qa-task.html | 6 +- frontend/vs/fiverr.html | 6 +- frontend/vs/freelancer.html | 6 +- frontend/vs/index.html | 6 +- frontend/vs/toptal.html | 6 +- frontend/vs/upwork.html | 6 +- scripts/check_public_shell.py | 10 +- scripts/sync_public_shell.py | 124 ++++ 145 files changed, 1491 insertions(+), 1395 deletions(-) create mode 100644 scripts/sync_public_shell.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29af6c8..c08c858 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,6 +35,8 @@ jobs: run: python backend/security_static_checks.py - name: Public shell guardrails run: python scripts/check_public_shell.py + - name: Public shell synchronization + run: python scripts/sync_public_shell.py --check - name: Performance budgets run: python scripts/performance_budget.py diff --git a/backend/test_deep_audit_regressions.py b/backend/test_deep_audit_regressions.py index e5e1c55..162eaf8 100644 --- a/backend/test_deep_audit_regressions.py +++ b/backend/test_deep_audit_regressions.py @@ -1081,8 +1081,10 @@ def test_first_task_wizard_and_measurement_invariants(self): "lead_qualification: {", "homepage_describe_task_primary_click", "Describe your task", - "Guided first-task wizard", - "Trust before payment", + 'data-simplified-home="true"', + 'id="guided-task-intake"', + "Build a task draft", + 'data-home-section="how"', "first_task_wizard_started", "first_task_template_selected", "first_task_wizard_review_draft_click", @@ -1208,7 +1210,8 @@ def test_phase2_ui_flow_polish_invariants(self): "id=\"apply-portfolio-url\"", "New listing", "services-result-count", - "Filter services", + 'data-filter-toggle', + "function toggleServiceFilters(forceOpen)", "Keep payments on-platform", "You can apply to jobs before connecting payouts.", "grid-template-columns:repeat(auto-fit,minmax(240px,1fr))", @@ -1248,7 +1251,7 @@ def test_audit_redacts_sensitive_details_recursively(self): def test_trust_safety_page_covers_payment_and_dispute_safety(self): text = (REPO_ROOT / "frontend/trust-safety.html").read_text(encoding="utf-8", errors="ignore").lower() - required = ["stripe-powered processing", "payment review", "issue review", "off-platform", "dispute"] + required = ["stripe-powered processing", "payment review", "issue review", "off-platform", "available evidence", "dispute"] missing = [snippet for snippet in required if snippet not in text] self.assertEqual(missing, []) @@ -1608,28 +1611,33 @@ def test_admin_worker_activation_notifications_create_in_app_notifications(self) def test_jobs_page_highlights_worker_activation_path(self): text = (REPO_ROOT / "frontend/index.html").read_text(encoding="utf-8", errors="ignore") for snippet in [ - "New paid jobs", - "Apply directly through GoHireHumans", - "Newest open jobs are shown first", + "No public jobs right now", + "Create a worker profile", + "open job${total === 1 ? '' : 's'} ยท newest first", "worker_jobs_apply_cta_click", "worker_job_card_apply_click", "Apply now", "const sortedJobs = [...jobs].sort", ]: self.assertIn(snippet, text) + for contradictory in ["New paid jobs", "View open jobs"]: + self.assertNotIn(contradictory, text) def test_public_homepage_visual_cleanup_invariants(self): text = (REPO_ROOT / "frontend/index.html").read_text(encoding="utf-8", errors="ignore") for snippet in [ - "Human verification", - "Choose the fastest proof-backed check.", - "Trust before payment", - "For workers and agents", + 'data-simplified-home="true"', + "Describe the work. Hire the right human.", + "What do you need help with?", + "Clear scope, visible evidence, buyer approval.", + "A clear route for workers and agents.", "homepage_describe_task_primary_click", "homepage_high_intent_route_click", ]: self.assertIn(snippet, text) + self.assertEqual(text.count('data-home-section="'), 5) + self.assertNotIn("Four ways to start small.", text) self.assertNotIn("GA4 shows visitors", text) self.assertNotIn("High-intent visitors", text) @@ -1639,7 +1647,7 @@ def test_market_discovery_pages_capture_open_ended_demand(self): "lp-market-discovery", "homepage_request_any_task_click", "homepage_task_ideas_click", - "Describe any task you need a human to check.", + "Describe any task you need a human to do or check", ], "frontend/ideas.html": [ "What should people hire humans for?", @@ -1694,23 +1702,23 @@ def test_high_intent_seo_pages_feed_starter_offer_funnel(self): def test_first_orders_conversion_infrastructure_is_discoverable(self): required = { "frontend/index.html": [ - "lp-first-orders-proof", "homepage_starter_offers_click", "homepage_sample_deliverables_click", + "homepage_proof_packs_click", "What a strong application says", "job_application_cover_focus", ], "frontend/starter-offers.html": [ - "Human verification for AI work before you trust it.", + 'data-starter-simplified="true"', + "Start small when the work needs proof.", "starter_offer_draft_click", - "Choose by the risk you need checked", - "starter_problem_route_click", "AI Output Verification", "Automation QA Sprint", "Real-World Check", ], "frontend/pricing.html": [ - "Start with proof, then scale.", + 'data-pricing-order="fee-first"', + "Prefer a fixed starting point?", "pricing_proof_first_cta_click", "lead_research", ], @@ -1744,12 +1752,11 @@ def test_first_orders_conversion_infrastructure_is_discoverable(self): def test_growth_activation_pages_and_homepage_proof_are_discoverable(self): required = { "frontend/index.html": [ - "lp-first-orders-proof", "homepage_starter_offers_click", "homepage_sample_deliverables_click", "homepage_high_intent_route_click", - "Trust before payment", - "For workers and agents", + "Clear scope, visible evidence, buyer approval.", + "A clear route for workers and agents.", ], "frontend/post-a-small-task.html": [ "Humans who verify what your AI produces", @@ -2142,13 +2149,17 @@ def test_sitemap_noindex_guard_recognizes_attribute_order_and_directive_tokens(s def test_sitemapped_html_pages_use_single_canonical_public_nav(self): expected_labels = [ "GoHireHumans", - "Starter QA", "Marketplace", - "For Workers", + "Find Work", "For Agents", "Pricing", "Trust", "Sign in", + "Post a task", + ] + expected_mobile_labels = [ + "Marketplace", "Find Work", "For Agents", "Pricing", "Trust", + "Starter Offers", "Use Cases", "FAQ", "Sign in", "Post a task", ] failures = [] for rel in self._sitemapped_html_pages(): @@ -2172,6 +2183,10 @@ def test_sitemapped_html_pages_use_single_canonical_public_nav(self): missing.append("first nav uses canonical lp-nav + aria label") if labels[:8] != expected_labels: missing.append(f"top nav labels {labels[:8]!r}") + mobile = re.search(r'
', text, flags=re.S | re.I) + mobile_labels = self._nav_labels(mobile.group(1) if mobile else "") + if mobile_labels != expected_mobile_labels: + missing.append(f"mobile nav labels {mobile_labels!r}") if '