Files
Rafael MelgaçoandClaude Opus 5 50c2017978 feat(marca): tela /admin/marca — ver, mudar, e ver o estado quando falha
A tabela e a server action existiam sem chamador. Esta e a superficie: o dono
da instalacao troca o nome e a cor pela tela, em vez de SSH + reinicio da stack.

Gate is_platform_admin com notFound(), nao redirect('/403') — a existencia da
tela nao e assunto de quem nao e da plataforma (precedente: settings/atualizacao).
A porta e o AdminSidebar; NAO entra no registry.ts, que so cobre app/app/**
(confirmado lendo tests/unit/navegacao-completude.test.ts).

O BLOCO QUE ENSINA. O controle primario da cor e a tira dos 11 tons, com tres
marcacoes: "Sua cor", "Botoes no modo claro", "Botoes no modo escuro". Sem ela o
usuario cola um hex e nao entende por que o botao ficou de outro tom. A marcacao
usa frente calculada por luminancia, entao o contorno e visivel em qualquer marca.

LINGUAGEM E METADE DA ENTREGA. O leitor e dono de uma VPS, nao designer. Zero
"OKLCH", "rampa", "stop 600", "WCAG". A tela diz "o texto em cima dos botoes",
"passa em AA", "no modo claro os botoes usam um tom mais escuro que a sua cor —
e o que mantem o texto em cima deles legivel". Um teste guarda isso: a uniao dos
codigos do motor e Record<CodigoDaMarca, Traducao>, entao codigo novo em
lib/branding/ REPROVA o typecheck aqui em vez de vazar cru para a tela.

BLOCO DE ESTADO (invariante 6 — configuracao tem superficie): origem de cada
campo ("padrao do sistema" / "definido nesta tela" / "veio do arquivo de
instalacao"), contraste medido com veredito, o que o sistema ajustou, e o
fallback ativo com data e motivo. Fallback que ninguem ve e indistinguivel de a
feature nunca ter sido instalada.

E a tela DIZ O QUE AINDA NAO FAZ, embaixo do campo: hoje o nome alcanca o titulo
da aba; o menu e a tela de entrada ainda leem o .env. Sem isso o operador conclui
que quebrou.

DOIS DEFEITOS DE PROSA QUE SO A SONDA PEGOU (gates nao pegam texto errado):
1. A frase de deslocamento citava o tom padrao DAQUELE MODO. Medido com #f5c518:
   o modo escuro anda +2 e a tela dizia "um tom mais escuro da sua cor" quando o
   botao pousa EXATAMENTE na cor da pessoa. Agora a distancia e ate a cor dela.
2. Com marca neutra (#808080), a derivacao emite semantica_deslocada porque o
   verde DO PRODUTO colide com o verde de sucesso DO PRODUTO — e a tela dizia
   "sua cor ficou parecida com sucesso" sobre uma cor que nao pinta nada.
Ambos com teste, ambos sabotados para confirmar que reprovam (2/2 e 1/1).

PROVA EM TELA (Playwright, build de producao, login com MFA real):
  estado          swatches   --color-accent   titulo da aba
  inicial              1        #506d48        Marca da instalacao
  digitando #7a5cd6   15        #506d48
  hex invalido        --        Salvar DESABILITADO
  salvo               15        #604aa6        <- a cor muda no produto
  recarregado         15        #604aa6        <- persistiu

E o #604aa6 e exatamente o tom que a tela prometeu como "Botoes no modo claro":
a tela nao mentiu. Banco depois do salvar: accent_hex=#7a5cd6, seeded_from_env=f.
Zero jargao tecnico na tela, zero rolagem lateral. Evidencia em evidence/.

O primeiro run REPROVOU com "Could not find the table 'public.platform_branding'
in the schema cache" — o baseline tinha sido provado num Postgres descartavel,
mas o Supabase local nunca recebera a migration. Nao era bug do codigo; era o
ambiente. Aplicada a 0155 no banco local, o ciclo fechou.

Medido de brinde, nao consertado: `border-error-fg/30` nao gera CSS nenhum no
Tailwind 3.4 (modificador de opacidade sobre cor em var()). Duas telas do repo
usam a classe e estao sem borda — contacts/[id]/_client.tsx:64 e
AnonymizeDialog.tsx:102.

typecheck 0 · lint 0 · test:unit 380 files / 4326 passed · build EXIT=0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TCiffR3ugjQbxsfceQE2GB
2026-08-13 17:48:56 -03:00

93 KiB
1280x880px