Regras de design para AI coding — por que toda IA produz a mesma UI?
Cursor, Claude Code, Cline, Windsurf — toda ferramenta de AI coding cai no mesmo conjunto de padrões. Inter 90px no título, gradiente roxo-azul, três cards iguais lado a lado. Troca o modelo — a saída praticamente não muda. ux-skill é um engine Python open source (licença MIT) com 145 regras determinísticas que barram slop no CI. Sem chamada de LLM, sem token gasto, sem telemetria.
Por que toda IA escreve a mesma UI
Não é limitação do modelo. Claude Sonnet, GPT-4, DeepSeek, Gemini — qualquer modelo grande consegue escrever UI muito boa se receber o briefing certo. O problema é que ninguém entrega briefing. "Construa uma landing page de SaaS" leva o modelo a regredir para a média do dataset de treinamento — e essa média parece uma landing page de startup de 2023.
Três forças combinadas reforçam essa impressão digital. Primeira, o corpus de treinamento dos modelos pesa para fontes populares — Vercel, Linear, Stripe, Tailwind UI, shadcn — e todas elas compartilham a mesma estética. Segunda, o prompt do usuário é curto demais — "build a hero section" não produz nada específico. Terceira, não há gating — nada barra o modelo quando ele entrega o mesmo gradiente velho pela centésima vez.
Das três forças, duas são difíceis de corrigir — você não controla o corpus de treinamento, e o hábito de escrever prompts de 500 palavras não se sustenta num time inteiro. A terceira — gating — é um problema de nível mecânico. É exatamente isso que ux-skill resolve.
Os oito padrões que toda ferramenta entrega
Rodamos o mesmo briefing — "hero para produto fintech editorial, tema escuro, voz calma" — em oito ferramentas diferentes de AI coding (Cursor, Claude Code, Windsurf, GitHub Copilot, Cline, Continue, Codex, Aider). Sete das oito produziram saídas com pelo menos cinco dos oito padrões abaixo:
- Inter como fonte de display — Inter é uma fonte body ajustada para tamanhos pequenos; usada a 90px como título, lê como impressão digital de startup-landing.
- Gradiente roxo-para-azul — os mesmos dois códigos hex em todo lugar, sinal quase universal de saída AI de SaaS-startup.
- Três cards iguais em uma linha — bloco de features, gap-6, sempre ícone-título-parágrafo.
- CTA genérica — "Get started", "Learn more", "Click here". A regra
generic-cta-textcaptura. - Fade-in-up em cada filho direto — mesmo perfil de movimento em hero, features e footer; nenhuma diferenciação por papel.
- Verbos vazios de marketing — verbos de marketing genéricos nos títulos. A regra
filler-marketing-verbscaptura. - Nomes de placeholder — nomes dummy genéricos e parágrafos stub que vazam de staging para produção.
- Eixo de tudo-no-centro — layout simétrico independentemente do conteúdo; nenhuma composição assimétrica ou bento.
A lista completa está em 35 impressões digitais de design AI — cada regra com regex de detecção, o "porquê" e o "como corrigir". O ponto que vale repetir: trocar o IDE não muda a saída de forma significativa. Trocar a gramática de design muda.
ux-skill — a camada determinística
ux-skill é um pacote Python open source (MIT), com CLI e servidor MCP. Um mesmo engine, um mesmo catálogo de 998 entradas, um mesmo linter de 145 regras. Três caminhos de instalação cobrem 17 IDEs:
- Plugin do Claude Code —
/plugin marketplace add Laith0003/ux-skill; /plugin install ux@ux-skill - Pacote Python —
pip install uxskill, em qualquer IDE que rode shell: Cursor, Windsurf, Continue, Cline, JetBrains, Aider, Zed, Codex - Servidor MCP —
npx uxskill@alpha mcp, plugável em qualquer cliente MCP
O engine tem três ações principais. Um — uxskill discover roda o protocolo de discovery de 10 campos para capturar um briefing estruturado (sem improvisação — o discovery protocol é requisito rígido). Dois — uxskill recommend roda cinco buscas paralelas sobre as 998 entradas do catálogo e devolve um sistema de design resolvido (paleta, par de fontes, motion, grid de espaçamento, lista de componentes). Três — uxskill lint roda as 145 regras regex no código. Exit 0 se limpo, exit 1 se houver finding no threshold.
Uma regra real — Inter como display
Essa é a regra número um do manifesto de 145, direto do data/anti-patterns.json. Severidade high:
// 1 das 145 regras { "id": "inter-as-display", "severity": "high", "category": "Typography", "detection": { "type": "regex", "pattern": "font-family:\s*['\"]?Inter['\"]?[^;}]*[;}][^{]*(?:font-size:\s*([4-9]\d|\d{3,})px|\btext-(5xl|6xl|7xl|8xl|9xl)\b)", "scope": ["css", "scss", "tsx", "jsx", "vue", "html"] }, "why": "Inter é uma fonte body ajustada para legibilidade em tamanhos pequenos; usada como display ela lê como a impressão digital startup-landing.", "fix": "Pareie Inter (body) com uma display face distinta: Geist, Satoshi, Cabinet Grotesk, General Sans, Outfit." }
O regex procura font-family: Inter e, no mesmo bloco, font-size a partir de 40px ou classe Tailwind text-5xl (ou maior). O campo scope limita a regra às extensões relevantes. Uma única regra funciona em CSS, SCSS, TSX, JSX, Vue, Astro, Blade.
Rodando no CI — GitHub Actions
Um arquivo de workflow, cada PR push é barrado pelo linter se houver finding no threshold. Média no repo todo: 380ms (cold), 90ms (warm). Sem chamada de LLM. Sem token gasto.
# .github/workflows/ux-lint.yml name: ux-lint on: pull_request: paths: - '**/*.{tsx,jsx,vue,css,scss,html,astro,blade}' jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: { python-version: '3.11' } - run: pip install uxskill - run: uxskill lint --threshold high
O que tem dentro das 998 entradas do catálogo
| Lane | Qtd | Conteúdo |
|---|---|---|
| Indústrias | 161 | De logística a legaltech; cada uma com perfil de voz padrão e set de padrões. |
| Estilos | 50 | Editorial cinema, swiss minimal, brutalist warm, mid-mod, neo-pop. |
| Paletas | 161 | Sistemas de cor — hue, saturação, contraste, tratamento dark-mode. |
| Pares de fonte | 57 | Combinações display + body, validadas para renderização em tela. |
| Motion presets | 57 | Framer Motion, GSAP, CSS — com ramos prefers-reduced-motion. |
| Componentes | 182 | De cards a dialogs a dashboards, com regras de composição. |
| Brand specs | 110 | Gramática de marcas reais como Stripe, Airbnb, Vercel. |
| Anti-patterns | 145 | As 145 regras do linter. Mesmo JSON, dois consumidores. |
| Outras taxonomias | 120 | Perfis de densidade, voice register, deltas para RTL. |
| Total | 998 | Uma árvore JSON. recommender, linter e servidor MCP a leem. |
Em uma codebase assistida por IA, o linter é a única superfície determinística. Toda outra checagem é probabilística.
Por que regex, e não um LLM-juiz
A alternativa comum é usar um LLM como "juiz" — pedir ao Claude ou ao GPT para avaliar a saída, aceitar a nota, reexecutar quando baixa. Esse caminho tem três problemas que se acumulam com o uso.
Um — não é determinístico. Para o mesmo input, o juiz dá notas diferentes entre execuções. Falhas de CI viram flakes, contribuidores aprendem a reexecutar em vez de corrigir, o sinal colapsa.
Dois — é caro. Cada PR push gasta token. Cada retry dobra a conta. Um repo de 200 PRs por semana rodando juiz de LLM no diff está pagando por compute para confirmar o que um regex captura em 12 milissegundos.
Três — esconde a regra. Quando o juiz reprova um PR, o autor recebe prosa. Quando o regex reprova, o autor recebe um padrão concreto contra o qual comparar o próprio código e aprender. O primeiro cria cultura de apelação; o segundo cria cultura de fluência.
A comparação honesta — estrelas no GitHub
Três projetos open source sérios na categoria bolt-on. Estrelas em 2026-05-28:
| Projeto | Stars | Recommender | Linter | MCP | Catálogo |
|---|---|---|---|---|---|
| ui-ux-pro-max | 84k | Sim | Não | Não | ~600 |
| taste-skill | 25k | Sim | Não | Não | ~480 |
| ux-skill | 14 | Sim | 145 regras | 14 tools | 998 |
ux-skill é o menor em estrelas (14) e o maior em superfície de funcionalidades. 998 entradas no catálogo, 145 regras regex que rodam no CI como exit não-zero, servidor MCP com 14 tools que alcança 17 IDEs, 22 comandos, 160 brand specs como gramática de referência, 75 testes. ui-ux-pro-max e taste-skill ambos entregam um recommender. ux-skill entrega recommender + linter + MCP. É um lance assimétrico.
Onde isso encaixa no time brasileiro de produto
Times de produto no Brasil que usam Cursor ou Claude Code têm o mesmo problema: a velocidade de codar com IA é real, mas o output regride para o mesmo conjunto de fingerprints SaaS-startup. O linter no CI corta esse caminho. Cada PR que sobe com Inter a 90px, com o gradiente roxo-azul, com os três cards padrão — falha o exit code. O time aprende a gramática da casa porque cada erro vem com a regra concreta e o fix sugerido, não com uma descrição vaga.
Para times que escrevem em português, há um benefício adicional: as regras de marketing-verb são em inglês porque o corpus de treinamento dos modelos é em inglês, mas o engine não impede que o conteúdo final seja em português. Você ganha o filtro contra o vocabulário de marketing dos modelos sem perder a voz da sua marca. As 160 brand specs incluem várias marcas que operam em mercados não-anglófonos com gramática própria — a referência funciona.
Regex captura impressões digitais estruturais, não taste.
O linter nunca vai dizer "este bloco está no ritmo errado" ou "este copy está frio". Para isso, é preciso um humano ou um modelo. O que o regex captura é toda impressão digital com token, padrão ou forma literal — e essa é a maior parte dos defaults da IA, porque o modelo volta ao mesmo artefato a cada vez.
Não rodamos LLM-juiz no CI de propósito. Se o seu critério é "parece feito por designer" — isso é code review, não lint. ux-skill entrega /ux-critique para o passe de taste — mas roda no IDE, sob demanda, e não no CI.
O que ler em seguida
Para ver o manifesto completo de 145 regras com antes/depois em um hero Next.js real, leia o post sobre regex linter. Para a taxonomia completa com regex de detecção de cada regra, leia o post das 35 impressões digitais de design AI. Para o ranking 2026 de ferramentas de AI coding por qualidade de design, leia o ranking anti-AI-slop.