← gpu-pilot · json · source: docs/superpowers/specs/2026-07-18-commutingcost-pilot-design.md

◆ SPEC 7/18 — commutingcost.com redesign pilot (design spec: SEO/GEO/AEO + motion + conversion)

The design spec the plan implements. Approach C — balanced pilot slice: take one fully-realized vertical slice (homepage + metro-page template), do all four layers on it end to end, ship it, then fan the pattern out to the remaining pages and to multimodal + losingground. Defines the four success outcomes (get discovered / convert visitors / delight & shares / investor-ready polish), the GEO and AEO artifact set, the motion inventory with its Core Web Vitals guardrails, and the component kit both pilot pages establish. · updated 2026-07-18 07:39

TL;DR

  • The pilot is NOT 'create SEO from scratch' — build_metros_seo.py already generates per-metro title, meta_description, h1, GEO intro paragraphs, a real faq[] and json_ld_facts from live DB numbers. The work is (1) RENDER it fully and server-side, (2) ADD the missing GEO/AEO artifacts, (3) SHARPEN conversion, (4) LAYER ON motion within a CWV budget.
  • GEO (be cited by ChatGPT/Perplexity/Claude/AI Overviews): llms.txt + llms-full.txt, answer-ready structure with the quotable answer FIRST, an explicit freshness stamp, inline source citations, and a /methodology authority page as the canonical explainer. AEO: question H2s with 40-55 word answer paragraphs, a visible FAQ backed by FAQPage schema, and snippet-friendly comparison tables.
  • HARD CONSTRAINT: motion must not blow Core Web Vitals (LCP<2.5s, CLS<0.1, INP<200ms) because CWV is itself a ranking signal — motion pays for delight AND must protect discovery. All motion is transform/opacity only, gated behind prefers-reduced-motion, and must never delay the LCP element.
  • SPEC CORRECTION recorded by the plan (C-1): spec sections 7/10 mandate /usr/bin/python3 for the data pipeline. That is WRONG — it lacks pyarrow and every new script reads network parquet. Use venv/bin/python. Do not 'fix' the scripts back.
  • Section 11 (design direction) is now CLOSED: Editorial Warm was selected, then extended with the per-page transit-vehicle motion system and GTFS-derived dominant mode. The live reference implementation is at commutingcost.com/preview/design-directions.html.

Design Spec — commutingcost.com Redesign Pilot

SEO / GEO / AEO + Motion Design + Conversion — the vertical-slice pilot

  • Date: 2026-07-18
  • Author: Krishna Malyala + Claude (Opus 4.8)
  • Status: DRAFT — awaiting (a) user pick of visual direction from the mockup, (b) live gap-audit of the deployed FE
  • Approach: C — balanced pilot slice. Do all four layers end-to-end on the homepage + the metro-page template, ship it, then fan the exact pattern out to the rest of commutingcost.com and to multimodal + losingground.
  • Site: commutingcost.com (Next.js, geo3, pm2 commutingcost-web :3035, repo tlcengine/commutingcost-web)
  • Success = all four: get discovered · convert visitors · delight & shares · investor-ready polish.

1. Summary

commutingcost.com already has a strong data spine: content/build_metros_seo.py generates, per metro, a title, meta_description, h1, GEO-optimized intro_paragraphs, a real faq[] (Q&A), and a json_ld_facts object — all from live DB numbers, never invented. The engine serves 62 metros × 9 modes, 151,781 precomputed destinations, sub-second.

The pilot is therefore not "create SEO from scratch." It is four things on two page types:

  1. Render the generated SEO/GEO content fully and server-side (JSON-LD, FAQPage, OG/Twitter, canonical) — verify the FE actually emits it.
  2. Add the GEO/AEO artifacts that don't exist yet (llms.txt, sitemap, an answer hub, freshness stamps, a methodology page).
  3. Sharpen GTM/conversion (positioning, CTAs that deep-link the tool, trust/provenance, a light lead hook).
  4. Layer on the "Claude Design" motion system (animated isochrone hero, count-ups, mode bars, scroll reveals) — within a Core-Web-Vitals budget.

