Auditoria de conformidade ao design system — e a aplicação das trocas.
O caso que esta skill existe para resolver: o design system foi definido depois. As telas já existem, o protótipo já roda, e agora é preciso fazer tudo obedecer aos tokens. As dores são sempre as mesmas: fonte que não foi trocada em algum canto, uma cor específica repetida em lugares que ninguém acha, o raio de um campo fora da escala.
Esta skill segue o Método v12x: ferramenta antes de opinião, nenhum furo silencioso, refute antes de reportar, veredito não pontuação. O alvo muda — aqui a norma é o seu design system, não uma norma de segurança — mas o processo é o mesmo.
Por que é híbrida, e isso não é opcional: o app rodando é a única fonte de verdade do que
é realmente pintado (pega o CSS que o código esconde, estilo herdado, tema de biblioteca). Mas
só no código dá para trocar. Varredura que não volta ao código gera relatório que ninguém
aplica; linter de código que nunca viu a tela reporta o que não aparece e perde o que aparece.
As duas pontas se unem pelo valor bruto (#3a3a3a, 7px, Arial), que é a chave comum.
Regra dura — sem improviso (leia antes de tocar em qualquer arquivo)
Esta skill não é uma licença para refatorar telas por bom senso. O modelo tende a "melhorar" o que vê — e isso já apagou funcionalidade num app real (um toggle de tema removido no meio de uma suposta auditoria). Três travas, e nenhuma é opcional:
- Sem coletor, sem auditoria. Se você não rodou
mapear.pye não tem ummapa.json, você não auditou — você opinou. Proibido editar qualquer arquivo a partir de leitura de tela ou de intuição. O relatório sai domapa.json, não da sua impressão. - Aplicação é mecânica e nada mais. A única mudança permitida é substituir um valor bruto
por um token, linha a linha, exatamente como o
mapa.jsonmanda. É proibido tocar em import, prop, assinatura de componente, lógica, condicional, ícone, ou qualquer comportamento. Se a troca exige mexer em algo além do valor, ela não é desta skill — reporte e pare. - O que a ferramenta não mede, a skill não troca — e declara. Ícone certo para o significado, escolha semântica de token, "esse componente devia ser outro" — nada disso é conformidade de valor, nada disso é determinístico, e o modelo não deve adivinhar. Entra no mapa de cobertura como não coberto, e o código fica como está.
Se, ao aplicar, você se pegar reescrevendo um componente em vez de trocando um literal por um token: pare. Isso é o improviso que esta skill existe para não fazer.
Por que não existe pontuação
Nunca gere "89% de conformidade" nem "nota do design system". Uma tela com 200 valores certos e o botão primário fora da marca pontua alto — e é exatamente o caso que importa. Conformidade média esconde o desvio visível.
O substituto é contagem por severidade + veredito de handoff. Exemplo: 1 crítica, 3 altas. Não aprovar o handoff até resolver as críticas.
Fase −1 — Escopo e âncora
- Onde está o design system?
tokens.json(formato W3C ou plano), CSS custom properties,tailwind.config, ou o arquivo que o time usa. Sem tokens não há norma — e sem norma não há auditoria, só opinião. Se não existir, o primeiro entregável é extrair o sistema de fato (os valores mais usados viram os tokens candidatos). - Qual o inventário de telas? Liste-as antes de varrer: as que existem, as que exigem login, os modais, os estados. O que não entrar na lista não é varrido — e entra no mapa de cobertura.
- Ancore: commit do código, data, e a lista de telas varridas. Auditoria de UI sem âncora não pode ser comparada com a próxima.
Regra de cobertura (Tese 2), e aqui ela é decisiva: uma varredura de telas estáticas não vê hover, foco, disabled, erro, empty state, dark mode, nem o modal que não foi aberto. É justamente onde a padronização vaza. Isso entra no relatório como não coberto, sempre.
Fase 0 — Coleta determinística
Os dois lados. Nenhum julgamento ainda — só inventário.
Antes de coletar, veja de que é feito o alvo. Web (CSS/TSX) e nativo (Swift) têm coletores diferentes. Rodar o coletor errado acha zero arquivos e diz que está tudo conforme — o furo silencioso na sua pior forma. Confirme sempre quantos arquivos foram varridos.
Alvo Coletores Web (CSS, TSX, Vue, Svelte) coletar-tela.js+coletar-codigo.shSwiftUI / iOS nativo coletar-swift.py(tokens e usados) — ver abaixoOutra stack nenhum coletor pronto: declare como não coberto e colete à mão
Tela (a verdade do que é pintado)
scripts/coletar-tela.js roda no navegador e tabula cada valor visual com onde aparece. Uma
tela por vez; o nome da tela vira etiqueta.
# via ferramenta de browser do agente, ou colado no console
# saída: usados-<tela>.json
Varra também, como coletas separadas: cada estado relevante (hover/foco/erro/disabled), cada tema (claro/escuro) e cada breakpoint que o produto suporta. O que não for varrido é declarado.
Código (onde a troca acontece)
bash scripts/coletar-codigo.sh . > usados-codigo.json
Coleta hex/px/font hardcoded com arquivo:linha, e ignora o que já usa token
(var(--x), theme.x, $var) — isso já é conforme.
SwiftUI / iOS nativo
Não há navegador para varrer, e não é perda: SwiftUI não tem cascata nem herança arbitrária de estilo, então o valor escrito na view é o valor pintado — o código é a fonte fiel. A tela entra como verificação visual (captura antes/depois no simulador), não como extração de valores.
python3 scripts/coletar-swift.py tokens Packages/MeuDesign/Sources > tokens.json
python3 scripts/coletar-swift.py usados App MeuDesign > usados.json
O modo tokens extrai a norma do próprio pacote (Color.adaptive(light: Color(hex:)),
static let x: CGFloat, tamanhos de rubik(...)); o modo usados varre o app excluindo o
pacote de design (é lá que os tokens são legitimamente definidos) e pula linhas que já
referenciam Palette./Layout./Typography..
Ele detecta o que importa num sistema acromático: matiz nomeado (Color.red, .foregroundColor(.blue))
é violação mesmo em linha "conforme", Color(hex:) hardcoded, .font(.system(size:)),
cornerRadius: literal, .padding(N) e spacing: fora da escala.
Zero não é desvio. HStack(spacing: 0) e cornerRadius: 0 são idioma — "ausência de
propriedade" —, e nenhum design system tem token para isso. O coletor descarta.
Fora de escopo — declare, não adivinhe
O coletor mede valor (cor, tipografia, raio, espaço, sombra). Ele não julga:
- ícone — nem "asset certo para o significado", nem alinhar o ícone da tela ao catálogo do design system. Isso é escolha semântica, não distância de valor;
- qual token semântico é o certo quando o valor já é um token (usar
radiusSonde caberiaradiusMnão é hardcoded — é decisão de design); - estrutura — se um componente devia ser outro.
Nada disso é determinístico, então nada disso o modelo troca. Tudo entra no mapa de cobertura como não coberto, com uma linha dizendo o que ficou de fora e por quê. Silêncio aqui é o furo que faz o modelo preencher o vácuo com achismo.
Mapeamento (o coração determinístico)
python3 scripts/mapear.py --tokens tokens.json \
--usados usados-home.json usados-checkout.json usados-codigo.json \
--json mapa.json
Para cada valor usado, encontra o token mais próximo:
| Tipo | Métrica | Leitura |
|---|---|---|
| Cor | ΔE CIEDE2000 (perceptual, não diferença de hex) | <1 imperceptível · 1–3 só lado a lado · 3–10 distinta · >10 outra cor |
| Raio, espaço, tamanho | distância absoluta em px | 0 conforme · ≤1px quase certo · ≤3px provável · >3px sem token |
| Fonte | família normalizada | exata ou fora do sistema |
Saída: tabela valor → token sugerido, com confiança, ocorrências e onde. É ela que dirige a
troca — não é relatório de leitura, é plano de execução.
Fase 1 — Análise
Carregue a referência conforme o que apareceu:
| Camada | Quando | Referência |
|---|---|---|
| Cobertura e estados | sempre — define o que a varredura não viu | references/cobertura-e-estados.md |
| Aplicação segura | quando for trocar de fato | references/aplicacao-segura.md |
O que a ferramenta não decide: se #e11d48 é o danger errado ou um vermelho proposital
daquele componente. A máquina mede a distância; a intenção é leitura crítica. Priorize tempo
nos casos media/nenhuma — os exato/alta são mecânicos.
Fase 2 — Verificação adversarial
Nenhuma troca entra no plano sem passar por aqui:
- Onde exatamente?
arquivo:linha(código) ou seletor + tela (runtime). Sem âncora, não troca. - É mesmo desvio? O valor pode já vir de um token por outro caminho (herança, tema, biblioteca). Se vier, não é achado — a troca seria ruído.
- É one-off proposital? Ilustração, logo de terceiro, gráfico com escala própria, estado de marca de campanha. Um desvio intencional não é falha — é decisão de design. Rebaixe ou registre na linha de base.
- A troca muda o layout? Trocar
15px → 16pxdesloca tudo em volta. Espaçamento tem risco de regressão maior que cor — separe os dois lotes.
Calibragem: vale mais trocar 5 valores certos que 30 duvidosos. Uma troca errada num componente compartilhado quebra dezenas de telas de uma vez.
Fase 3 — Severidade
Por impacto visual e de marca, não por quantidade:
| Nível | Critério |
|---|---|
| Crítica | Fonte fora do design system, ou elemento que define a marca fora do token (botão primário, cor de marca, cor semântica de erro/sucesso). Bloqueia o handoff. |
| Alta | Desvio sistemático (mesmo valor errado em muitos lugares — indica componente errado propagado), ou near-miss em elemento de marca. |
| Média | Desvio isolado com distância visível; exige decisão de intenção. |
| Baixa | Diferença imperceptível (ΔE<1, ≤1px) em elemento secundário. |
Um desvio repetido sobe de nível: 14 ocorrências não são 14 erros, são um componente errado — e a correção é no componente, não nas 14 telas.
Fase 4 — Relatório e aplicação
Cabeçalho com âncora, veredito e mapa de cobertura:
Conformidade · commit a1b2c3d · 2026-08-19 · 14 telas varridas
1 crítica · 3 altas · 1 média · 2 baixas
VEREDITO: não aprovar o handoff até resolver as críticas.
COBERTO: 14 telas (claro, desktop) · código (CSS + componentes) · cor, tipografia, raio, espaço
NÃO COBERTO: estados (hover/foco/erro/disabled) · dark mode · mobile · 3 modais não abertos
· telas atrás de login
Depois, para cada achado: valor → token, ocorrências, onde, e a nota de confiança.
A aplicação segue references/aplicacao-segura.md — em lotes por tipo, do mais seguro para o
mais arriscado, com verificação na tela depois de cada lote. Nunca troque tudo de uma vez.
Antes de aplicar, o teste de uma linha: cada troca é um literal → um token, e o git diff
daquela linha mostra só isso? Se o diff removeu um import, mudou uma prop, apagou um handler
ou trocou um ícone, você saiu da skill (Regra dura, item 2) — reverta a linha e reporte como "fora
do escopo desta skill". Um git status limpo antes de começar é obrigatório, para que
git checkout/stash desfaça qualquer troca que escape.
Linha de base
Se existir .design-baseline.md na raiz, leia antes de reportar e omita o que estiver lá como
desvio aceito (o one-off proposital), citando só a contagem. Formato:
- `.grafico-receita` — paleta própria do gráfico — aceito em 2026-08-19 por: escala de dados, não é UI
O ciclo
- Persistir o relatório e o
mapa.jsonem.design-reports/AAAA-MM-DD/. A próxima auditoria diffa: valor que voltou é regressão. - Cada correção vira verificação permanente — um lint de token no CI, ou um teste que falha se um hex hardcoded reaparecer. Achado que só vive no relatório volta.
- Reauditar depois de aplicar — a Fase 0 inteira. Troca de estilo introduz regressão visual com frequência.
Quando estiver criando telas
Preventivo: antes de escrever um componente novo, use os tokens desde o primeiro commit. Conformidade nasce barata e se aplica cara.
Referências e scripts
scripts/coletar-tela.js— varredura do que é realmente pintado, tela a tela (somente leitura).scripts/coletar-codigo.sh— inventário de valores hardcoded (web), comarquivo:linha.scripts/coletar-swift.py— SwiftUI/iOS: extrai os tokens do pacote de design (tokens) e varre o app (usados), incluindo matiz nomeado — que em sistema acromático é violação.scripts/mapear.py— motor de mapeamento: ΔE de cor, distância numérica, família de fonte; emite a tabelavalor → tokene o veredito.references/cobertura-e-estados.md— o que uma varredura não vê, como varrer estados e temas, e como declarar a lacuna.references/aplicacao-segura.md— ordem dos lotes, o que é automático e o que exige decisão, verificação depois da troca, e como não quebrar o layout.