Por que conselhos em nível de prompt não funcionam bem
Conselhos de prompt não estão errados, são apenas efêmeros. Se instruído a usar uma paleta quente, o agente o fará. Seis telas depois, ele terá o adjetivo, mas não os valores, então ele fará uma aproximação — e as aproximações divergem. Esse é o mecanismo por trás de por que sites construídos por IA convergem, e é por isso que as correções abaixo são escritas como valores, e não como instruções.
Regra geral ao ler: se uma mudança puder ser expressa como um número ou um hex, coloque-a nos tokens. Se ela só puder ser expressa como um adjetivo, você ainda não terminou de tomar a decisão.
1. Matize os neutros com a sua cor de destaque
Esta é a mudança de maior retorno e quase ninguém a faz. Temas padrão combinam uma escala de cinza puro com um destaque não relacionado, e os dois nunca parecem pertencer ao mesmo produto. Design systems projetados inclinam os neutros alguns graus em direção à cor de destaque, com croma muito baixo.
/* Default: pure neutral, unrelated to the accent */
--background: oklch(0.145 0 0);
--muted: oklch(0.269 0 0);
--primary: oklch(0.55 0.19 45);
/* Tinted: same lightness, a trace of the accent hue */
--background: oklch(0.145 0.008 45);
--muted: oklch(0.269 0.012 45);
--primary: oklch(0.55 0.19 45);Mantenha o croma genuinamente baixo. Acima de aproximadamente 0.02, os cinzas começam a ser lidos como coloridos em vez de neutros, e você terá trocado um visual óbvio por outro.
2. Adicione uma segunda família tipográfica
Uma única família cuidando de títulos, corpo, labels e números é a maneira mais rápida de identificar uma UI gerada. A solução é um emparelhamento com contraste real — não duas fontes grotescas semelhantes, o que pareceria um acidente em vez de uma decisão.
- Serif display + grotesque body. O contraste mais confiável e difícil de errar.
- Grotesque display + humanist body. Mais discreto; funciona para UIs de produtos densas onde uma serifada pareceria decorativa.
- Uma superfamília, dois extremos. Uma condensed heavy contra uma regular. Seguro quando a marca precisa manter a coesão.
- Uma mono para dados. Não como decoração: algarismos tabulares impedem que os números oscilem entre as linhas.
Seja qual for a sua escolha, escreva as famílias, pesos e o letter-spacing exatos nos tokens. *Combine uma serif com uma sans* é um adjetivo, e adjetivos se perdem.
3. Dimensione o radius conforme o tamanho do elemento
Um único --radius aplicado em tudo é o terceiro sinal. O radius é lido *em relação ao elemento onde está*, então os mesmos 8px fazem um botão pequeno parecer arredondado demais e um card grande parecer quase reto.
/* One value, applied to everything */
--radius: 0.5rem;
/* Scaled to element size */
--radius-sm: 0.25rem; /* inputs, chips, badges */
--radius-md: 0.5rem; /* buttons, small controls */
--radius-lg: 0.875rem; /* cards, panels */
--radius-xl: 1.25rem; /* modals, sheets, hero surfaces */4. Quebre a grade uniforme
Três cards iguais dizem que cada item tem o mesmo peso. Isso quase nunca é verdade, e um layout que afirma isso, mesmo assim, não transmite nenhuma informação sobre o produto.
A mudança é editorial, não técnica: decida qual item realmente importa mais e deixe o layout mostrar isso. Um card largo acima de dois estreitos. Uma divisão de dois terços/um terço. Um único recurso com imagens de apoio reais em vez de três ícones. A grade é aceitável quando os itens são genuinamente equivalentes — a falha está em usá-la por padrão.
Consistency check · No type scale
The same plan card, built two ways in Mauve Broadcast.
Pricing
Everything a small team needs to ship a branded UI.
Pricing
Everything a small team needs to ship a branded UI.
5. Defina um modelo de elevação
UIs geradas geralmente possuem apenas uma sombra, aplicada a qualquer elemento que deva parecer elevado. Sistemas de elevação reais possuem dois ou três níveis que concordam sobre a direção da luz e utilizam alterações de borda e fundo, além de sombras — muitas vezes em substituição a elas.
/* One shadow doing every job */
--shadow: 0 1px 3px rgb(0 0 0 / 0.1);
/* Levels that agree about a light source */
--elevation-0: none; /* flush: use a border */
--elevation-1: 0 1px 2px rgb(0 0 0 / 0.06); /* cards */
--elevation-2: 0 4px 12px rgb(0 0 0 / 0.08); /* dropdowns */
--elevation-3: 0 16px 40px rgb(0 0 0 / 0.12); /* modals */6. Escreva onde o agente irá reler
As cinco mudanças acima valem pouco se ficarem apenas em uma conversa. Coloque-as em um DESIGN.md e em arquivos de tokens no repositório; assim, o agente resolverá os mesmos valores em cada execução — inclusive em uma sessão aberta no mês que vem.
- 1
Instale o contrato de design
Grava o DESIGN.md e os arquivos de tokens no projeto.
npx --yes identityforge@latest install --client claude-code - 2
Aplique um kit que já tome essas decisões
Neutros matizados, um pairing real, radius escalonado e um modelo de elevação, tudo já definido.
identityforge apply terrain-vivant - 3
Referencie-o no arquivo do seu agente
Uma linha no AGENTS.md para que o contrato seja encontrado, em vez de descoberto por acaso.
Never hardcode theme colors. Use the semantic tokens in DESIGN.md. - 4
Verifique se funcionou
Abra uma nova sessão, crie uma tela não relacionada e compare a cor primária e o radius com a primeira. Se forem idênticos, significa que os valores estão sendo lidos, e não lembrados.
O que ainda parece gerado após as seis mudanças
Todo guia nesta SERP termina na lista de correções. Esse é o lugar errado para parar, pois dois indícios sobrevivem a todas as seis mudanças e são justamente aqueles que as pessoas notam sem conseguir nomear. Ambos estão fora do arquivo de tokens, como ele é usualmente escrito, e é exatamente por isso que persistem.
Tudo se move da mesma forma
Interfaces geradas possuem apenas uma animação: um fade curto com um pequeno deslocamento para cima, aplicado a cada elemento que aparece. Está no hero, nos cards, no modal e no toast. Nada no movimento indica que tipo de evento acabou de acontecer, então o produto inteiro parece um slideshow contínuo.
O movimento transmite significado quando a duração e o easing variam de acordo com *o que o elemento está fazendo*, e não onde ele está posicionado. A distinção a ser codificada é entre coisas que respondem a você e coisas que surgem por conta própria:
| O que é | Duração | Easing | |
|---|---|---|---|
| Respondendo a um clique ou hover | Um controle confirmando sua ação | 100–150ms | ease-out — início rápido, deve parecer que já terminou |
| Algo entrando | Um menu, popover ou painel | 200–250ms | ease-out, com o transform fazendo a maior parte do trabalho |
| Algo saindo | O mesmo elemento sendo fechado | 120–180ms | ease-in — saídas devem ser mais rápidas que entradas |
A assimetria nessa última linha é a parte que quase nada gerado acerta: as saídas rodam na mesma velocidade que as entradas, o que faz com que fechar qualquer coisa pareça "travado". Escreva as três durações como tokens e o agente parará de escolher um único número para tudo.
/* One duration, one curve, applied to everything */
--transition: 200ms ease;
/* Motion that says what kind of event it was */
--motion-response: 120ms cubic-bezier(0, 0, 0.2, 1);
--motion-enter: 220ms cubic-bezier(0, 0, 0.2, 1);
--motion-exit: 160ms cubic-bezier(0.4, 0, 1, 1);
@media (prefers-reduced-motion: reduce) {
--motion-response: 1ms;
--motion-enter: 1ms;
--motion-exit: 1ms;
}Todo produto usa os mesmos ícones
O segundo sobrevivente é a iconografia. Uma instalação padrão entrega um conjunto open-source com uma única espessura de traço e, como esse conjunto vem com a biblioteca de componentes, os mesmos vinte glifos aparecem em milhares de produtos. Você pode mudar cada cor e cada tipografia e ainda assim ser reconhecível apenas pelos ícones.
Substituir o conjunto geralmente não vale a pena. Restringi-lo, sim:
- Fixe a espessura do traço (stroke weight) de acordo com o peso da sua tipografia. Um traço de 1.5px contra uma fonte de corpo light parece emprestado; contra uma medium, parece harmonizado. Escolha um valor e coloque-o nos tokens.
- Vincule o tamanho ao texto adjacente, para que um ícone em um botão e um ícone em uma linha de tabela não tenham o mesmo tamanho em pixels por acidente.
- Bana os decorativos. Proíba ícones que representam um "clima" em vez de uma ação — faíscas, foguetes e raios são os sinais mais fortes de UI gerada que sobrevivem a um retheme completo.
- Permita uma exceção e nomeie-a. Um único glifo personalizado, geralmente a marca, usado em um local consistente. Um único desvio deliberado parece uma decisão; vários parecem um acidente.
O teste da faísca
Se uma tela contém um ícone de faísca, um gradiente de violeta para azul e a palavra "seamlessly", nenhuma das seis alterações de tokens acima a salvará. Esses três são decisões de conteúdo e iconografia, e devem ser proibidos por escrito, pois nenhuma paleta pode anulá-los.
O que as pessoas erram nos arquivos que escrevem
Escrever as seis alterações é a parte fácil. Analisamos 299 arquivos DESIGN.md públicos do GitHub para ver o que as pessoas realmente commitam, e o padrão de falha é consistente o suficiente para valer um planejamento.
| Proporção de arquivos | |
|---|---|
| Omitir totalmente o dark mode | 69% |
| Não usar nomes de roles semânticas para cores | 86% |
| Não estabelecer proibições | 76% |
| Não definir motivos ou princípios | 57% |
| Não conter nenhum valor de tamanho concreto | 44% |
| Usar um adjetivo vago onde deveria haver um valor | 54% |
| Especificar uma escala de radius | 21% |
Compare isso com as seis alterações acima e a sobreposição é exata. A escala de radius é especificada em um a cada cinco arquivos. Proibições — a coisa mais barata de escrever e a mais seguida com rigor — estão ausentes em três quartos. E as palavras mais comuns usadas no lugar de uma decisão foram *clean* (39% dos arquivos), *modern* (36%) e *professional* (22%).
Escrever não é o mesmo que decidir
Mais da metade dos arquivos reais contêm pelo menos um adjetivo onde deveria haver um valor. Um agente que recebe "clean and modern" precisa resolver isso, e o resolve de forma diferente a cada vez. Se uma linha pode produzir duas telas diferentes para dois leitores competentes, a decisão ainda não foi tomada.
A consequência prática para as seis alterações: escreva cada uma como um número ou um hex, e verifique se as três palavras acima estão no seu arquivo antes de commitá-lo.
Todas as seis, já decididas
Cada kit do Identity Forge vem com neutros matizados, uma combinação de fontes real, um conjunto de raios escalonados e um modelo de elevação — acompanhados do DESIGN.md que garante a consistência entre as sessões. Kits gratuitos não exigem conta.
Qual mudança única traz a maior melhoria?
Tingir os neutros. Não exige trabalho de layout, novas fontes nem redesign — você está ajustando o croma de valores que já possui, e isso muda a leitura de toda a página.
Uma segunda fonte prejudicaria a performance?
Marginalmente, e é gerenciável. Duas famílias com dois pesos cada somam aproximadamente 60–120KB com woff2 e subsetting, carregados uma única vez. Fontes variáveis reduzem isso ainda mais. É uma troca justa para eliminar o sinal visual mais óbvio da página.
Preciso de OKLCH para os neutros tingidos?
Não, mas facilita muito. O OKLCH separa a luminosidade do croma, permitindo adicionar um traço de matiz sem alterar o brilho percebido. No HSL, a mesma edição também altera a luminosidade, e você acaba tendo que reajustar a rampa.
Isso é apenas theming?
Em parte, e esse é o ponto — a maior parte do que parece 'genérico' reside em valores que uma camada de tema já controla. As partes que não são theming são a decisão do grid e o modelo de elevação, que são estruturais.
Como impeço o agente de sobrescrever isso?
Defina a restrição como uma proibição em vez de uma preferência. 'Nunca use cores de tema hardcoded; use os tokens semânticos' é seguido com muito mais precisão do que 'prefira tokens semânticos'.