4.6 KiB
Context
O site público usa Blade/Tailwind e já contém um runtime pequeno em resources/js/motion.js: abertura focal da home, page-open, reveals com IntersectionObserver e progresso do índice. A cobertura e a marcação são parciais, os reveals não têm grupos/direções explícitas e a matriz browser se concentra nas quatro páginas visuais originais. A mudança cruza templates, CSS, JavaScript e testes, mas não envolve estado de aplicação, dados ou dependências.
Goals / Non-Goals
Goals:
- Tornar a coreografia Heritage Editorial consistente em toda página pública visual.
- Manter texto legível durante toda entrada, animando somente
transforme recorte de mídia. - Garantir enhancement progressivo: estado final imediato sem JavaScript, observer ou com movimento reduzido.
- Preservar interação, foco, validação e ausência de overflow em desktop/mobile.
- Cobrir marcação, comportamento real, acessibilidade e console.
Non-Goals:
- Não criar transições de rota, parallax, animação contínua ou repetição ao voltar no scroll.
- Não mudar copy, dados de clientes, estrutura de layout, CMS, controllers, banco, APIs ou Filament.
- Não adicionar biblioteca de animação nem itens de SPEC.md §4.2.
Decisions
-
Contrato declarativo em atributos
data-*. Templates usarãodata-motion="page-open",data-motion-beat,data-reveal-group,data-revealedata-reveal-from="up|left|right". CSS define o estado visual e JS apenas ativa classes. Alternativa rejeitada: acoplar seletores a classes de layout, por tornar a coreografia frágil a ajustes visuais. -
Enhancement opt-in pelo elemento raiz. O HTML inicial permanece no estado final; o runtime adiciona
html[data-motion="enhance"]somente quando movimento é permitido e os recursos necessários existem. Sem JS, semIntersectionObserver, ou emreduce, o atributo não é aplicado/removido e todo conteúdo fica final. Alternativa rejeitada: estado inicial oculto no HTML/CSS, pois pode prender conteúdo fora da tela. -
Transformação sem fade de texto. Entradas duram cerca de 500 ms com
cubic-bezier(0.16, 1, 0.3, 1), deslocamento vertical de 12 px e lateral de 24 px no desktop/16 px no mobile. Grupos recebem stagger de 90 ms limitado a 270 ms. Mídia pode combinar transform comclip-path; texto não usa opacidade. Alternativa rejeitada: fade geral, que reduz contraste durante axe e legibilidade percebida. -
Observer de execução única. Cada reveal intersectado recebe o estado final e é removido do observer. Grupos calculam índice limitado para o delay; depoimentos definem explicitamente
left/rightpela coluna, preservando alternância no mobile. Alternativa rejeitada: reanimar em toda rolagem, por criar fadiga e instabilidade. -
Feedback separado das entradas. CTAs, links, navegação e controles recebem transições curtas (100–200 ms) em cor/transform/borda.
:focus-visiblecontinua prioritário; alertas e mensagens de erro não entram no contrato de motion. Alternativa rejeitada: feedback via JS, desnecessário para estados CSS. -
Progresso com coalescência por frame. Eventos de scroll apenas agendam uma atualização por
requestAnimationFrame; o cálculo existente é preservado. Alternativa rejeitada: calcular em todo evento, que multiplica leituras/escritas durante scroll. -
Testes em camadas. Feature tests comprovam contratos Blade/CSS/JS e renderização de erros; browser tests comprovam entrada, stagger, direções, reduced motion, fallback, interação, overflow e console. Axe e console incluem sobre, contato, privacidade e 404; demais erros ficam em renderização feature.
Risks / Trade-offs
- [Conteúdo pisca entre estado final e início do enhancement] → inicializar no primeiro módulo Vite, limitar transformações a distâncias pequenas e nunca ocultar texto.
- [Transforms laterais causam overflow horizontal] → limitar distância por breakpoint, manter recorte no contêiner público e testar
scrollWidthem ambos viewports. - [Muitos observers/estilos inline] → usar um único observer, custom property de índice limitada e
unobserveimediato. - [Páginas de erro não carregam o runtime em todos os contextos] → o estado final é seguro; feature tests cobrem os cinco templates.
Migration Plan
Publicar CSS, JS e templates no mesmo bundle/commit; não há migração de dados. Rollback consiste em reverter esses assets e atributos, sem compatibilidade de schema ou limpeza operacional.
Open Questions
Nenhuma; direção, alternância mobile, execução única e limites de escopo foram aprovados no plano.