From c10a573cabb7b59c84556085ad7eeec78d655a8c Mon Sep 17 00:00:00 2001 From: Lucas Kalil Date: Tue, 16 Jun 2026 19:46:57 -0300 Subject: [PATCH] docs: log stats screen Stage B (verdict hero + goals-by-round) Co-Authored-By: Claude Opus 4.8 --- .agents/TODO.md | 2 +- .agents/project-map.md | 6 +++--- .agents/project-memory.md | 8 ++++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.agents/TODO.md b/.agents/TODO.md index 64eab52..13b93e2 100644 --- a/.agents/TODO.md +++ b/.agents/TODO.md @@ -81,7 +81,7 @@ data-blocked (graceful-degradation shell lets the UI land dark until JSON arrive ### 🟒 OPTIONAL (release feature) - [x] ~~Stage 0 β€” branch `feature/stats-final-screen` off `master`~~ - [x] ~~Stage A β€” degradation engine + fault-tolerant `loadData` + sticky scrollspy sub-nav + media fallback~~ (2026-06-16) -- [ ] Stage B β€” verdict hero (gated on FINAL finished; aggregate-hero fallback) + goals-by-round chart +- [x] ~~Stage B β€” verdict hero (gated on FINAL finished; aggregate-hero fallback) + goals-by-round chart~~ (2026-06-16) - [ ] Stage C β€” final ranking 1–48 (phase-reached chain), favorite-row highlight, team record cards - [ ] Stage D β€” auto record-cards + "format-48 debuts" band - [ ] Stage E β€” 104-match results archive (accordion by phase, row β†’ modal) diff --git a/.agents/project-map.md b/.agents/project-map.md index a4f087c..dff4439 100644 --- a/.agents/project-map.md +++ b/.agents/project-map.md @@ -4,7 +4,7 @@ Navigation map of the codebase. Use this to find which file owns a concern befor > **Status 2026-06-12 (all 12 steps + real-data migration done):** everything works with **real World Cup 2026 data** β€” all views, bracket interactions, simulation, responsive/a11y pass, favorites, time toggle, challenge, share link, `.ics` export. Remaining: keep `results.json` current, fill `thirdPlaceAssignment` after the group stage (~Jun 27), Lighthouse run + GitHub Pages deploy. Spec source of truth: `world-cup-2026-hub-spec-en.md` + `complement-spec-worldcup2026-en.md` (complement **wins on conflict**). > -> **Branch note (2026-06-16):** the full post-Cup Stats screen (`.agents/stats-screen-plan.md`, stages A–J) is being built on **`feature/stats-final-screen`** (merges to `master` at the end of the Cup). **Stage A done** on that branch (degradation engine + fault-tolerant `loadData` + sticky scrollspy sub-nav + flag monogram fallback). `master` keeps the partial Stats tab + daily refreshes. Descriptions below reflect the branch. +> **Branch note (2026-06-16):** the full post-Cup Stats screen (`.agents/stats-screen-plan.md`, stages A–J) is being built on **`feature/stats-final-screen`** (merges to `master` at the end of the Cup). **Stages A–B done** on that branch (degradation engine + fault-tolerant `loadData` + sticky scrollspy sub-nav + flag monogram fallback; verdict-or-aggregate hero + goals-by-round chart). `master` keeps the partial Stats tab + daily refreshes. Descriptions below reflect the branch. --- @@ -68,11 +68,11 @@ worldcup2026/ β”‚ β”‚ β”œβ”€β”€ storage.js localStorage wrapper β€” wc2026_* keys, auto-JSON β”‚ β”‚ β”œβ”€β”€ i18n.js EN/PT-BR dicts + t(key), lang toggle β”‚ β”‚ β”œβ”€β”€ stats.js β˜… Stats tab: tournament-to-date aggregates (finished -β”‚ β”‚ β”‚ matches only), hero pulse + overview + goals-by-stage + +β”‚ β”‚ β”‚ matches only); verdict-or-aggregate hero + overview + goals-by-stage/round + β”‚ β”‚ β”‚ 48-team sortable table. SECTIONS registry (graceful- β”‚ β”‚ β”‚ degradation gate: section + chip render only if available, β”‚ β”‚ β”‚ else removed from DOM) + sticky scrollspy sub-nav (anchor -β”‚ β”‚ β”‚ chips, hash-safe) + flagImg monogram fallback. Grows into +β”‚ β”‚ β”‚ chips, hash-safe) + flagImg fallback; imports getBracketTree. Grows into β”‚ β”‚ β”‚ the post-cup plan (.agents/stats-screen-plan.md, A–J). β”‚ β”‚ └── calendar.js .ics export (RFC 5545, CRLF, Blob download) β”‚ β”œβ”€β”€ images/ Team flag SVGs, stadium placeholders diff --git a/.agents/project-memory.md b/.agents/project-memory.md index 44f6277..d187d09 100644 --- a/.agents/project-memory.md +++ b/.agents/project-memory.md @@ -253,6 +253,14 @@ Static web app showing the FIFA World Cup 2026 (Mexico/USA/Canada, 48 teams) β€” - **Verified (preview 8126, branch):** console clean (no errors, no 404 warnings); 6 optional layers = empty defaults, core 48/104/104; sub-nav sticky at `--header-h`, only Overview+Teams chips; scrollspy topβ†’Overview / bottomβ†’Teams; chip click leaves hash `#stats`; EN↔PT relabels chips + sections/table survive; flag fallback β†’ "XYZ" span at 22Γ—15; mobile 375px (2-band header, 2Γ—2 tiles, nav follows 98px header); Home hero+dashboard regression clean. - **Next:** Stage B (verdict hero gated on FINAL finished, falling back to the current aggregate hero; + goals-by-round chart) β€” awaiting approval. Will consume `getBracketTree().champion` + `resolveBracketTeams('FINAL'|'THIRD-PLACE')` from `bracket.js`. +### Stats final screen β€” Stage B: verdict hero + goals-by-round (2026-06-16) +- **Verdict hero (`stats.js`):** `heroHTML()` now dispatches β€” `model.verdict ? verdictHeroHTML() : aggregateHeroHTML()`. The verdict hero shows the champion (trophy + gold-outlined flag + name) and a **2/3/4 podium** (runner-up / 3rd / 4th) above the same 4 count-up tiles (extracted to `heroTilesHTML()`, shared by both heroes). **Gated on the REAL final:** `computeVerdict()` reads `getBracketTree().nodesByRef.get('FINAL')` and returns `null` unless `result.status==='finished' && !simulated && winner` β€” so a user's **simulated** champion never leaks into the verdict (`decide()` sets the real winner first, so `simulated:false` β‡’ real). Third/fourth come from `tree.third` the same way, independently (podium degrades gracefully if only the final is in). Until the final is really finished it falls back to the existing **aggregate "tournament in progress" hero**, so an early merge stays correct (current 17/104 data shows the aggregate hero β€” verified). +- **`stats.js` now imports `getBracketTree` from `bracket.js`** β€” the 4th intentional circular import with `app.js` (safe: only called at render runtime, and `bracket.js` evaluates before `stats.js` in `app.js`'s import order). +- **Goals-by-round chart (`goalsByRoundHTML`, in the Overview section after goals-by-stage):** finer companion to goals-by-stage β€” the group stage is split into its **3 matchdays** (derived per group by `computeGroupMatchdays`: sort each group's 6 fixtures by kickoff, chunk into pairs β†’ MD1/2/3; **`matches.json` has no matchday field**) plus each knockout round on its own. `ROUND_ORDER = ['MD1','MD2','MD3', ...STAGE_ORDER]`. **Hidden until β‰₯2 rounds have data** (`order.length < 2 β†’ ''`) so early on it doesn't show a lone bar duplicating goals-by-stage's "Group" bar (current data = only MD1 β†’ chart hidden, verified). The model gained `byRound` + `verdict`. +- **New i18n keys** (EN+PT): `stats.goalsByRound`, `stats.matchday` ("Matchday"/"Rodada"), `stats.verdictTitle`, `stats.runnerUp`, `stats.thirdPlace`, `stats.fourthPlace`. **New CSS** in `stats.css`: `.stats-verdict` + `.verdict-champion/-trophy/-flag/-name/-crown/-podium/-place/-rank/-place-name/-place-label`. +- **Verified (preview 8126, branch):** real 17/104 β†’ aggregate hero + goals-by-round hidden, console clean; **faked all-104-finished** (+ a valid `thirdPlaceAssignment`, injected via `preview_eval`, restored by reload) β†’ verdict hero (champion + 2/3/4 podium, tiles 276 goals / 2.65 avg / 6 / 55) + goals-by-round with all 9 buckets (MD1–3 + R32β†’Final); EN↔PT relabels the verdict + round chart and survives re-render; no regression after restore. +- **Next:** Stage C β€” final ranking 1–48 (phase-reached β†’ pts β†’ GD β†’ GF β†’ id chain), favorite-row highlight (`getFavorites` + `favchange`), team record cards (biggest rout β†’ modal, champion's path, form). Awaiting approval. + ### How to update real-world data (scores, schedule) Follow `how-refresh-data.md` (project root). In short: 1. Edit `data/results.json` (scores/status) or `data/matches.json` (schedule, rare).