# Frontend Audit — Amare site ## T0 — Baseline - [x] Rodar `composer quality` p/ registrar estado verde atual (110 passed após composer install) - [x] Registrado estado baseline; Lighthouse final consolidado no T6 - [x] Registrar achados baseline (audit completo em frontend-audit.md + relatório subagent) ## T1 — Formulário de contato (e-mail, sem CRM) - [x] Form em /contato (campos, LGPD obrigatório) - [x] Rota POST /contato + validação + honeypot + throttle - [x] Anti duplo-envio, estados sucesso/erro/rede, preservação de dados - [x] E-mail via MAIL_MAILER (Resend prod / log local) - [x] A11y do form (labels, erros ligados) - [x] Testes feature + atualizar PublicPagesTest — Feature suite: 97 passed ## T2 — A11y/navegação - [x] Menu mobile: Escape, retorno de foco, fallback sem-JS (app.js + noscript) - [x] Touch targets ≥44px (header, footer, CTAs, capítulos) - [x] Footer: ul/li + address ## T3 — SEO/metadados - [x] Títulos "Página · Amare" (PageMeta::withBrandSuffix) - [x] og:locale, og:site_name, Twitter cards - [x] Favicon real + link, theme-color - [x] Metadados corretos em 404/500 (PageMeta::forErrorPage) - [x] noindex fora de produção (robots meta condicional) ## T4 — Conteúdo/posicionamento - [x] Remover welcome.blade.php, home/cases, home/proof - [x] Dedup heading final-CTA vs h1 contato; dedup disclaimers - [x] CTA consistente mobile/desktop - [x] Corrigir copy "Em breve..." nas listas - [x] Rebalancear copy corporativo/social ## T5 — Performance - [x] fetchpriority + dimensões hero (LCP) - [x] Guarda CLS no media/image - [x] Cache manifest de fontes - [x] Escape JSON-LD ## T6 — Validação final - [x] pint, phpstan, testes unit/feature/architecture — `composer quality` verde (135 testes) - [x] Browser tests + visual regression (18 passaram; 8 baselines `.snap` atualizadas com `--update-snapshots`) - [x] Lighthouse final (home mobile: A11y 100, Best Practices 100, SEO 69 só por noindex intencional fora de prod; contato desktop: A11y 100, BP 100) - [x] E2E form: submit → sucesso role=status; 2 e-mails (novo briefing + confirmação) logados via MAIL_MAILER=log; fila drenada - [x] Mobile: sem overflow horizontal nas 7 rotas (390px); menu mobile abre/fecha + Escape + retorno de foco - [x] Relatório de entrega ## T7 — Hardening Public Blades - [x] Chunk 1: CSS overflow resilience (`overflow-wrap` body + `[data-chapter-index]` wrap safety, browser test) - [x] Chunk 2: Hero + final-CTA fallbacks + `leading-tight` (TDD) - [x] Chunk 3a: Skip blank-quote testimonials (TDD) - [x] Chunk 3b: Guard empty `event_type` + `break-words` meta line (TDD) - [x] Chunk 4: Extend `PageMeta::forErrorPage` + branded 419/429/503 error views (TDD) - [x] Chunk 5: `app.js` defensive hardening — bfcache submit reset, "Enviando…" label swap, aria-busy, mobile-menu focus trap + Escape - [x] Chunk 6: Quality gates — Pint passed, PHPStan clean, 104 feature tests passed (587 assertions), Vite build succeeded ### Deviations from plan - `PageMeta::forErrorPage` landed on `main` during implementation; rebased and extended it for 419/429/503. - Contact form landed on `main`; submit-state browser coverage was restored. - `event_type: null` violates NOT NULL column — test uses `''` instead (guard covers both). # Browser CI Gate — estabilidade e diagnosticabilidade ## BG — Causa raiz - [x] Diagnosticar 3 runs: mismatch visual (8 testes), acessibilidade (1), timeout networkidle 5s + overflow real - [x] Reproduzir local: `waitForLoadState('networkidle')` fragil (conexões longas), default 5s - [x] Reproduzir warning `file_get_contents(.env)` em TODO teste (CI sem .env) ## BG — Fixes - [x] Helper `StableScreenshot` (tests/Support/): drop networkidle → readyState + fonts + settle - [x] Exportar PNGs standalone (diff/expected/actual) no mismatch — visíveis nos artifacts - [x] CI: `cp .env.example .env` nos jobs de teste; checkout/cache v5 - [x] Gitignore tests/Browser/Screenshots - [x] Unit test MismatchScreenshotExporter; pint/phpstan/unit/feature verdes - [x] Push + PR + CI browser verde (PR #15 merge f09ea83, run 31098941038) - [x] Refresh baselines de CI se necessário (não necessário — browser passou com baselines atuais)