The homepage + /commute-cost/[metro] are the two surfaces. Once locked, the components (<Seo>, <JsonLd>, <Hero>, <MetroCostCard>, <FaqAccordion>, <CountUp>, <Reveal>, <IsochroneBloom>, <Ticker>) are the reusable kit for every other page and the other two sites.

2. Goals & success metrics

Outcome What we ship How we measure
Get discovered SSR JSON-LD (FAQPage + Dataset + Breadcrumb), OG/Twitter + per-metro OG images, canonical/hreflang, sitemap.xml, robots.txt, llms.txt/llms-full.txt, /methodology authority page, 62 metro pages Google Rich Results Test passes; Lighthouse SEO = 100; pages indexed; sample AI queries (ChatGPT/Perplexity/Claude/AI Overviews) cite us
Convert visitors Sharper hero/positioning, primary "Check your commute" CTA deep-linking the tool prefilled per metro, secondary "See the rankings", email hook, analytics events CTA CTR, tool-start rate, email capture rate
Delight & shares Motion system (isochrone bloom, ticker, count-ups, mode bars, hover micro-interactions), premium OG previews Subjective "wow"; OG cards render on X/LinkedIn/iMessage; Lighthouse Best-Practices ≥ 95
Investor polish One cohesive premium brand; /methodology; "Powered by GPU RAPTOR" credibility; consistent tokens Cohesion across the two pilot pages; methodology live

Hard constraint: motion must not blow Core Web Vitals — LCP < 2.5 s, CLS < 0.1, INP < 200 ms — because CWV is itself a ranking signal. Motion pays for delight and must protect discovery.

3. Scope

In (pilot): - The homepage (hero + value props + tool entry + rankings teaser + trust). - The metro-page template /commute-cost/[metro] (one template, all 62 metros). - The shared component kit + design tokens those two pages establish. - Root artifacts: sitemap.xml, robots.txt, llms.txt, llms-full.txt, /methodology, OG image route.

Out (later phases / other tasks): - /map, /compare, /rankings, /TLCcosts, /losing-ground — inherit the kit in Phase 3, not now. - multimodal.certihomes.com + losingground.certihomes.com — Phase 4 replication. - Any GPU-engine, RAPTOR-kernel, or data-model change. No backend changes beyond regenerating metros_seo.json to full 62-metro coverage. - New CRM / auth. Lead capture stays a single email field → existing store (YAGNI).

4. Current state (known; some pending live audit)

  • Data spine (verified in-repo): content/build_metros_seo.pymetros_seo.json. Per metro: seo.{title,meta_description,h1,intro_paragraphs,faq} + json_ld_facts. METROS list currently ~50; network is 62 → reconcile/expand.
  • Positioning (from gtm/): "True Lifestyle Cost" — multimodal + multiuser + true cost vs Google/TravelTime (time-only, 1–2 modes, 1 user). Hook: "$5 gas is hurting families"; flagship = the multiuser two-commuter home-finder; GPU speed = proof, not the hook.
  • App (from prior work): Google-Maps-style redesign done; 2-col homepage (from/to + 9 mode pills left, maplibre right); unified nav + footer; standalone Next build (.next/static + public/ must be copied into .next/standalone on deploy — known gotcha).
  • ⚠ PENDING LIVE AUDIT (first implementation step): App Router vs Pages Router; styling stack (Tailwind suspected — .geo3-map-stage used hidden sm:flex); whether the metro template currently emits server-rendered JSON-LD/FAQPage/OG or only client-side (crawlers + LLMs need SSR); current Lighthouse/CWV baseline. Do not assume — measure against the live geo3 code before writing components.

5. Design layers

5.1 Discovery — SEO / GEO / AEO

Technical SEO (per page, server-rendered): - <title> + meta description from metros_seo (already generated). - <link rel="canonical">; hreflang en-US / en-CA for CA metros; robots index,follow. - Open Graph + Twitter tags + a dynamic per-metro OG image (/og/commute/[metro] via next/og/satori — branded card: metro name + headline cost + "cheapest mode"). Self-contained (no external fonts per CSP habits). - sitemap.xml enumerating homepage + 62 metros + rankings + methodology (from metros_seo.json); robots.txt pointing at it.

