feat(stats): verdict hero + goals-by-round chart (Stage B)

- Verdict hero: champion (trophy + flag + name) and a 2/3/4 podium
  (runner-up/3rd/4th) above the shared count-up tiles. Gated on the REAL
  final via computeVerdict() — getBracketTree()'s FINAL node must be a real
  finished result (!simulated), so a user's simulated champion never leaks
  into the verdict. Third/fourth from the third-place match, independently.
  Falls back to the existing aggregate 'in progress' hero until the final is
  in, so an early merge stays correct.
- Goals-by-round chart beside goals-by-stage: group stage split into its 3
  matchdays (derived per group; no matchday field exists) plus each knockout
  round. Hidden until >=2 rounds have data so it never duplicates the
  goals-by-stage Group bar early on.
- stats.js imports getBracketTree from bracket.js (4th circular import with
  app.js, render-time only). i18n stats.goalsByRound/matchday/verditTitle/
  runnerUp/thirdPlace/fourthPlace (EN/PT); verdict-hero CSS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Lucas Kalil 2026-06-16 19:46:57 -03:00
parent f3751f0042
commit 61e0bb0d0a
3 changed files with 231 additions and 12 deletions

View file

@ -131,7 +131,13 @@ const dicts = {
'stats.decisive': 'Decisive',
'stats.draws': 'Draws',
'stats.goalsByPhase': 'Goals by stage',
'stats.goalsByRound': 'Goals by round',
'stats.matchday': 'Matchday',
'stats.stageGroup': 'Group stage',
'stats.verdictTitle': 'Final verdict',
'stats.runnerUp': 'Runner-up',
'stats.thirdPlace': 'Third place',
'stats.fourthPlace': 'Fourth place',
'stats.teamStatsTitle': 'Team statistics',
'stats.colGpg': 'G/M',
'stats.colCS': 'CS',
@ -278,7 +284,13 @@ const dicts = {
'stats.decisive': 'Decididas',
'stats.draws': 'Empates',
'stats.goalsByPhase': 'Gols por fase',
'stats.goalsByRound': 'Gols por rodada',
'stats.matchday': 'Rodada',
'stats.stageGroup': 'Fase de grupos',
'stats.verdictTitle': 'Veredito final',
'stats.runnerUp': 'Vice-campeão',
'stats.thirdPlace': 'Terceiro lugar',
'stats.fourthPlace': 'Quarto lugar',
'stats.teamStatsTitle': 'Estatísticas por time',
'stats.colGpg': 'G/J',
'stats.colCS': 'CS',