A branch de QA do #659 trouxe a spec, doze arquivos de evidência e um script de
medição — e deixou o script na RAIZ do repositório.
**O script sai da raiz.** `medir-fachada.mjs` existe porque no dia o daemon do
Docker estava travado: ele mede a fachada contra um `next start` já buildado,
sem banco. É proveniência das medições, não ferramenta do projeto — num
repositório aberto, na raiz, vira arquivo que ninguém sabe para que serve. Foi
para junto da evidência que produziu.
**As imagens ganham o documento que as justifica.** `tests/unit/evidencia-citada.test.ts`
reprova imagem versionada sem citação, e com razão: imagem sem texto não prova
nada, e num projeto aberto todo clone paga o peso dela.
O README diz o que cada captura prova — inclusive a comparação que responde à
condição literal do dono ("desde que não quebre o visual que já existe"): para
quem não enviou logo, posição e tamanho idênticos até a fração de pixel, nos
dois temas. E diz o que elas NÃO provam, a começar pela barra lateral, que é a
superfície principal do #659 e não foi medida em tela.
Um tropeço meu no caminho, pego pela cerca: abreviei nomes (`… / -light.png`),
e ela leu `-light.png` como um arquivo inexistente e deixou três imagens sem
citação. Cada arquivo agora vai pelo nome exato — conferido um a um: 13 de 13.
evidencia-citada.test.ts -> 46 passed (46)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017jpi8VAeDpDhcfA3L63et2
O que está aqui é a superfície 2 do #659 — a tela de entrada — medida por
ferramenta num build de produção, com build ANTES e DEPOIS.
`medir-fachada.mjs` existe ao lado da spec porque o daemon do Docker desta
máquina travou (o socket ACEITA conexão e nunca responde), e sem Supabase local
a spec não carrega — o `loadCreds()` dela semeia pelo banco. A fachada não
precisa de banco: `marcaDaInstalacao()` devolve `null` quando a consulta falha
(`instalacao.ts:362` — ela não lança) e a resolução cai na camada do AMBIENTE,
que é a semente `APP_LOGO_URL` documentada no CLAUDE.md. O caminho de produto é
o mesmo; muda qual camada ganhou.
MEDIDO (tema escuro, logo enviado):
background-color=rgb(255,255,255) padding=[8,12,8,12] box-shadow≠none
a moldura CONTÉM o logo: 64×56 contra 40×40
MEDIDO (tema claro, mesmo logo):
background-color=rgba(0,0,0,0) padding=[0,0,0,0] box-shadow=none
MEDIDO (tema escuro, marca do PRODUTO):
nenhum ancestral com fundo claro — a fronteira da reconciliação vale.
A CONDIÇÃO DO DONO, com dois builds de produção (pré-#659 = 688f798f2 contra o
estado atual): para quem NÃO enviou logo, a marca e o cartão de acesso ocupam
retângulos IDÊNTICOS até a fração de pixel, nos dois temas, antes e depois.
O preço, medido e não escondido: para quem TEM logo enviado, o cartão desce 8px
no escuro (o `dark:py-2` da moldura, num bloco centrado). É a troca que o #659
declara — fica com número para poder ser discutida.
SABOTAGEM, previsão antes de rodar: revertendo a fachada ao pré-#659, 4
asserções vermelhas (pintura, folga, sombra, contenção) e o tema claro intacto.
Observado: exatamente 4, cada uma pelo motivo certo — a da contenção falha pela
ALTURA, porque sem o <div> o pai do logo passa a ser o `flex justify-center`,
que tem a mesma altura do logo.
Duas sondas minhas nasceram cegas e estão registradas no dossiê: uma rodou com
rótulo que não casava com o ramo do script (contagem certa, motivo errado), e a
outra usava "nenhum ancestral claro" no tema CLARO, onde o próprio
`bg-background` é claro por definição.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A cerca unitária do #659 (`tests/unit/logo-nao-some-no-tema-escuro.test.ts`)
declara no próprio cabeçalho o que ela NÃO faz:
> O que ele NÃO faz é medir contraste num navegador — isso é Playwright com
> `getComputedStyle`, e está anotado como pendência.
Esta spec é essa pendência. Ela não relê a fonte: abre a tela, escolhe o tema
pelo controle que a pessoa usa (`ThemeToggle`) e pergunta ao NAVEGADOR qual cor
foi pintada. A diferença não é formal — uma classe `dark:` escrita no JSX e uma
classe `dark:` que o Tailwind compilou para o seletor certo são coisas
diferentes, e só a segunda pinta pixel.
Seis casos, cobrindo as três superfícies e a fronteira que a reconciliação criou:
(1) escuro + logo ENVIADO → a barra lateral pinta a moldura (e a CONTÉM)
(2) claro + logo ENVIADO → nenhuma moldura (as classes são `dark:`)
(3) a TELA DE ENTRADA → as duas medidas, sem sessão nenhuma
(4) a PRÉVIA da tela de marca → prevê o que o app desenha
(5) escuro + marca do PRODUTO → NÃO recebe moldura ← a fronteira
(6) sem logo enviado → o cabeçalho não muda de retângulo entre os temas
O caso (5) é o que mais importa: pôr a moldura na arte do produto — que já é
desenhada para os dois temas — seria dar o remédio a quem não tem a doença.
A negação ali é sobre TODA a cadeia entre a marca e o `<aside>`, e não só sobre
o pai: uma moldura acrescentada em qualquer avô pintaria igual na tela, e uma
asserção de um nível só passaria verde ao lado do defeito.
O caso (6) é a condição com que o dono aprovou a mudança ("desde que não quebre
o visual que já existe"), no único sentido que é mensurável: para quem NUNCA
enviou logo, nenhum pixel do cabeçalho pode se mover ao trocar de tema.
`medirMoldura` parte do `<img>` e sobe UM nível, em vez de procurar pela classe
`.dark\:bg-white`. Perguntar pela classe acharia o elemento pela propriedade que
se quer provar, e passaria verde num DOM onde a moldura existe e não embrulha
nada — a sabotagem do "chip irmão auto-fechado" que derrubou a primeira versão
da cerca unitária.
Registrada em `SPECS_PARTE_3` do `e2e.yml`, ao lado de `marca-logo.spec.ts`:
as duas mexem na mesma camada de marca, e a mesma parte as serializa.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>