Pular para o conteúdo
As doze regras

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.
PerguntaOnde 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.
CheckO que olhar
Os cinco temasTroque o tema e reveja: botão colorido, selo, dot, ilha ink-950, campo em foco.
Os três estadosCarregando (cabeçalho real + esqueleto), vazio (as DUAS variantes) e erro.
TecladoTab atravessa tudo; Esc fecha; setas andam em abas e radiogroups; o foco volta pro gatilho.
320pxNada vaza, nada corta, o cluster de ações quebra em linhas.
DedoAlvos sobem de degrau; nada colado; a ação principal ao alcance do polegar.
Movimento reduzidoLigue no sistema e confira que nada anima — e que tudo continua legível.
Leitor de telaRótulo em todo botão de ícone; erro ligado ao campo; região carregando anunciada.
NúmerosTudo tabular, tudo por src/lib/format.ts.
CopyVerbo no infinitivo, sentence case, erro que não culpa, consequência escrita.
npm run lint && npx tsc --noEmit && npm testAntes 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.