Tags

Next.js 15React 19TypeScriptTailwind CSS 4sportseditorialnextjsmobile

NinetyPlus is a matchday-programme-styled field guide that turns World Cup fandom into a year-round club soccer habit. Pick the national teams and marquee players you followed at the World Cup, and it surfaces where they play domestically the rest of the year — including the women's club sharing the same crest, building a bridge toward the 2027 Women's World Cup in Brazil.

One Journey, One Route

The entire app is a single route with two states, plus overlay sheets instead of extra pages:

1. Onboarding — "Who did you watch this summer?" with nation rows and horizontally-scrolling marquee-player chips. A sticky ticker CTA confirms picks into localStorage with a rolling-digit count.

2. Your Guide — a scrolling feed of sticker cards (one per followed athlete) interleaved with up to three computed "Connection Moment" callouts, closing with a dark countdown band toward Brazil 2027.

There's no tab bar. Three destinations exist as on-demand bottom sheets instead: an Explainer sheet for any league/tournament name (who participates, how it works, why it matters), an Athlete sheet with enrichment facts and derived connections, and a full-screen Search overlay.

Knowledge Graph, Not a Database

There's no backend — the entire content graph (15 leagues/tournaments, 25 clubs cross-linked men's/women's via 8 club crossovers, 43 athletes, 15 gender-scoped nations, 30 curated relationship edges) is a hardcoded, cross-referenced object graph in data/index.ts. Relationships that can be derived — club teammates, national teammates, league peers, compatriots playing abroad — are computed by selector functions rather than stored; only facts the schema can't express (a specific transfer, a rivalry, a shared title) are hand-curated as Relationship edges.

A custom validation script (npm run validate-data) checks the graph for duplicate ids, unresolved foreign keys, gender mismatches, missing explainer coverage, crossover stars who aren't actually on their listed club, and prose sanity — run after every data edit alongside tsc --noEmit.

Design System

A "matchday programme / sticker album" aesthetic: paper-white canvas, near-black ink, one accent color (pitch green) reserved strictly for interactive state — selected chips, the CTA, countdown captions. Athlete cutouts are true transparent-background PNGs produced with background-removal from press photos, the only element in the app allowed a drop shadow. Archivo variable font drives all display type; system SF stack handles body copy. Capped at a 430px mobile viewport — no responsive breakpoints, since the whole product is designed mobile-only.

Tech Stack

Next.js 15 App Router, React 19, TypeScript, Tailwind CSS 4 via @theme design tokens (no tailwind.config file — everything lives in globals.css). No database, no test suite — user state is a single localStorage key, and content correctness is enforced entirely by the validation script.