◆ SPEC 7/18 — commutingcost.com redesign pilot (design spec: SEO/GEO/AEO + motion + conversion)
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, repotlcengine/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:
- Render the generated SEO/GEO content fully and server-side (JSON-LD, FAQPage, OG/Twitter, canonical) — verify the FE actually emits it.
- Add the GEO/AEO artifacts that don't exist yet (
llms.txt, sitemap, an answer hub, freshness stamps, a methodology page). - Sharpen GTM/conversion (positioning, CTAs that deep-link the tool, trust/provenance, a light lead hook).
- 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.py→metros_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/standaloneon deploy — known gotcha). - ⚠ PENDING LIVE AUDIT (first implementation step): App Router vs Pages Router; styling stack (Tailwind suspected —
.geo3-map-stageusedhidden 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 /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,781stat 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.xmlroute (ornext-sitemap) enumerating frommetros_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.pyMETROS 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.json— run with/usr/bin/python3(psycopg2 not in the venv; SA-gotcha) against commute DB172.26.1.152:5433. - Add
dateModified/ "data updated" stamp source (generation date) into the record for freshness schema. - Generate
llms.txt+llms-full.txtfrommetros_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-webcode; 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+publicinto.next/standalone(standalone gotcha), restart the pm2 process by its registry name (never guess), verify. Nevergit add -Aon 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/mapshell — and builds the/answershub. - 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.txtvalid;llms.txtreachable. - 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-motiondisables 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+publiccopy; pm2 name fromservice-registry.json; specific-path staging; geo-bundle push route for gpu-pilot, direct push for the web repo with user OK. metros_seoregen 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):
- Editorial — warm cream + clay
#CC7A5C, serif display, drifting gradient. Premium, calm, investor-ready. (= "Claude Design".) - Kinetic — near-black + electric transit palette, blooming isochrone + live ticker. Energetic, playful, shareable.
- 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.