- Penalty shootout panel: shootout-flagged events get a kicker-by-kicker
dot strip on the Summary tab (and stay OFF the timeline/running score).
Parsing is defensive — validate against the first real shootout June 28.
- Road to the final on team profiles: the model's projected knockout run
(teamPath in whatif.ts forces the team through the model bracket) with
per-round reach probabilities and a title-chance chip. Teams the model
doesn't project through still get a hypothetical runner-up road.
- Match videos: ESPN summaries carry per-match clips (SUMMARY_V=5 keeps
headline/duration/thumbnail/link) — a Videos card on the Summary tab,
clips open on ESPN. Tokenless; replaces the parked ScoreBat idea.
- ICS calendar export: /api/calendar.ics[?team=X] (RFC 5545, escaped,
folded, CRLF) + an Add-to-calendar chip on team pages.
- Injuries plumbing (dormant until API_FOOTBALL_KEY is set): twice-daily
API-Football sweep into the injuries table, surfaced on team profiles
and the match availability banner next to suspensions.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- /stats: FotMob tournament boards (goals/assists/rating/xG player+team
categories from the data.fotmob.com CDN, capture-first via scheduler),
Golden Boot race with DraftKings anytime-line benchmark from the
already-captured scorer props, and an attack-vs-defence xG scatter.
- Discipline engine (src/lib/discipline.ts): FIFA suspension rules folded
from stored event feeds — red/second-yellow bans, two-yellow accumulation,
post-QF wipe. Surfaces on /stats, team profiles and match lineups tabs.
- In-play win probability now accounts for red cards (10 men: own rate
x0.67, opponent x1.15 per card) on the server tick and the match page.
- Fix ModelDiary infinite render loop (unstable zustand snapshot while the
model loads crashed the Methodology route under React 19).
- Drop dead tables squad + goalscorers; scorer_props is now read.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Finished matches show the STARTING XIs on the pitch (red markers with
the minute on everyone subbed off) with 'Subbed on' / 'Subbed off'
lists below, minutes and ratings included; live matches keep the
current-XI view that swaps substitutes in
- Title-race chart gets a sort toggle, defaulting to 'Biggest movers'
(the teams whose odds changed most at the latest update — what's
relevant now) with 'Title favorites' as the alternative
- Entering what-if on the bracket now pre-fills the model's most likely
tournament: group slots seeded from win-group/advance odds (best-
thirds assigned to their allowed slots via backtracking), every
pairing picked by the model — a complete overview to edit by tapping;
Reset returns to the projection
- Team fixtures drop the US 'vs/@' convention: always 'vs' plus an H/A
badge with a tooltip
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fully progressive: without VAPID keys in the environment the API says
404, the bell never renders, and the service worker addition (a push
handler via workbox importScripts — no SW strategy change) is inert.
With keys: a bell on each team page requests permission, subscribes
(one team per device) and the server diffs fixture states on every
broadcast to push Kickoff / Goal / Full time to that team's followers.
Dead endpoints (404/410) self-clean. Round-trip verified locally with
dev VAPID keys; disabled mode verified too.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
buildRatings samples each WC team's rating along the full walk (yearly
historically, monthly since 2022) into elohistory.json (~72KB, 48
teams). Team pages plot it as a clean SVG line with year and rating
gridlines — Germany's century, 1908 → today, in one glance.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A star on the team page (localStorage, no accounts) pins that team's
next or running match in a My team section at the top of the Live tab.
EN/DE strings + aria-pressed on the toggle.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Bracket on phones: a segmented round picker with full-width cards
replaces the 1040px sideways scroll; desktop keeps the columns.
- Odds table: sticky team column; the three lowest-value columns hide
on phones so Team/QF/SF/Final/Champion fit without scrolling.
- Bottom nav: 4 primary tabs + a More sheet (vs Markt, Modell, Story,
Teams, Daten, plus language & theme toggles) — 7 tabs were cramped.
- Emoji → icons: timeline events use a ball icon, card-shaped color
chips and substitution arrows; unknown-team fallbacks use a shield.
Country-flag emojis stay (intentional).
- Readability: bigger scores on match cards, minimum text sizes bumped,
probability-number triple hides on the narrowest screens (the bar
carries the information).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A tiny typed i18n layer (no library): en.ts is the single source of UI
copy and the clarity rewrite lives there — shorter sentences, plain
words, the dense Methodology/Scoreboard copy untangled. de.ts mirrors
its shape exactly, enforced by the compiler, with placeholder parity
covered by tests. Every page now reads from the dictionary via useT();
dates flip locale through useFormat() (en-GB/de-DE); raw server values
(status, outcome, stage) map through total records.
The header gains an EN/DE toggle (persisted, defaults from the
browser language); <html lang> stays in sync.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Match cards surface the model's pre-match expectation (favoured team + win%).
- Everything is now clickable: group-table + odds-table team rows → team
profiles; bracket matches → match pages; match ↔ team cross-links.
- New /teams hub: all 48 nations ranked by title odds, linking to profiles
(reachable from Groups + every team link; back-links point here).
- Predict → Methodology link ('How & how accurate'); cohesive hover/transition
polish across cards.
- 26 tests pass; build clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>