Commit Graph

11 Commits

Author SHA1 Message Date
NilsBriggen 0fd13d4c24 Players become first-class: profile pages, unified names, deeper match data
- /player/:name pages assembled entirely from stored data: tournament
  totals, per-match log (rating, minutes, G/A, cards), aggregated shot
  map, suspension status, next-match scorer line. Either source's
  spelling resolves to the same page (token-set + romanization fold).
- Player names are now links everywhere: stats boards, golden boot,
  discipline, injuries, all-time scorers, lineups, the pitch dots,
  timeline events and assists, and the search palette (diacritic-folded).
- Golden Boot displays the FotMob form of each name — no more
  "Hwang In-Beom" and "In-Beom Hwang" on the same page.
- Match pages: detailed full-time stats card (passes, duels, xGOT… from
  the stored FotMob report), O/U + spread closing line, "Who scores?"
  pre-match props board, and a FIFA-confirmed-lineups badge.
- Stats hub: new boards — xA, chances created, save percentage, saves
  per 90.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 00:54:58 +02:00
NilsBriggen f0e0f7390d Tier 2: shootout panel, road to the final, ESPN videos, ICS export, injuries plumbing
- 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>
2026-06-12 15:57:17 +02:00
NilsBriggen f2203ed4a4 Tournament stats hub, suspension tracker, card-aware live probabilities
- /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>
2026-06-12 15:42:00 +02:00
NilsBriggen 15d955e65c Starters-on-pitch, chart movers sort, pre-filled what-if bracket, vs/@ fix
- 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>
2026-06-12 13:46:27 +02:00
NilsBriggen 03b0fa734e Web Push: goal, kickoff and full-time alerts for a followed team
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>
2026-06-12 08:21:55 +02:00
NilsBriggen 047e9f8767 Elo trajectories: a century of strength on every team page
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>
2026-06-12 01:12:36 +02:00
NilsBriggen 8e6c9416fa Favorite team: star a side, get its next match pinned on Live
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>
2026-06-12 00:59:15 +02:00
NilsBriggen dc3c375081 Mobile overhaul: round-picker bracket, 5-tab nav + More sheet, real icons
- 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>
2026-06-12 00:30:48 +02:00
NilsBriggen 05010771a3 German language option + a full wording-clarity pass
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>
2026-06-12 00:20:07 +02:00
NilsBriggen 51dfe00216 v2 Phase 5: incredible UI pass — deep interlinking + Teams hub
- 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>
2026-06-11 16:24:46 +02:00
NilsBriggen 7f4838d032 v2 Phase 2: match previews + team profiles
- buildPreviewData.ts: precomputes from 150y of results → h2h.json (825 WC-team
  pairings, full records + recent meetings) + scorers.json (top-10 all-time
  scorers per team). Committed goalscorers.csv.
- server/src/preview.ts: assembles MatchPreview / TeamProfile from three layers —
  historical (h2h, scorers), DB enrichment (ESPN form/lineups/venue), live model
  (W/D/L, xG, odds, Elo). /api/preview/:num + /api/team/:name.
- Client: rich /match/:num page (model expectation, recent form chips, H2H record
  + recent meetings, lineups-or-key-players) and /team/:name profile (Elo, odds,
  standing, fixtures, all-time scorers). Match cards now link to previews;
  cross-linking between matches and teams.
- Verified: Mexico-SA preview (81% W, 2-0, form, H2H 2-1-1, Borgetti 37) and
  Argentina profile (Messi 63) render; 22 tests pass; build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 15:34:54 +02:00