01 Visão geral
Um site de personal trainer que não parece um site de personal trainer
Eduardo é personal trainer em Divinópolis/MG, com atuação presencial e online, especialização em Musculação e Condicionamento Físico e mais de 5 anos de experiência. O objetivo do projeto era uma landing page de conversão que se diferenciasse do modelo genérico do nicho — formulário, foto de banner, lista de serviços — sem abrir mão de performance nem de simplicidade de manutenção.
A decisão estratégica de maior impacto no projeto foi arquitetural, não visual: o site inteiro é HTML, CSS e JavaScript estáticos, sem framework, sem etapa de build e sem dependência de npm em tempo de execução. Isso significa deploy imediato, superfície de ataque mínima e zero risco de quebra por dependência desatualizada — um site que continua funcionando daqui a cinco anos exatamente como funciona hoje.
A peça central da experiência é uma técnica pouco comum em sites do setor: em vez de vídeo de fundo tocando em loop, cada seção principal é controlada pelo próprio gesto de rolagem do visitante — o vídeo "anda" junto com o dedo ou o mouse, para exatamente onde a pessoa parar.
02 Stack técnica
Sem framework, sem build, sem dependência de runtime
Toda a stack foi escolhida para minimizar peças móveis. Não há React, Vue, bundler ou pipeline de compilação — o que está no repositório é exatamente o que é servido ao visitante.
CSS3
vanilla
+ ScrollTrigger
API 2D
Workers
03 A técnica central
Vídeo controlado pelo scroll, não pelo autoplay
Cada seção com vídeo não é um arquivo .mp4 — é uma sequência de centenas de frames WebP, gerados a partir de vídeo produzido por IA e desenhados um a um num <canvas> conforme o GSAP ScrollTrigger reporta o progresso da rolagem.
O resultado prático: o vídeo nunca "corre sozinho". Ele avança, para e até volta exatamente na velocidade que o visitante rola a página — sem autoplay bloqueado por navegador, sem tela de carregamento de vídeo, sem buffering perceptível, porque cada frame já é uma imagem estática comum.
04 Arquitetura de performance
Carregar 29 MB de vídeo sem pesar 29 MB
A técnica de scroll-vídeo só é viável em produção com uma arquitetura de carregamento agressiva. A regra do projeto: nenhuma seção carrega frames antes de precisar deles, e nenhuma seção fica na memória depois que deixa de precisar.
Regras de carregamento
- Janela simétrica de uma seção. Um
IntersectionObserverpor seção decide o que carregar e o que descarregar — nunca mais que 3 sequências de vídeo na memória ao mesmo tempo. - Transição sem corte perceptível. Ao se aproximar do fim de uma seção, o primeiro frame da próxima já está pronto para um crossfade suave — sem precisar da sequência inteira carregada.
- Sistema de tiers com fallback automático. Conexão lenta, hardware fraco ou
prefers-reduced-motionativo fazem o site cair para uma imagem estática por seção — zero JavaScript de vídeo é executado nesses casos. - Fallback inteligente e simulação de ambiente. O sistema conta com detecção dinâmica de hardware e velocidade de rede para alternar entre os modos de exibição, permitindo testes rigorosos de garantia de qualidade (QA) e de performance web em múltiplos cenários de acesso — do 4G instável ao desktop de ponta.
05 Sistema de marca em código
O manual de identidade, não uma interpretação livre dele
A paleta e a tipografia do site seguem o manual de identidade oficial do cliente — incluindo as regras de uso, não só as cores.
Tipografia: Montserrat (display, caixa alta, tracking positivo) + Inter (corpo), ambas self-hosted como variable fonts. Forma: raio de 3px em todo o sistema — o "canto vivo" herdado do monograma da marca.
Um detalhe de rigor: o grafismo que não podia animar duas vezes
O manual define um grafismo de apoio — uma "régua de anilhas" (blocos em progressão simétrica) — e restringe explicitamente onde ele pode animar: só na barra de progresso de treino do aplicativo. O site usa o mesmo grafismo como divisor de seção, estático, em respeito a essa regra.
Ao desenhar um indicador de progresso de leitura para o site, a solução óbvia seria reaproveitar essa régua e animá-la — o que teria violado a regra do manual. Em vez disso, o indicador de progresso de scroll do site foi desenhado como uma peça nova, usando o mesmo vocabulário visual (blocos discretos em bronze), mas como uma aplicação própria e compatível com a marca, não uma reutilização fora de contexto.
06 Funcionalidades
Peças construídas ao longo do projeto
Carrossel de depoimentos
8 depoimentos reais, transcritos de prints de WhatsApp. Três cards visíveis por vez, o do centro em destaque, avançando conforme o scroll da seção — não em loop automático.
Mockup do app com giro 360°
Captura de tela real do aplicativo gira em torno do próprio eixo vertical (rotateY) sincronizada ao scroll, seguida de um CTA "Acessar App" que só aparece depois que o giro termina.
Ações flutuantes
WhatsApp (ícone SVG próprio, não emoji) e "voltar ao topo", com visibilidade atrelada à posição do visitante na página.
Indicador de carregamento do Hero
Barra fina e não-bloqueante sob o header — nunca esconde conteúdo nem trava scroll, só sinaliza que o scrub vai ficar fluido.
Botão secundário "Área do Aluno"
Acesso direto ao aplicativo de treino do cliente, em estilo visual distinto do CTA primário (WhatsApp) para não competir por atenção.
Crédito Make Solution
Barra fixa no rodapé, com reveal bidirecional ligado ao scroll — aparece e desaparece conforme o visitante se aproxima ou se afasta do fim da página.
07 Auditoria de performance
Medido com PageSpeed Insights, não estimado
Resultado da auditoria de desktop após a rodada de otimização — acessibilidade, práticas recomendadas e SEO no máximo:
Otimização de imagens
A auditoria de mobile identificou dois arquivos de logo desproporcionalmente grandes para o que exibiam em tela — a causa mais provável de um LCP (Largest Contentful Paint) acima de 8 segundos. Ambos foram redimensionados com folga para telas retina e convertidos para WebP sem perda de qualidade:
Outras correções aplicadas
- Scripts sem
defer. GSAP e ScrollTrigger bloqueavam a renderização; passaram a carregar em paralelo ao parsing do HTML. - Estratégia granular de cache na borda (Edge). Aplicação de políticas diferenciadas de Cache-Control no nível de CDN: ativos imutáveis de alto peso — como sequências de frame e fontes — recebem cache de longa duração, enquanto arquivos de marcação e estilo mantêm revalidação frequente, garantindo performance extrema sem comprometer atualizações do site.
- Imagens sem dimensões declaradas. Atributos
width/heightadicionados para eliminar o risco de deslocamento de layout (CLS) durante o carregamento.
08 Engenharia & depuração
Três bugs que só aparecem em produção
Registro honesto de problemas reais encontrados durante o desenvolvimento — o tipo de detalhe que separa "funciona no meu navegador" de "funciona".
Colisão de especificidade CSS — duas vezes
Seletores como .section-content--testimonials parecem duas classes, mas são uma classe só (o -- é convenção BEM, não um segundo seletor) — mesma especificidade da regra genérica de mobile. No mobile, a regra genérica vencia por ordem de declaração e derrubava o posicionamento central, enquanto o transform: translateX(-50%) da regra original continuava valendo — empurrando o conteúdo pra fora da tela.
Correção: override explícito dentro da media query de mobile. O mesmo bug reapareceu numa segunda seção (CTA final) semanas depois — reconhecido e corrigido em minutos por já ter o padrão mapeado.
Loop infinito de IntersectionObserver
Uma barra fixa no rodapé precisava "empurrar" o conteúdo acima dela em vez de cobri-lo. A primeira implementação ajustava o padding-bottom do rodapé dentro do próprio callback do observer — o que mudava a altura do documento a cada toggle, deslocando o elemento-sentinela que disparava o observer, criando um ciclo de feedback: aparece → empurra → sentinela sai da viewport → desaparece → encolhe → sentinela volta → aparece de novo.
Ajuste: reestruturação da lógica de cálculo de dimensão da viewport, isolando a verificação de visibilidade dos eventos de redimensionamento de layout para eliminar ciclos de atualização concorrentes.
Ordem de cálculo no crossfade entre seções
A transição suave entre duas seções de vídeo depende de saber quais são vizinhas de verdade no DOM. Calcular essa adjacência depois que o GSAP já envolveu cada seção num pin-spacer (necessário para o efeito de scroll travado) sempre dava errado — o wrapper muda a estrutura da árvore e quebra a checagem de "próximo elemento".
Ajuste: reordenação no ciclo de vida da inicialização dos scripts, garantindo que o mapeamento de adjacência do DOM seja executado na fase pré-DOM mutation do framework de animação.
09 Conformidade & responsabilidade
Um personal trainer não é um médico — e a copy respeita isso
O cliente possui formação complementar em Farmacologia Hormonal Aplicada, usada para adaptar treinos de alunos em acompanhamento hormonal. A copy foi escrita para deixar claro que esse conhecimento apoia decisões de treino, sempre em conjunto com o médico responsável — nunca em substituição a ele, respeitando os limites de atuação de um profissional de Educação Física registrado no CREF.
- LGPD. Os 8 depoimentos publicados usam identificação genérica (ex.: "Aluno(a) — Divinópolis/MG") até a confirmação de consentimento explícito de cada aluno para uso do nome real.
- Acessibilidade.
prefers-reduced-motionrespeitado em toda a experiência de scroll, foco de teclado visível em todos os elementos interativos, texto alternativo em imagens informativas. - SEO técnico. Nota 100/100 na auditoria — meta description, hierarquia de heading única, HTML semântico.
10 Deploy
Do commit ao ar, sem etapa intermediária
Infraestrutura serverless edge: o projeto é hospedado na rede global da Cloudflare via Workers, com distribuição geográfica de ativos estáticos (Edge Assets) — sem build, sem runtime de servidor e sem infraestrutura tradicional para manter.
O fluxo de publicação é 100% automatizado por scripts de integração contínua (CI/CD): cada alteração aprovada vai do commit ao ar em segundos, com zero downtime durante o processo. A política de cache em cada tipo de ativo segue a estratégia de borda (Edge) descrita na seção 07.