Contrato
As doze regras
O checklist duro. Antes de entregar qualquer tela nova — feita por gente ou por agente — ela passa por estes doze pontos. Não é sugestão: é o que a revisão cobra, e o que três testes do repositório já cobram sozinhos.
checklist de entregatokens.test.tscontraste.test.ts
O checklist
01Nunca hex ou px solto
Sempre token ou utilitário:
bg-brand, text-fg-muted, gap-phi-3. Cor nova é decisão de design system, não do componente — e o teste tokens.test.ts reprova cor literal fora de globals.css.02Marca = ação · IA = agente
Ação, dado e sucesso vestem
--brand-*. Tudo que o agente gera é --ia-* + Sparkles. Sem misturar, sem exceção — e a regra é a DISTÂNCIA entre as duas, não o matiz.03tabular-nums em todo número
Métrica, contador, telefone, valor, percentual, ocupação, duração:
tabular-nums (ou .tabular). Sempre.04Toca = pílula · contém = canto 16
Botão, campo de uma linha, filtro, badge e item de nav são
rounded-full. Card, painel, modal, tabela e textarea são rounded-xl. Item interno: rounded-md. Exceção única: checkbox rounded-[6px].05Texto semântico usa o tom -strong
text-warning-strong, text-negative-strong… O tom base fica pra dot, fundo e borda. Em texto pequeno ele reprova AA — e o teste de contraste mede isso nos cinco temas.06Foco verde; composer do agente roxo
Todo alvo clicável foca com halo de
ring-[3px]. O único foco roxo do app é o território do agente. Nunca outline-none sozinho.07Status vem do domínio
Rótulo, cor e ordem da jornada moram no domínio e reusam a semântica. Nunca recolorir ad-hoc na tela; nunca escrever “perdido”.
08Escolher ≠ agir
Escolher 1 entre N pinta o escolhido de verde e mantém a lista viva. Menu de AÇÃO só destaca no hover, e a destrutiva fica vermelha, por último, depois de um separador.
09Respiro antes de densidade
p-6 em superfícies, max-w-lg+ em modal de conteúdo, gap-6/gap-phi-3 em grades. Comprimir só de propósito, nunca por descuido.10Marca é SVG oficial; ícone é Lucide
Símbolo sozinho onde o nome ao lado é o da clínica; trava inteira onde o nome é o nosso — a palavra vem DENTRO do SVG. Ícone é Lucide outline stroke 2 (duotone rejeitado), nunca emoji.
11Celular = 1 coluna
flex-col sm:flex-row, grid sm:grid-cols-2. Cluster de ações sempre com flex-wrap; texto sempre min-w-0 + truncate. Largura fixa em px só em ícone e avatar. Altura de tela é dvh, nunca vh.12Toque cresce sozinho; token fluido
Botão e campo sobem um degrau em
pointer-coarse: — nunca compensar com altura fixa. phi-4/5/6 e text-phi-display são clamp() e encolhem por conta própria. Testar em 320 · 375 · 768 · 1024 · 1440.E a regra que vale FORA da tela
As doze acima são pra construir tela. Esta é pra todo o resto — e é a que mais se quebra por engano, porque o app tem cinco peles e a marca tem uma.
NuncaTema escuro é do modo escuro do app. Ponto final.
Landing page, apresentação, proposta, e-mail, post, anúncio, impresso, papelaria, slide, vídeo, ícone de loja — todo material da Hiperclini que não é a tela do produto nasce no tema Claro: o verde da marca sobre superfície branca. Os três temas escuros existem só pra dar modo escuro a quem passa o dia dentro do app; o Azul clínico é preferência de uma CLÍNICA dentro do produto, não cor da Hiperclini. Nenhum dos quatro é versão da marca. A tabela de peça por peça está em Marca.
Antes de abrir o editor
Quatro perguntas que evitam a maior parte do retrabalho.
| Pergunta | Onde checar |
|---|---|
| Este componente já existe com outro nome? | O inventário |
| Esta tela tem sub-telas? | Se tem, é palco; se não, é barra. |
| Esta tela edita alguma coisa no lugar? | Então ela herda o foco em camadas de graça — não reimplemente. |
| Que cor este estado usa? | A semântica já tem uma. Cor nova é decisão de design system — ver Cor. |
Antes de entregar
A passada final. Cada item aqui já reprovou uma entrega.
| Check | O que olhar |
|---|---|
| Os cinco temas | Troque o tema e reveja: botão colorido, selo, dot, ilha ink-950, campo em foco. |
| Os três estados | Carregando (cabeçalho real + esqueleto), vazio (as DUAS variantes) e erro. |
| Teclado | Tab atravessa tudo; Esc fecha; setas andam em abas e radiogroups; o foco volta pro gatilho. |
| 320px | Nada vaza, nada corta, o cluster de ações quebra em linhas. |
| Dedo | Alvos sobem de degrau; nada colado; a ação principal ao alcance do polegar. |
| Movimento reduzido | Ligue no sistema e confira que nada anima — e que tudo continua legível. |
| Leitor de tela | Rótulo em todo botão de ícone; erro ligado ao campo; região carregando anunciada. |
| Números | Tudo tabular, tudo por src/lib/format.ts. |
| Copy | Verbo no infinitivo, sentence case, erro que não culpa, consequência escrita. |
| npm run lint && npx tsc --noEmit && npm test | Antes do commit, sempre. |
os três testes que já cobram o canon sozinhos
src/lib/tema/tokens.test.ts → recusa hex/rgb literal fora de globals.css src/lib/tema/contraste.test.ts → mede os pares texto/fundo dos 5 temas (WCAG AA) src/lib/tema/aparencia.test.ts → prende a régua "este tema é claro ou escuro"
NotaRegra que virou teste não volta a ser disciplina
A ordem de preferência é: prender no CSS global → prender num componente de
ui/ → prender num teste → escrever no guia. Só o que não cabe nas três primeiras vira “lembre-se de”.E a regra de manutenção deste guia: mudou o canon, muda a página no mesmo commit. Guia que envelhece cala — e um guia que cala é pior que nenhum, porque ainda é citado.