Site imersivo · estádios históricos em 3D (WebGL)
As Copas

Problema
Conteúdo esportivo na web é tudo igual: listas de texto sem identidade, nada que alguém queira compartilhar.
Solução
Tributo às Copas do Mundo com 8 estádios icônicos modelados em 3D (arquibancadas, setores e torcida), Modo cinema para gravar vídeos, álbum de figurinhas com os áudios virais e identidade editorial própria. É 100% estático e rápido até no 3G.
Como foi construído
Site 100% estático em Next.js (App Router), sem backend e sem banco de dados: história, curiosidades, estádios e figurinhas moram em módulos TypeScript tipados dentro de src/data. Isso vira SSG puro, incluindo páginas dedicadas por estádio (/estadios/[slug]) geradas via generateStaticParams, cada uma com metadata e canonical próprios. É o que explica a sensação de carregamento instantâneo mesmo em 3G: zero round-trip a qualquer API para renderizar conteúdo.
O diferencial é um gerador procedural de estádios em React Three Fiber. Cada um dos 8 estádios icônicos é descrito por um StadiumParams tipado: perfil radial em pontos [raio, altura] revolucionado com LatheGeometry, proporções sx/sz próprias e um "landmark" único, como a torre art déco no Centenário, o anel plano no Maracanã, o arco gigante em Wembley, a coroa dourada em Lusail e as lâminas de aço no MetLife. As arquibancadas em degraus não são um asset importado: é uma BufferGeometry construída na mão, fileira por fileira, com vertex colors para simular corredores de setor e degraus alternados. E a torcida é um InstancedMesh de milhares de esferas posicionadas por um PRNG determinístico (mulberry32, seed por hash do slug), pra nunca variar entre servidor e cliente e nunca quebrar a hidratação.
A experiência 3D foi escrita para sobreviver ao mundo real: teste de contexto WebGL antes de montar o Canvas (com fallback textual e fotos reais se falhar), frameloop="never" quando o card sai da viewport ou a aba fica oculta (IntersectionObserver mais visibilitychange, economizando bateria no mobile), dica de gravação que detecta touch e user agent para não instruir "Win+Alt+R" num iPhone, e um Modo cinema com câmera respirando (seno suave em Y) mais uma marca d'água discreta gravada no canto do vídeo. Essa última existe porque o objetivo do site é ser compartilhado, e um clipe sem atribuição não traz ninguém de volta.
O projeto nasceu com uma auto-auditoria sênior de UX, UI, SEO e acessibilidade, rodada sobre o próprio código e sobre o HTML servido em produção (14 dimensões, contrastes WCAG calculados par a par). Boa parte do roadmap gerado ali já foi implementada: countdown com estado pós-final, botão de compartilhar por estádio e por curiosidade, fallback de WebGL, pausa do render fora de tela, páginas individuais por estádio para SEO long-tail e a marca d'água do Modo cinema. É o tipo de disciplina de "projeto pessoal tratado como produto" que normalmente só aparece em trabalho remunerado.
100% estático
Sem backend nem banco: conteúdo em módulos TypeScript, SSG total incluindo página própria por estádio.
Estádios procedurais
8 estádios em 3D gerados por parâmetros (LatheGeometry + BufferGeometry escrita à mão), não modelos importados.
Torcida determinística
Milhares de instâncias posicionadas por PRNG com seed fixa: mesmo resultado no servidor e no cliente, zero erro de hidratação.
3D com consciência de bateria
Render pausa fora da viewport e com a aba oculta; fallback amigável se o WebGL falhar.
Mais telas
Stack
- Next.js
- TypeScript
- Three.js
- React Three Fiber
- Tailwind
- Framer Motion