Structured data (JSON-LD, SSR — the AEO core): - Homepage: Organization + WebSite w/ SearchAction (sitelinks searchbox) + Service/SoftwareApplication. - Metro page: FAQPage (maps 1:1 from seo.faq[]), Dataset (the cost figures + dateModified + creator + source citations), BreadcrumbList, WebPage. Optional Place for the metro. - Rankings (Phase 3): ItemList / Dataset.

GEO — Generative Engine Optimization (be cited by ChatGPT/Perplexity/Claude/AI Overviews): - llms.txt (root) — curated machine index: what the site is, the 62 metros with page links, the methodology link, data sources, licensing/attribution ask. llms-full.txt — the full factual corpus (all metros' key numbers + FAQ answers) as clean markdown for direct ingestion. - Answer-ready structure on every metro page: the direct quotable answer first ("The median single-trip transit fare in New York is $2.90…"), a TL;DR summary block, comparison tables, an explicit "Data updated " freshness stamp, and inline source citations (GTFS/GBFS/toll authority/SpotHero/CNT H+T). - /methodology authority page — "How we calculate the true cost of commuting" — the canonical explainer LLMs cite; defines every term, every data source, the H+T 45% benchmark. - Entity consistency — one canonical name per metro/agency/mode across pages so engines resolve entities cleanly.

AEO — Answer Engine Optimization (featured snippets / direct answers): - Question H2s (How much does it cost to commute in X?) with a 40–55-word answer paragraph immediately under each. - FAQ accordion (visible + FAQPage schema) from seo.faq[]. - Comparison tables + definition lists (snippet-friendly formats). - A cross-metro /answers hub aggregating the top questions (big long-tail AEO surface) — Phase 3, but its schema/pattern is set here.

Content expansion: reconcile build_metros_seo.py METROS to the full 62-metro network; regenerate metros_seo.json; internal-link metro ↔ rankings ↔ compare ↔ methodology.

5.2 Motion — "Claude Design" (delight)

Design direction: DECISION PENDING (user picks from the 3-way mockup). Default if unspecified = Hybrid: Editorial shell (cream/clay, serif display — the Claude aesthetic; premium + investor-ready) + Kinetic hero motion (blooming isochrone + city-cost ticker — the "dynamic & fun") + Data-Luxe data-viz (tabular numerals, growing mode-bars — conversion-grade credibility). See §11.

Tokens to define (once direction is picked): color roles (bg/paper/ink/accent/data), type scale (display + body + mono numerals), spacing, radius, elevation, motion timing (durations, easing, stagger).

Motion inventory ("interactive moving images"): - Hero: animated morphing isochrone bloom (concentric hexes pulsing outward) + a live city-cost ticker. (Optional stretch: a real animated isochrone frame from the engine.) - Data cards: number count-ups; mode-cost bars that grow on reveal. - Scroll reveals via IntersectionObserver (<Reveal>). - Hover micro-interactions on cards/CTAs.

Guardrails (non-negotiable): - All motion = CSS transform/opacity, GPU-composited, no layout thrash → protect CLS/INP. - Everything gated behind prefers-reduced-motion: reduce (static fallback). - Hero animation must not delay LCP — the LCP element (headline/CTA) renders first; motion enhances after. - Lazy-init below-the-fold motion.

5.3 GTM — Conversion

  • Positioning/hero: lead with True Lifestyle Cost — the dollar truth Google Maps won't show you. Subhead: real fares/tolls/parking · 62 metros · 9 modes · GPU-computed. Value props: multimodal, multiuser, true cost.
  • CTAs: primary "Check your commute" → the tool (on a metro page, deep-link the tool prefilled with that metro/anchor); secondary "See the rankings". Metro pages also get "Calculate your exact commute in →".
  • Trust/credibility: the provenance line ("GTFS · GBFS · toll authorities · SpotHero · CNT H+T — never invented"), the 62 · 9 · 151,781 stat line, a "Powered by GPU RAPTOR" badge, link to /methodology.
  • Lead hook (light): single email field — "Get a monthly true-cost report for your commute" → existing store + analytics event. No CRM build.
  • Analytics: events on CTA click, tool-start, email capture (whatever's already wired; else a minimal client event).

6. Architecture & components

  • Rendering: metro pages are SSG/ISR from metros_seo.json (static props). JSON-LD + answer content + FAQ must be in the server HTML (crawlers + LLMs don't run our client JS reliably). Homepage SSR/SSG likewise.
  • New/updated components (framework-agnostic here; match the live stack after audit):
  • <Seo> — title/meta/canonical/hreflang/OG/Twitter.
  • <JsonLd type> — FAQPage / Dataset / BreadcrumbList / Organization / WebSite.
  • <Hero> + <IsochroneBloom> + <Ticker> — motion hero.
  • <MetroCostCard>, <ModeBars>, <FactGrid>, <FaqAccordion> — the answer surface.
  • <CountUp>, <Reveal> — motion primitives (reduced-motion aware).
  • OG images: /og/commute/[metro] route (next/og). Fallback: pre-generated static PNGs if the route is heavy.
  • Sitemap: /sitemap.xml route (or next-sitemap) enumerating from metros_seo.json.
  • Tokens/theme: shared theme module matching the existing stack (Tailwind config extension or CSS-vars) — established by the two pilot pages.

7. Content pipeline changes

  • Extend content/build_metros_seo.py METROS to full 62-metro coverage (add any network metros missing from the ~50); keep the "omit field if no data, never invent" rule.
  • Regenerate metros_seo.jsonrun with /usr/bin/python3 (psycopg2 not in the venv; SA-gotcha) against commute DB 172.26.1.152:5433.
  • Add dateModified / "data updated" stamp source (generation date) into the record for freshness schema.
  • Generate llms.txt + llms-full.txt from metros_seo.json (new small script, e.g. content/build_llms_txt.py).

8. Rollout plan

  • Phase 0 — Live gap-audit (first step, needs classifier up): pull the geo3 commutingcost-web code; confirm router/stack; check what the metro template actually renders (SSR JSON-LD? OG? FAQ?); capture Lighthouse/CWV baseline. Output = a punch-list of "generated but not rendered."
  • Phase 1 — Build the slice on a preview build: tokens + component kit + both pages, all four layers. Validate on scratch (:3036/preview or local) — not prod.
  • Phase 2 — Ship to prod: build on geo3, copy .next/static + public into .next/standalone (standalone gotcha), restart the pm2 process by its registry name (never guess), verify. Never git add -A on the app dir — stage specific paths.
  • Phase 3 — Fan out: the metro template already covers all 62 metros in the pilot (one SSG template). Phase 3 applies the same kit to the other page types — /rankings, /compare, /TLCcosts, /losing-ground, the /map shell — and builds the /answers hub.
  • Phase 4 — Replicate: port tokens + kit + SEO/GEO pattern to multimodal.certihomes.com (design/motion-led, light SEO shell) and losingground.certihomes.com (motion + ItemList schema on rankings).

9. Testing & validation

  • SEO: Google Rich Results Test (FAQPage + Dataset valid, no errors); Lighthouse SEO = 100; canonical/OG present in view-source; sitemap.xml + robots.txt valid; llms.txt reachable.
  • GEO/AEO: manual — ask ChatGPT / Perplexity / Claude / Google AI Overview a metro cost question; check whether we're cited and numbers match; verify answer paragraphs are snippet-shaped.
  • Core Web Vitals: PageSpeed/Lighthouse mobile — LCP < 2.5 s, CLS < 0.1, INP < 200 ms with motion enabled.
  • Accessibility: axe clean; prefers-reduced-motion disables motion; keyboard nav + focus on tabs/accordions; contrast AA.
  • Visual/responsive: matches the approved mockup direction; mobile verified (Playwright iPhone-13, per the mobile-touch precedent); cross-browser.
  • Data correctness: spot-check 5 metros' on-page numbers vs DB.
  • Regression: the tool + existing routes still work (e.g. 08854→10001 unchanged); nav/footer intact.

10. Risks & open questions

  • Motion vs CWV — mitigated by transform-only, lazy, reduced-motion, LCP-first.
  • JSON-LD must be SSR — if the current template injects it client-side, that's the #1 fix (crawlers/LLMs miss client-only).
  • Unknown live stack — resolved by Phase 0 audit before any component is written.
  • Prod-deploy safety — standalone .next/static+public copy; pm2 name from service-registry.json; specific-path staging; geo-bundle push route for gpu-pilot, direct push for the web repo with user OK.
  • metros_seo regen needs /usr/bin/python3 (psycopg2).
  • Tooling flakiness (mine, not the deliverable): the Anthropic Bash/network classifier is intermittently down and the claude.ai Artifact OAuth token is revoked — affects how I preview/deploy, not the design. Live audit + deploy wait on classifier up-windows.
  • Design direction unresolved — §11.

11. Design direction — PENDING USER PICK

Three directions were mocked up (scratchpad/design_directions.html; to be published at videolens.certihomes.com/r/cc-design-directions.html when the render pipe clears):

  1. Editorial — warm cream + clay #CC7A5C, serif display, drifting gradient. Premium, calm, investor-ready. (= "Claude Design".)
  2. Kinetic — near-black + electric transit palette, blooming isochrone + live ticker. Energetic, playful, shareable.
  3. Data-Luxe — white + indigo #4338CA + emerald, tabular numerals, self-drawing sparkline + growing bars. Precise, fintech-credible, conversion-grade.

Recommendation: Hybrid — Editorial as the base brand, Kinetic's isochrone/ticker for the hero's "dynamic & fun," Data-Luxe's data-viz in the cost cards. Serves all four outcomes at once.

This is the only section that blocks starting implementation. Everything else in this spec is direction-independent.


Appendix A — Pilot page inventory

Page Route Layers touched Key schema
Homepage / all 4 Organization, WebSite+SearchAction
Metro template /commute-cost/[metro] (×62) all 4 FAQPage, Dataset, BreadcrumbList
Methodology /methodology (new) discovery + polish Article/WebPage
OG image /og/commute/[metro] (new) delight/share
Root artifacts /sitemap.xml, /robots.txt, /llms.txt, /llms-full.txt discovery

Appendix B — Metro-page JSON-LD (shape, from existing json_ld_facts + seo.faq)

{
  "@context":"https://schema.org",
  "@graph":[
    {"@type":"FAQPage","mainEntity":[
      {"@type":"Question","name":"How much does it cost to commute in New York?",
       "acceptedAnswer":{"@type":"Answer","text":"The median single-trip transit fare … A daily round trip costs roughly $5.80."}}
    ]},
    {"@type":"Dataset","name":"Cost of commuting in New York",
     "dateModified":"2026-07-18","creator":{"@type":"Organization","name":"CommutingCost"},
     "isBasedOn":["GTFS agency feeds","GBFS","toll authority rates","SpotHero","CNT H+T Index"],
     "variableMeasured":["median transit fare","downtown parking daily","toll range","H+T % of income"]},
    {"@type":"BreadcrumbList","itemListElement":[…]}
  ]
}

Appendix C — llms.txt (shape)

# CommutingCost — the true dollar cost of commuting
> Real fares, tolls, and parking across 62 US + Canada metros, 9 modes, GPU-computed.
> Not time estimates — actual cost. Data from GTFS, GBFS, toll authorities, SpotHero, CNT H+T.

## Methodology
- /methodology: how every number is computed + sources

## Metros (62)
- /commute-cost/new-york: transit $2.90 median, parking $35/day, cheapest mode transit ~$5.80/day
- /commute-cost/chicago: …
  (…all 62, generated from metros_seo.json…)

## Rankings
- /best-transit-cities, /most-walkable-cities, /best-commute-cities

## Attribution
Cite as "CommutingCost (commutingcost.com)". Figures updated monthly.

Comments