the chip nobody saw coming —
Panenka
Football statistics, elevated. Results alone say little about who is actually performing, and raw totals are unfair across positions and small samples.
Live commentary
how a match becomes a season of stats
- 3′
Team sheet
Log a match — score, and each player's rating, goals, assists and MOTM — validated with Zod and saved in one transaction.
- 17′
Service layer
Only the service layer touches the database; UI and MCP handlers go through it, enforced by a lint rule.
- 34′
Pure stats
Streaks, splits, records and form trends are pure functions with no I/O.
- 58′
Rating model
Nine per-game metrics are shrunk toward their group, z-scored within role, weighted per position and scaled to an OVR.
- 76′
Everything else
Attributes, tiers, archetypes, keywords, seasons and the Ballon d'Or build on top — and feed the pages and the MCP server.
Starting five
tap a player for the scouting report
Collectible cards
OVR, tier, six attributes, archetype and a holographic foil that tilts with the pointer.
Tactics board
Position-fair rating
Sample-size shrinkage and per-position weight recipes — wingers are only compared with wingers.
src/lib/stats/rating-model.ts ↗Lint-enforced boundaries
UI and MCP code can only reach data through the service layer.
.eslintrc.json ↗Keyword engine
Ladders, feats and keywords minted per opponent, competition and season.
src/lib/stats/keywords.ts ↗The squad
| 1 | Next.js 14 | Frontend |
| 2 | React 18 | Frontend |
| 3 | Tailwind | Frontend |
| 4 | shadcn/ui | Frontend |
| 5 | Recharts | Frontend |
| 6 | Server Actions | Backend |
| 7 | Prisma | Backend |
| 8 | Zod | Backend |
| 9 | PostgreSQL 16 | Data |
| 10 | Docker Compose | Data |
| 11 | MCP SDK | AI & tests |
| 12 | Vitest | AI & tests |
Validate startup ideas with evidence, not opinions.