Inspiration
Elena, 42, a parent in Cobb County, Georgia, gave up after three hours searching for a local Paralympic role model to inspire her daughter — and never knew that three Team USA athletes actually share her ZIP code, but every public atlas stopped at the state line so she had no way to find them. State-level maps exist. Athlete finders exist. None of them combine the data, treat Olympic and Paralympic equally, or work at the county level — the level where local pride lives. The structural fact under Elena's search: 4 in 5 U.S. counties show no Team USA athlete representation in our 2016–2024 indexed sources. 2,667 counties are silent, and 68% of small counties under 250,000 people are quietly out-performing the major metros in Paralympic representation rates — a signal nobody is looking at.
What it does
Hometown Pathway Atlas is a single per-county lens for Olympic and Paralympic representation. Type a ZIP. Atlas resolves it to county FIPS — the analytical unit nobody else uses for this question — then surfaces:
- Per-capita parity — Olympic and Paralympic shown side-by-side, never merged. Empirical Bayes shrinkage so a small county doesn't blow up the signal or get drowned by megacounties.
- Three peer counties matched by athlete profile (40%), sport mix (35%), and climate (25%). Weighted, MSA-diversified, explained per dimension in the UI.
- Pattern Gaps — three categories per spec (observed strength / public access signal / opportunity hypothesis), every claim conditionally phrased.
- Compliance Log ★ — every Gemini-generated narrative passes a hybrid auditor (deterministic regex + Gemini semantic causal-tone analysis) before it reaches the user. The audit log streams live in the UI. Judges can watch it catch a draft like "Cobb County PRODUCES Olympic athletes" and rewrite it to "could be associated with Olympic representation patterns." Live. Visible. Auditable.
- RegionQA — Ask the Atlas (Layer C). Below the analog narrative, a Gemini-powered Q&A panel lets the user ask any natural-language question about the visible region. Reasoning chain visible step-by- step, parallel to the Compliance Log audit-stream pattern but at the core UX layer. Conditional phrasing enforced by the same hybrid auditor before responses reach the panel.
How we built it
Frontend: React 19 + Vite 8 + TypeScript strict + Tailwind v3 with a custom Atlas Editorial palette. Framer Motion 12 drives the motion choreography (Compliance Log streaming, fail→fixed in-place crossfade). react-simple-maps 3 renders the US choropleth via the us-atlas TopoJSON. Sonner 2 handles error toasts. @tanstack/react-query 5 manages data fetching with hackathon-tuned defaults (5min staleTime, no refetch on window focus, custom retry that skips 4xx).
Backend: FastAPI + Python 3.12 + Pydantic v2 with strict typed I/O. County profiles, similarity matrix, climate signatures, and Move United chapter coverage are precomputed into Apache Parquet at build time and loaded at startup. Runtime is fast lookup, not live ETL. Frontend hits four real endpoints live: POST /api/region (ZIP → RegionResponse), GET /api/analogs/{fips} (3 peer counties with similarity breakdown), GET /api/pathway/{fips} (3 Pattern Gap categories), GET /api/stats/county/{fips} (CountyMap hover lookups). Backend Pydantic schemas are the authoritative shared contract; frontend TypeScript mirrors them 1:1.
AI: Vertex AI Gemini 2.5 Flash is wired into the backend via
the official Python SDK and initialized at FastAPI startup
(backend/main.py lifespan). GeminiService (backend/services/
gemini_service.py) calls enrich_region + enrich_analogs on
every region/analogs route response — generates narrative prose +
tradeoff_explanation + per-analog narrative under structured-output
JSON schemas. HybridAuditor (backend/services/auditor.py) wraps
each Gemini output with a deterministic regex layer + a Gemini
semantic causal-tone layer, rewriting drift before serving. Frontend
renders whatever the backend emits — the Compliance Log streams the
live audit entries. RegionQA Layer C is wired against the live
/api/region/qa route — GeminiService.qa() returns reasoning steps,
final answer, confidence, and a source flag; the eyebrow flips to
"Live Gemini" only on a real Vertex call. Backend response shape
(narrative, narrative_source, tradeoff_explanation,
tradeoff_source, compliance_log, before/after fields on fixed
entries) is the authoritative contract — frontend TypeScript mirrors
it 1:1. Source flags propagate through to the UI eyebrow so the
"Live Gemini" attribution never fires on deterministic fallback
prose, even if the backend HybridAuditor swaps Gemini's draft for
the safe fallback after exhausting rewrite attempts.
Hosting: Google Cloud Run in us-central1 (frontend nginx:alpine, backend python:3.12-slim). Artifact Registry + Cloud Build CI.
Accessibility: axe-core/Playwright sweep across hero, results, and mobile (375x812). Zero WCAG 2.1 AA violations across all three surfaces. Custom focus-visible ring on Tab-reachable map counties. Sr-only role=status announcer for the Compliance Log fail→fixed transition (live AT-accessible, not just visual).
Challenges we ran into
Parity discipline. Olympic and Paralympic must be visually and analytically symmetric. Every component shows them side-by-side, never merged. Every metric carries an evidence-strength label. The locked decision: never collapse them into a single number. Holding this discipline across 17 components meant catching three near-violations during cold-check rounds.
Conditional phrasing as a UI rule, not a vibe. No causal language about geography ever reaches the user. Banned verbs ("produces", "creates", "leads to") are deterministically caught by regex layer 1. Semantic causal tone is caught by Gemini layer 2. The audit happens in real time, in front of the judge, in the Compliance Log. This is the Pillar 4 differentiator — making AI safety a UI surface, not a postmortem document.
Pillar 5 number sourcing. Our first pass had three numbers we thought were sourced. Cold-check round 3 web-verified each against the cited reports and caught all three: TAM was children not households (Aspen Institute), NFHS school count was 19,983 not 13K, NGB recruitment "6,000" was a model not a citation. Corrected and labeled honestly.
Three-round cold-check pattern. We ran a Codex + Claude reviewer
- web-verify fan-out after every major component ship. Round 1 caught design-pattern issues, round 2 caught runtime-boundary failures, round 3 caught content-sourcing errors. Across the project this caught 30+ issues that would have shipped to judges otherwise.
Accomplishments we're proud of
- Compliance Log ★ — Pillar 4 demo moment. Live judge-visible AI
safety surface. HybridAuditor (Vinh task 2.9, shipped 2026-05-03)
populates
compliance_logon every region call — deterministic regex layer + Gemini semantic causal-tone analysis + rewrite loop. Frontend renders entries live with FLAGGED/REWRITTEN badges on fail→fixed transitions. Zero code change at the flip from scripted demo to live audit; the prop was data-aware from day one. - Source-citation tooltip system — every visible number on the results view (17 metrics) hover-reveals its source citation: per- pillar parity methodology, Climate / Sport mix / Adaptive Access source datasets, similarity-dimension weights with their CLAUDE.md locked-decision references, NGB lighthouse program URLs. NYT Upshot / Bloomberg / Pudding citation pattern.
- Per-capita parity discipline — every analytical view treats Olympic and Paralympic symmetrically. No exceptions.
- Zero axe-core WCAG 2.1 AA violations across hero, results, and
mobile. Caught a tailwind-merge silent bug along the way that was
stripping
text-stat-mdwhen colliding withtext-olympic-blue— ParityPanel stats were rendering 16px on mobile instead of 28px. Fixed with a custom font-size classGroup. - Pillar 5 numbers locked + sourced + defensible. TAM (~50M children, Aspen Project Play State of Play 2024), deployment surface (~20,000 NFHS-affiliated high schools, NFHS 2023-24), annual signal (modeled ~6,000 NGB recruitment positions per year), per-incident harm (Beat the Streets Tier 1 startup-year cost $35K-$70K), three named lighthouse-pilot NGBs (USA Wrestling, USA Swimming, USA Track & Field) with sourced unit economics. Pre-pitch defensibility checklist documented + pre-commit drift CI keeps doc + code in sync.
What we learned
- Cold-check pattern works. Codex (different model fingerprint) + Claude code-reviewer (project conventions) + general-purpose web verify (sources) catches different classes of issues. Three rounds per component is the right cadence for a 10-day build.
- Conditional phrasing is a hard rule, not a soft preference. Once we put the auditor between Gemini and the user, the conditional phrasing rule became enforceable, not aspirational.
- NotebookLM as a pre-pitch oracle. It flagged Pillar 5 as our weakest pitch axis on Day 5. Without that flag we would have shipped Pillar 5 with placeholder numbers. Worth using earlier next time.
What's next
- Layer A — Shocking Stat Hunt (shipped). "4 in 5 U.S. counties show no Team USA athlete representation in our 2016–2024 indexed sources" lands on the HeroStat as live data via /api/stats/global. Live numerator + denominator visible on the methodology page alongside the 68% small-county Paralympic underdog finding.
- Layer B — Editorial polish (shipped). SourceTooltip primitive surfaces source citations on every metric (NYT/Pudding pattern). Atlas-branded favicon + OG image + per-route meta. Per-FIPS document.title sync. Replay-audit button on the Compliance Log header. /about methodology page. Sound design recipe in docs/sound_design.md for Day 9 recording.
- Layer C — Reasoning-Chain Q&A (shipped live). RegionQA panel
in the results view fires against the live
/api/region/qaroute. Question input + visible reasoning chain + final conditional-phrased answer + suggested-question chips. Backend returns asourceflag so the "Live Gemini" eyebrow only fires on a verified Vertex call — fallback responses (quota / IAM / deadline / auditor swap) render with a "Design preview" eyebrow instead. - Layer D — Embedded scrollytelling editorial. 3–4 chapters walking through the most surprising findings, anchored on Layer A.
Log in or sign up for Devpost to join the conversation.