Por que conselhos em nível de prompt têm desempenho inferior
Conselhos de prompt não estão errados, são apenas efêmeros. Instruído a usar uma paleta quente, o agente o fará. Seis telas depois, ele tem o adjetivo, mas não os valores, então ele faz 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 todas 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 rampa 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 par com contraste real, não dois grotescos 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 letter-spacing exatos nos tokens. *Combine uma serif com uma sans* é um adjetivo, e adjetivos se perdem.
3. Escale o radius conforme o tamanho do elemento
Um único --radius aplicado em todo lugar é 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, de qualquer forma, 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 expressar 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. Dê um modelo para a 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 variações de borda e fundo, além de sombras — e 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 seguinte.
- 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, raio 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, e não 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 raio com a primeira. Se forem idênticos, significa que os valores estão sendo lidos, e não apenas 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 reconhecendo você | 100 a 150ms | ease-out: início rápido, deve parecer que já terminou |
| Algo entrando | Um menu, popover ou painel | 200 a 250ms | ease-out, com o transform fazendo a maior parte do trabalho |
| Algo saindo | O mesmo elemento sendo fechado | 120 a 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 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 mudanças 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 mudanças é 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 completamente o dark mode | 69% |
| Não usar nomes de funções de cores semânticas | 86% |
| Não estabelecer proibições | 76% |
| Não estabelecer 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 raio | 21% |
Compare isso com as seis mudanças acima e a sobreposição é exata. A escala de raio é 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 frase puder produzir duas telas diferentes para dois leitores competentes, a decisão ainda não foi tomada.
A consequência prática para as seis mudanças: escreva cada uma como um número ou um hex, e verifique seu próprio arquivo em busca das três palavras acima antes de commitá-lo.
Todas as seis, já decididas
Cada kit do Identity Forge vem com neutros matizados, um pairing de fontes real, um conjunto de raios escalonados e um modelo de elevação, com o DESIGN.md que os mantém consistentes entre 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 percepção de toda a página.
Uma segunda fonte prejudicaria a performance?
Marginalmente, e é gerenciável. Duas famílias com dois pesos cada totalizam aproximadamente 60 a 120KB com woff2 e subsetting, carregados uma única vez. Fontes variáveis reduzem isso ainda mais. É uma troca justa para eliminar o maior sinal visual de genericidade 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 toque de matiz sem alterar o brilho percebido. No HSL, a mesma edição também altera a luminosidade, forçando você a reajustar a rampa de cores.
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?
Declare a restrição como uma proibição, não como uma preferência. 'Nunca faça hardcode de cores do tema; use os tokens semânticos' é seguido com muito mais rigor do que 'prefira tokens semânticos'.