Aprenda a gerar UI consistente em apps React usando tokens de design e regras de componente para que telas geradas por IA respeitem espaçamento, tipografia e comportamento de formulários.

A inconsistência de UI geralmente aparece em pequenos detalhes que parecem estranhos conforme você navega. Uma página tem padding generoso, outra parece apertada. Headings pulam entre tamanhos, botões mudam de forma e cor, e o mesmo input se comporta de modo diferente dependendo da tela.
Na maior parte das vezes, o desvio vem de alguns elementos básicos:
Isso é comum quando telas são geradas a partir de prompts separados. Cada prompt é, efetivamente, um novo começo, então o modelo preenche decisões faltantes chutando. Mesmo “use um estilo moderno” ainda deixa centenas de escolhas pequenas: gaps de 8px vs 12px, texto corpo 14px vs 16px, quando mostrar erros, qual é a aparência de um botão primário.
Você pode limpar manualmente duas ou três páginas, mas não escala. Você acaba correndo atrás de correções pontuais de CSS, copiando estilos entre arquivos e refazendo formulários. As regras estão na sua cabeça, não no projeto.
Imagine gerar uma tela de login hoje e uma de perfil amanhã. Se uma mostra erros só no submit e a outra no blur, os usuários percebem. Se a altura do botão primário muda entre telas, o app parece costurado.
A consistência vira padrão quando cada tela segue o mesmo sistema compartilhado: design tokens (espaçamento, tipografia, cor) mais um pequeno conjunto de regras de componente e formulário.
Design tokens são valores nomeados simples que você reutiliza pela UI. Em vez de pedir “padding confortável” em cada tela, você usa um token como space-4. Em vez de “levemente arredondado”, você usa radius-md. O nome permanece estável mesmo se você mudar o que ele representa depois.
Tokens são o conjunto de decisões que você quer que cada tela compartilhe. Eles eliminam gosto e chute — que é exatamente o que causa drift quando você gera ou constrói novas páginas.
Tokens típicos cobrem espaçamento, tipografia, cores, forma e uma pequena quantidade de elevação. O ganho é prático: um cabeçalho sempre usa o mesmo tamanho, um card sempre usa o mesmo padding, e um botão primário mantém a mesma cor e radius.
Tokenize as coisas que afetam a sensação geral do produto: escala de espaçamento, tamanhos de fonte e alturas de linha, cores principais (texto, fundo, primary, danger, borda) e um pequeno conjunto de raios de borda.
Mantenha escolhas dirigidas por conteúdo flexíveis, como comprimento do texto, qual ícone usar, ou se uma seção precisa de dois ou três cards.
Quando você gera telas (incluindo com ferramentas como Koder.ai), fornecer um pequeno conjunto de tokens desde o início reduz a quantidade de chute e torna o resultado visivelmente mais consistente.
Um conjunto de tokens é apenas um menu curto de valores permitidos. Menor é melhor porque deixa menos espaço para escolhas aleatórias, mas ainda precisa cobrir o básico que faz as telas parecerem fora do lugar.
Comece pelo espaçamento. Escolha uma escala e use-a em todo lugar para padding, gaps e layout. Um conjunto como 4, 8, 12, 16, 24, 32 cobre a maior parte da UI. Se um design pede 10px ou 18px, arredonde para o token mais próximo em vez de introduzir novos números.
Depois defina padrões tipográficos para que headings e texto corpo parem de derivar. Você não precisa de um sistema tipográfico enorme. Precisa de passos claros e repetíveis.
Um conjunto compacto que continua útil sem inchar:
Acessibilidade também faz parte do sistema. Defina um estilo de outline de foco (cor, espessura, offset) para que usuários de teclado obtenham estados de foco consistentes. Defina um tamanho mínimo de alvo por toque (como 44x44) para mobile. Limite cores de texto a um conjunto pequeno e confiável para manter contraste previsível.
Se botões às vezes parecem apertados, muitas vezes é porque uma tela usou padding 10 e outra usou 12. Com tokens, você pode dizer: “Botões usam paddingY=8, paddingX=16, radius=12, token de outline de foco, altura mínima 44.” Uma vez que esses números estão fixos, o gerador para de improvisar.
Tokens definem os números. Regras de componente definem os hábitos.
Escolha um pequeno conjunto de componentes core e trate-os como os únicos blocos de construção para telas. Mantenha-os simples e reutilizáveis: Button, Input, Select, Checkbox, Card. Você pode adicionar TextArea e Modal, mas eles devem seguir o mesmo sistema (labels, espaçamento, estados).
Em seguida, limite variantes e defina quando são permitidas. Por exemplo: Button tem primary, secondary e danger. Primary é para a ação principal da tela (normalmente uma). Secondary é para cancelar ou ações de baixa prioridade. Danger é só para ações destrutivas como deletar. Se a variante não puder ser justificada, use secondary por padrão.
Regras de espaçamento evitam drift sutil. Defina padrões dentro dos componentes: padding do Button, altura do Input, gap entre label e campo, o gap padrão entre campos empilhados. Adicione algumas regras de layout também: Cards têm padding interno fixo e espaçamento consistente entre header/body; Modals usam os mesmos passos de largura e alinhamento do footer.
Por fim, torne estados não-negociáveis porque é aí que UIs costumam começar a parecer aleatórias:
Quando você gera uma tela com muitos formulários como “Create project”, essas regras evitam tamanhos mistos de botão, posições de label que mudam, ou um “card especial” que só aparece em uma página.
Mesmo com visuais estáveis, muitas queixas do tipo “isso parece errado” vêm do comportamento dos formulários. Se cada tela trata labels, erros e foco de forma diferente, os usuários percebem inconsistência.
Escolha um padrão de formulário e use-o em todo lugar: label, marcador opcional/obrigatório, helper text, depois texto de erro. Mantenha a redação consistente também (por exemplo, labels em sentence case, helper text curto, e mensagens de erro que começam com um verbo).
As regras que previnem a maior parte do drift:
Trave tamanhos e layout para que as telas não “respirem” de forma diferente. Defina uma altura de input, uma altura de botão e uma largura padrão de campo. No desktop, alinhe campos a uma grid consistente e empilhe labels acima dos inputs. No mobile, faça campos com largura total e evite formulários em duas colunas a menos que realmente necessário.
Um exemplo simples: uma tela “Create project” pode ter Name, Region e Description. Mesmo que Region seja um select, trate-o como qualquer outro campo: mesma altura, mesma posição de label, mesma linha de erro. Se o usuário submeter com Name vazio, o foco vai para Name, o erro aparece embaixo e o layout permanece estável.
Se você gera telas no Koder.ai, coloque essas regras de formulário no seu prompt uma vez e reutilize-as entre features para que cada novo formulário se comporte igual sem limpeza repetida.
Trate seu prompt como um pequeno contrato de UI. Mantenha-o curto, específico e reutilizável para que cada nova tela alinhe ao mesmo espaçamento, tipografia, componentes e comportamentos.
Um padrão prático é colar um spec compacto de UI no topo da sua requisição e depois descrever a tela em linguagem simples.
UI SPEC (apply to every screen)
Tokens:
- Spacing: 4, 8, 12, 16, 24, 32
- Radius: 8
- Typography: H1 24/32, H2 18/26, Body 14/20
- Colors: text, muted, bg, primary, danger (no custom hex)
Components (must use): PageShell, Section, Card, Button, Input, Select, TextArea, FormRow, HelperText, Toast
Layout rules:
- Page padding: 24 desktop, 16 mobile
- Section spacing: 24
- Card padding: 16
- Grid: 12 cols desktop, 4 cols mobile, gap 16
Do:
- Reuse components and tokens only
- Keep labels above inputs, helper text below
Do not:
- Invent new spacing values, font sizes, or one-off CSS
- Mix different button heights or input styles
If a new component is needed:
- Extend an existing component pattern and document it in the output
- Do not create new visual styles outside tokens
Após o spec, adicione algumas checagens de aceitação que peguem o drift cedo:
Se estiver usando um gerador baseado em chat, mantenha esse spec estável entre requisições. Mudá-lo toda vez derrota o propósito.
Escreva o contrato de UI antes de gerar qualquer coisa: um pequeno conjunto de tokens (espaçamento, tipo, cores, radius, sombras) mais um inventário curto de componentes (Button, Input, Select, Card, Modal, Table, Toast). Se faltar um token ou componente, o modelo vai inventar um e sua UI vai derivar.
Depois crie uma tela de referência que exercite as regras. Uma página com muitos formulários é um bom teste porque inclui headers, helper text, erros de validação, botões primário e secundário, e um toast de sucesso. Trate essa tela como baseline.
A partir daí, construa novas telas compondo o que você já definiu. Não peça “estilo novo”. Peça o mesmo Card, a mesma escala de espaçamento, os mesmos passos tipográficos e o mesmo padrão de campo.
Um fluxo simples:
Se uma tela “Search users” acabar com espaçamento mais apertado que a referência, não corrija margens manualmente. Atualize os tokens de espaçamento ou a regra de padding do Card uma vez, então regenere.
Se estiver trabalhando no Koder.ai, snapshots e rollback ajudam: bloqueie uma baseline, experimente com segurança e reverta rápido se uma mudança começar a introduzir drift.
A maneira mais rápida de perder consistência é tratar tokens e regras como sugestões. Pequenas exceções se multiplicam ao longo de novas telas.
Uma armadilha comum é mudar a escala de espaçamento no meio do projeto. Telas iniciais usam 8, 16, 24. Uma nova tela introduz 10 e 18 “porque parece certo.” Agora o drift está permitido, e telas antigas nunca são atualizadas.
Outra fonte de drift é deixar o gerador inventar novos estilos de componente. Se você não disser “apenas essas variantes de botão existem”, ele pode criar um novo radius ou um padding de input diferente em uma tela.
Estados são outro erro frequente. Loading, empty e error states frequentemente mudam espaçamento e comportamento. Se você os acrescenta no final, geralmente obtém padrões apressados que não combinam com o resto.
Também fique atento ao tipo errado de especificidade: “faça moderno com sombras suaves” é vago, enquanto regras de comportamento como “erros mostram abaixo do campo”, “botões desabilitados mantêm estilos de foco” e “Enter submete só no último campo” são concretas e repetíveis.
Se quiser um bloco leve de guardrail para colar em prompts, mantenha curto:
Antes de mergear uma tela gerada, faça uma varrida de dois minutos.
Comece pelo espaçamento. Procure valores aleatórios como 13px ou margens pontuais adicionadas “só para encaixar”. Se você usa tokens, todo gap deve vir do conjunto aprovado, incluindo gutters, padding de card e espaçamento entre campos de formulário.
Depois cheque tipografia contra sua escala. Headings devem seguir passos previsíveis. Texto corpo não deve trocar de tamanho entre seções similares. Altura de linha importa também, especialmente em telas densas como páginas de configurações.
Escaneie os botões em seguida. Variantes e tamanhos devem seguir suas regras: primary para a ação principal, secondary para ações menos importantes, danger só quando realmente deleta. Altura do botão, posicionamento de ícone e estilo do label devem bater.
Para formulários, consistência é sobretudo estrutura. Labels ficam em um lugar só, indicadores de obrigatório seguem uma regra, helper text e erros não competem, e erros aparecem em local consistente.
Um checklist curto:
Por fim, faça um rápido check em mobile. Reduza a largura e confirme que o layout se adapta sem inventar novos tamanhos de fonte ou espaçamentos.
Imagine um fluxo de onboarding simples: três telas (Profile, Preferences, Confirm), mais uma página de Settings depois. Você quer que cada tela pareça vinda do mesmo designer, mesmo que tenham sido geradas em runs separados.
Antes de gerar qualquer coisa, forneça um pequeno conjunto de tokens e algumas regras de componente:
TOKENS
- spacing: xs=4, sm=8, md=12, lg=16, xl=24
- radius: sm=8, md=12
- type: body=14/20, title=20/28, label=12/16
- layout: pageMax=960, sectionGap=24, fieldGap=12
COMPONENT RULES
- Page: max width=pageMax, padding=xl, sectionGap between blocks
- Card: padding=lg, radius=md
- Field: label above, helper below, fieldGap between fields
- Button row: primary on right, gap=sm
- Errors: shown under field, same copy style, no alerts
Agora gere “Profile” e “Preferences” separadamente. Como ambas as telas devem usar Page, Card, Field e Button row conforme definido, elas chegam com as mesmas margens, espaçamento de rótulos e posicionamento de botões. O passo Confirm ainda encaixa, mesmo com mais texto em modo read-only.
Comportamento de formulário é onde o drift costuma se infiltrar, então defina-o uma vez e reutilize: submit desabilitado até ser válido, erros inline só após blur ou submit, Enter submete só no último passo, e o botão Voltar nunca limpa valores já preenchidos.
Quando precisar de um novo pedaço de UI, não deixe o modelo improvisar. Adicione uma regra, então regenere com reuso em mente:
Transforme tokens e regras em um spec reutilizável que você realmente use. Se for longo demais para colar, não será seguido.
Um spec prático normalmente inclui: sua tabela de tokens (espaçamento, tipo, radii, cores), um conjunto curto de regras de componente (botões, inputs, cards, headings), regras de comportamento de formulário (timing de validação, erros, disabled/loading), defaults de layout (padding da página, largura máxima, espaçamento entre seções), e uma pequena lista de “nunca faça” (margens aleatórias, tamanhos de fonte ad-hoc).
Então crie um hábito: atualize o spec primeiro, não pixels individuais.
Se estiver usando Koder.ai (koder.ai), o modo de planejamento é um bom lugar para reiterar e confirmar o spec antes de gerar UI. Quando quiser testar alternativas, snapshots e rollback ajudam a explorar sem perder uma baseline estável.
Porque cada requisição de tela é um começo do zero. Se você não fornece um sistema compartilhado, o gerador preenche os detalhes faltantes chutando — espaçamentos, tamanhos de fonte, padding de botões, sombras e comportamento de formulários — e pequenas diferenças se acumulam entre páginas.
Design tokens são valores nomeados e reutilizáveis para coisas como espaçamento, tamanhos de fonte, cores e radius.
Ao invés de “padding confortável”, você usa algo como space-md. O nome permanece estável e cada tela reaplica as mesmas decisões, então a UI para de derivar.
Comece pequeno e cubra apenas o que causa drift visível:
Coloque um bloco compacto de UI spec no topo de cada requisição e trate-o como um contrato:
Depois descreva a tela abaixo. A chave é manter o spec inalterado entre as telas.
Tokens definem os números; regras de componente definem os hábitos. Regras úteis incluem:
Regra padrão: se um variante não for justificável, retorne ao padrão.
Escolha um padrão e não quebre:
Isso evita a situação comum de “uma tela valida no blur, outra só no submit”.
Padronize alguns estados não-negociáveis:
Se você não especificar estados, cada tela tende a inventar seu próprio padrão.
Não deixe o gerador improvisar o estilo. Adicione o novo componente como uma extensão documentada de um padrão existente:
Se você não consegue descrevê-lo com tokens, geralmente é custom demais e causará drift.
Crie uma tela de referência que teste o sistema (uma página com muitos formulários funciona bem) e reutilize o mesmo spec para todas as novas telas.
No Koder.ai (koder.ai), use o modo de planejamento para reavaliar e confirmar o spec antes de gerar, e use snapshots/rollback para manter uma base estável enquanto experimenta.
Faça um rápido scan antes de aceitar a tela gerada:
Se algo estiver fora, atualize o spec/tokens e regenere — não corrija margens pontuais.
Se precisar de um “novo” valor, arredonde para o token mais próximo em vez de inventar 10px ou 18px.