# Plano de Implementação — Tela de Estatísticas Finais (World Cup 2026 Hub) > Documento de planejamento (NÃO é implementação). Gerado em 2026-06-14 após workflow multi-agente > (5 perspectivas) + aprovação da lista de dados pelo usuário. Escopo aprovado: **as 4 camadas** > (✅ existentes · 🟡🧩 acréscimos baratos · 🔴 dados de jogadores · 📝 editorial). > > **PRINCÍPIO REITOR (requisito explícito do usuário):** *degradação graciosa*. Quando um dado não > puder ser obtido, o tratamento deve ser elegante — **não pode quebrar a UI nem deixar visível para o > usuário final que algo está faltando**. Sem `—`, sem cards vazios, sem "dados em breve". A regra é: > **um dado/seção só aparece quando está completo o bastante para ser apresentado como autoritativo; > caso contrário é removido do DOM** (não escondido com placeholder, *removido*). Ver §0 e §6. --- ## 0 · Camada de degradação graciosa (a espinha dorsal de todo o resto) Esta é a peça arquitetural mais importante do plano. Tudo abaixo se apoia nela. ### 0.1 Contrato de disponibilidade Cada estatística, card, linha de tabela e sub-seção declara um predicado `isAvailable(model)`: - **Sub-seção inteira sem dados** → a seção **não é renderizada** e seu chip no sub-nav **é removido** (navegação nunca aponta para o vazio). - **Card/recorde individual sem dados** → o card não é inserido; o grid reflui naturalmente. - **Célula opcional numa linha** (ex.: xG de um time sem feed) → a coluna some para todos OU a célula cai para um valor neutro só se isso não denunciar ausência. Preferência: **a coluna inteira só existe se todos os times tiverem o dado.** - **Agregado sobre `stats` esparso** (posse/chutes/cartões) → só renderiza com **cobertura completa** (todos os jogos da amostra relevante preenchidos). Sem cobertura → **escondido, sem disclaimer**. (Decisão: o usuário NÃO quer "baseado em N jogos" visível. Ou faz backfill total, ou não mostra.) ### 0.2 Carga de dados tolerante a falha `loadData()` em `app.js` passa a buscar os novos JSON; cada fetch novo é **opcional**: arquivo ausente / 404 / JSON inválido → `console.warn` (dev) + **default vazio** (`[]`/`{}`), **nunca** exceção que derrube o app. Os 6 arquivos atuais continuam obrigatórios. ### 0.3 Mídia com fallback Fotos de jogadores / bandeiras quebradas → `onerror` cai para iniciais (monograma) ou silhueta genérica. Nunca ícone de imagem quebrada. ### 0.4 Camadas se auto-desligam - Sem `players.json`/eventos → **toda** a seção Jogadores + Prêmios + comparador de jogadores + recordes de tempo de gol somem (chips inclusive). A tela continua completa só com dados de time. - Sem `curiosities.json` → Recordes mostra só os auto-deriváveis; nada de "em breve". - Sem `attendance` → recordes de público somem; o resto do Overview fica intacto. Resultado: a mesma base de código entrega uma tela coerente e "cheia" com **só os dados existentes hoje**, e vai "acendendo" seções conforme os dados das camadas 2/3/4 forem entrando — sem nenhuma data de corte nem buraco visível. --- ## 1 · Arquitetura da tela ### 1.1 Estrutura de componentes (segue o padrão por-view existente) ``` index.html ├─ nav.tabs +