# Impl: S36 — Central de Conteúdos — logo do header no tamanho da marca Status: aprovado Atualizado em: 2026-09-24 Issue: #1301 Intenção: docs/plans/central-conteudos-header-logo.md Design UI (gate): docs/plans/central-conteudos-header-logo-ui-design.html Appetite restante: ~0,25–0,5 dia eng — correção de fidelidade visual no header, só componente + CSS, sem schema/migration. Modo: autônomo (`--auto`) — impl plan nasce aprovado pelo agente. ## Leitura da intenção - **Outcome:** a marca no header da Central (`/conteudos`) lê, nos dois breakpoints, no mesmo peso visual do header público de referência (`/jingles`) — aferido lado a lado em staging. - **O que NÃO negociar:** - **Fonte única kit 1313:** `public/campaign-kit/`; nenhum lockup recriado, nenhuma cor ou tipografia inventada. - **Correção vive no header da Central:** escolha de ativo e/ou tamanho renderizado; sem redesenhar o header (`h-14 sm:h-16`, `bg-[#ae1603]` preservados). - **Badge "Central de Conteúdos", link "Voltar à Central" e comportamento nos dois breakpoints permanecem.** - **Nenhuma outra página pública muda** — `CampaignPageHeader` (`/jingles`) é referência intocada, sem drive-by. - **O que reavaliar (hipóteses do plano de intenção):** - "Opções A|B|C decididas no gate": o design hi-fi decidiu — **A RECOMENDADA** (lockup oficial com recorte técnico da moldura). B (marca completa negativa) comprime o slogan na barra; C (compensar tamanho sem recorte) estoura o header. O que resta para a engenharia é só **como** implementar o recorte técnico da opção A (D1). - "Recorte = preparo do ativo no kit": o design entrega o recorte como **CSS (`overflow-hidden` + offsets)** sobre o PNG oficial existente — não como PNG novo commitado. Nenhum binário novo no kit. ## Abordagem recomendada ```mermaid flowchart LR KIT["kit 1313 (fonte única)\njorge-solla-negativo.png\n1037x595, visível 790x285"] --> OWNER["ContentPiecePageHeader.tsx\núnico dono (page-local)"] OWNER -- "A: wrapper trimmed-lockup\nCSS overflow-hidden + offsets" --> DESK["desktop: 188x50\nimg 246px, -29/-38"] OWNER --> MOB["mobile: 142x39\nimg 186px, -22/-29"] DESK --> S1["/conteudos (catálogo)\ncom/sem peças"] MOB --> S1 DESK --> S2["/conteudos/"] MOB --> S2 DESK --> S3["não-encontrado\n(not-found.tsx)"] MOB --> S3 REF["CampaignPageHeader (/jingles)\nreferência ~46/52px\nNÃO TOCAR"] -. "peso-alvo lado a lado" .-> S1 ``` **Opções consideradas (abordagem geral):** A) lockup `jorge-solla-negativo.png` com recorte técnico via CSS no componente (wrapper `overflow-hidden` com as medidas do design); B) trocar pelo ativo `marca-negativa-completa.png` do kit; C) compensar tamanho renderizado do lockup atual (aumentar `h-7`/`sm:h-9` ou `transform: scale`) sem recorte. **Recomendação:** **A** — é a opção recomendada do design aprovado (cenas 01/02/03), preserva a assinatura horizontal do S27, atinge ~46 px de tinta visível no peso da referência e cabe no appetite sem binário novo nem redesign. **Rejeitadas:** **B** porque a marca completa (nome + 1313 + slogan) comprime o slogan na barra de 64/56 px e compete verticalmente com o nome da seção — o próprio design registra a perda de leitura; **C** porque escala a moldura transparente junto: ou continua pequeno, ou estoura o `h-14`/`sm:h-16` (redesign vedado), ou distorce o lockup. ### D1 — Como implementar o recorte técnico da opção A (decisão central, cara de reverter) **Opções:** A) CSS `overflow-hidden` com offsets no componente (wrapper `div.trimmed-lockup` 188×50 desktop / 142×39 mobile, `img` absoluta 246 px offset −29/−38 desktop e 186 px offset −22/−29 mobile, header `h-14 sm:h-16` preservado); B) asset recortado commitado no kit (novo PNG trimmed em `public/campaign-kit/` + atualização do `README.md`); C) `next/image` `fill`/`sizes` ou scale-up do lockup atual sem wrapper de recorte. **Recomendação:** **A** — port fiel do design aprovado (`central-conteudos-header-logo-ui-design.html:52-73`): o mesmo PNG oficial, nenhuma segunda fonte de marca, nenhum binário novo, reversão trivial (só o componente + CSS voltam). Os offsets derivam do recorte visível medido (transparência topo 162, base 148, esquerda 123, direita 124 sobre canvas 1037×595) — documentar a derivação em comentário no componente para o próximo leitor não "recalibrar no olho". **Rejeitadas:** **B** porque cria uma segunda fonte de verdade da marca fora do kit oficial: exige versionar binário + `README.md`, deriva silenciosamente a cada troca de PNG no kit e a reversão espalha (deletar asset + reeditar componente + docs). Gatilho de retorno: se o PNG oficial do kit mudar de canvas/moldura e os offsets CSS perderem a âncora, aí sim gerar o trimmed como build/preparo versionado — não agora. **C** porque `fill` sem janela de recorte replica o problema atual (a caixa continua medindo a moldura, não a tinta), e scale-up puro estoura a barra ou corta sem controle horizontal/vertical; `object-fit` sozinho não ancora o recorte 790×285 dentro de 1037×595. ### Componentes / mudanças - **`src/components/conteudos/ContentPiecePageHeader.tsx`** (editar, `:11-22` — único dono): trocar o `Image` direto (`h-7 sm:h-9`) pelo wrapper de recorte da opção A com as duas medidas do design (desktop + `mobile`), mantendo `Link href="/"`, `aria-label`, `alt="Jorge Solla"`, `priority`, `CONTENT_PIECE_FOCUS`, badge e `backHref`/`Voltar à Central` byte a byte. Sem extrair componente compartilhado — o header é page-local (precedente `JinglePageHeader`, molde do S27). - **CSS do recorte:** classes co-localizadas no componente (Tailwind arbitrário ou módulo local — sem stylesheet global novo, sem classe genérica em shell do site). Valores literais do design: `188x50 / img 246px / -29/-38` desktop, `142x39 / img 186px / -22/-29` mobile. Comentário curto com a derivação (canvas 1037×595 → visível 790×285). - **Consumidores intocados:** `src/app/(frontend)/conteudos/(catalog)/page.tsx:99,112`, `src/app/(frontend)/conteudos/[slug]/page.tsx:82`, `src/app/(frontend)/conteudos/[slug]/not-found.tsx:16` — todas usam `ContentPiecePageHeader`; nenhuma muda. - **Referência intocada:** `src/components/CampaignPageHeader.tsx:20-27` — não alterar (é o peso-alvo, não o paciente). - **Kit intocado:** nenhum PNG novo em `public/campaign-kit/`; `public/campaign-kit/README.md` intocado; `marca-negativa-completa.png` segue só nos cards (`src/lib/cardModels.ts:141`, `src/lib/cardRender.ts:359`) — não tocar. - **Migration:** **sem migration** — só componente + CSS; nenhum campo/collection novo. - **Access / Consent:** nenhum access novo, nenhum `Consent`, nenhuma PII — header público estático; Local API/bypass e multi-collection não se aplicam (sem leitura/escrita de dados). - **UI:** Impeccable B — port fiel das cenas 01 (desktop A), 02 (mobile A) e 03 (peça + Voltar) do artefato aprovado; header, badge, copy e CTA preservados. - **Changelog + impl plan no commit:** `docs/changelog/2026-09-24-s36.md` (uma entrada curta; nunca editar o agregado/HISTORY) e este arquivo `docs/plans/central-conteudos-header-logo-impl.md` no mesmo commit. ### Dados → forma (se aplicável) N/A — a superfície não apresenta KPI, agregado, contador ou série (a intenção declara correção de fidelidade visual; nenhum ator decide com número). Nada a modelar. ## Fases verificáveis 1. **Tracer / markup do recorte — quota ~40%:** editar `ContentPiecePageHeader` com o wrapper A (desktop + mobile); `pnpm dev` local; conferir `/conteudos`, `/conteudos/` e não-encontrado nos dois breakpoints antes de seguir. Critério: marca visível ~46 px desktop no peso da referência, header `h-14 sm:h-16` intacto, badge/Voltar inalterados. 2. **UI (port fiel + lado a lado) — quota ~40%:** confronto lado a lado com `/jingles` (referência) em staging nos dois breakpoints; checar cena 03 (peça + "Voltar à Central"), foco visível (`CONTENT_PIECE_FOCUS` não cortado pelo `overflow-hidden`), `alt`/contraste, retina. Sem spec de header novo — cobertura via e2e/visual de staging (achado do explorador). 3. **Gates — quota ~20%:** `pnpm gate:fast` (lint/format/typecheck/knip/cycles/unit) verde; `pnpm push` → PR `--base main`. Sem int novo (sem dados); sem manifest novo (superfícies já cobertas pelo `frontendConteudos` curado; mudança CSS-only não alarga blast radius). ## Testes previstos - **Sem unit/int novos** — sem lógica de domínio, sem leitura/escrita, sem querystring nova; nada puro para pinar. - **Visual/e2e em staging (verificação viva):** `/conteudos` (catálogo com/sem peças), `/conteudos/`, não-encontrado — marca no peso da referência nos dois breakpoints, lado a lado com `/jingles`; badge e "Voltar à Central" presentes e clicáveis. - **Pins intocados:** `tests/unit/e2eAffectedManifest.unit.spec.ts` (sem entrada nova — CSS-only no dono já mapeado), `tests/unit/codebaseConventions.unit.spec.ts`, `src/lib/shareLink.ts`, `scripts/lib/campaignKitAssets.mjs` — todos intocados. ## Rabbit holes / Não escopo (engenharia) - **Generalizar os headers públicos** ("padronizo `CampaignPageHeader` junto") — vira refactor de todas as páginas públicas e revisão de marca. Corte: só `ContentPiecePageHeader`. - **Criar lockup novo / PNG recortado no Figma ou no kit** — nasce marca paralela fora da fonte única. Corte: kit como fonte única; no máximo o recorte CSS do ativo oficial. - **`next.config` remote ou loader de imagem novo** — o ativo é local do kit; nada de infra de imagem. - **`scripts/lib/campaignKitAssets.mjs`** — tooling do kit, fora do escopo desta correção visual. - **Ajustar altura/espaçamento/badge do header para "caber" a marca** — redesign vedado; a menor mudança que faça a marca ler no peso certo. - **Mexer em copy, badge, CTA, "Voltar à Central", rotas, dados ou consentimento** — fora de escopo explícito. ## Riscos e mitigação - **Offsets frágeis a troca do PNG no kit:** o CSS ancora no canvas atual (1037×595 → visível 790×285); se o kit republicar o PNG, o recorte desalinha. Mitigação: comentário no componente com a derivação + gatilho registrado para a opção B (asset trimmed versionado). - **Anel de foco cortado pelo `overflow-hidden`:** o wrapper pode clipar o `CONTENT_PIECE_FOCUS`. Mitigação: foco no `Link` externo ao wrapper (estrutura atual já permite), conferir por teclado nos dois breakpoints. - **`next/image` vs `img` do artefato:** o design usa `img` absoluta; o componente usa `next/image` (width/height literais). Mitigação: manter `next/image` com os mesmos `width`/`height` do canvas e aplicar largura/offset via classe — sem trocar de primitiva de imagem neste item. - **Retina/downscale do lockup ampliado:** ampliar a janela pode expor serrilhado. Mitigação: PNG fonte tem 1037 px de largura para janela de 246 px — sobra de resolução; conferir em tela real no gate visual. - **Regressão em `/jingles`/home/`/cards`:** correção page-local, mas o olho valida. Mitigação: lado a lado em staging confirma peso igual **sem** nenhuma diff fora de `/conteudos`. ## Aceite de engenharia - [ ] Aceite de produto da intenção coberto: marca no header da Central lê nos dois breakpoints no mesmo peso visual de `/jingles` (aferido lado a lado em staging); fonte única kit 1313; correção só no header da Central; badge, "Voltar à Central" e comportamento preservados; nenhuma outra página pública muda. - [ ] Guardrails: sem migration, sem access/Consent/PII novo, sem escrita multi-collection; `CampaignPageHeader` e `marca-negativa-completa` nos cards intocados; nenhum binário novo no kit. - [ ] Invariantes AGENTS/engineering-standards: dono único editado (`ContentPiecePageHeader`, sem twin/compartilhado novo); identificadores em inglês, copy pt-BR preservada; migrations existentes intocadas. - [ ] Testes previstos executados: visual lado a lado em staging nas três superfícies × dois breakpoints; `pnpm gate:fast` verde; `pnpm push` via GitHub. - [ ] `docs/changelog/2026-09-24-s36.md` + este impl plan no mesmo commit. ## Decisões de engenharia - **D1 — Recorte técnico da opção A:** CSS `overflow-hidden` com offsets no componente (188×50/img 246/−29/−38 desktop, 142×39/img 186/−22/−29 mobile) sobre o PNG oficial existente. Rejeitadas: asset recortado no kit (segunda fonte de marca, reversão espalhada; gatilho se o canvas oficial mudar) e `next/image fill`/scale-up sem janela (replica o problema ou estoura o header). - **Sem migration, sem Consent, sem access novo, sem binário novo** — registrado, não presumido. ## Self-score (decision-quality) **Self-score decision-quality: 5/5.** 1. Decisão cara com Opções/Recomendação/Rejeitadas? 5/5 — D1 (CSS overflow-hidden vs asset recortado vs fill/scale-up) decide o único ponto caro de reverter, com recomendação e rejeitadas explícitas + gatilho de retorno. 2. Cabe no appetite? 5/5 — ~0,25–0,5 dia: um componente + CSS co-localizado, sem schema/migration/binário/testes novos. 3. Rabbit holes Teqo nomeados? 5/5 — generalizar headers, lockup novo, `next.config` remote, `campaignKitAssets.mjs`, redesign da barra, copy/badge/CTA/dados — todos com corte. 4. Depth check (reusar o módulo profundo)? 5/5 — edita o dono único `ContentPiecePageHeader`, reusa o PNG oficial e as medidas do design aprovado; nenhum pass-through raso, nenhum compartilhado novo, referência e kit intactos. 5. Outcome preservado + tracer cedo? 5/5 — outcome lado a lado em staging guia a fase 1; badge/Voltar/breakpoints e "nenhuma outra página muda" mapeados no aceite; fases vão do markup ao gate visual sem presumir dados. Média: 5/5 — ≥4/5.