Communitygithub.com

construtor-de-sistema-de-design

Construa um novo sistema de design do zero ou audite/evolua um existente. Ative com "sistema de design", "biblioteca de componentes", "tokens de design", "guia de estilo", "auditar meu sistema de design", "comparar sistemas de design", "fortalecer meu sistema de design", ou quando solicitado a construir infraestrutura de UI reutilizável para mais de um projeto.

O que é construtor-de-sistema-de-design?

Esta skill capacita agentes de IA a construir ou auditar sistemas de design de forma robusta e metódica, evitando bugs silenciosos que quebram a interface sem erros no console. Ela estrutura o processo em fases — descobrimento, autoria de tokens, construção de primitivas, guarda automatizada, documentação, empacotamento e verificação — cada uma com regras específicas que, se ignoradas, já causaram problemas reais em produção. A skill é compatível com qualquer plataforma (Claude Code, Cursor, Codex) e enfatiza a automação de verificações via scripts (como `assets/check-tokens.template.mjs`), garantindo que regras não dependam apenas da memória humana. O diferencial é o tratamento de casos extremos mal documentados, como a composição de opacidade no Tailwind, contraste WCAG entre múltiplas superfícies, e a propagação de glifs de gradiente — tudo baseado em um catálogo de bugs reais. A abordagem também obriga a verificação cruzada entre CSS e JavaScript para animações, a não duplicação de valores em documentações estáticas, e o empacotamento real (pacote instalável) em vez de cópia de arquivos, evitando a deriva de configurações entre projetos.

Funciona com~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/rodney-hu/skills/tree/HEAD/skills/design-system-builder

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Construtor de Sistema de Design

Isto não é uma lista genérica de melhores práticas. Cada regra abaixo existe porque ignorá-la produziu um bug real e enviado — a maioria deles silenciosos (sem erro, sem falha de build, apenas errado no navegador). references/bug-catalog.md tem o incidente específico por trás de cada uma. Leia-o uma vez antes de começar um sistema grande o suficiente para importar.

A linha condutora: uma regra que vive apenas em um comentário ou em um documento acabará sendo violada acidentalmente, e a violação não gerará erro. Cada fase abaixo termina perguntando "como isso é imposto automaticamente" — se a resposta for "alguém se lembra", a fase não está concluída.

Dois pontos de entrada:

  • Construindo novo → Fases 1–7 em ordem.
  • Auditando ou evoluindo um sistema existente → Fase 8, que aponta de volta para 1–7 conforme necessário.

Fase 1 — Descobrir

Pergunte antes de construir; adivinhar aqui produz um sistema que ninguém queria, e quando isso se torna visível, é caro desfazer.

  • Material de referência como exemplos literais, não como adjetivos. "Moderno e limpo" não especifica nada; três capturas de tela sim.
  • A cor carrega significado, ou é apenas estética? Se uma paleta tem valores categóricos (elemento, status, linha de marca), decida de antemão se cada um é também um comportamento (movimento, forma, peso) ou puramente visual. Retrofitar significado a uma cor escolhida pela aparência é muito mais difícil do que decidir isso primeiro.
  • Sobre o que o conteúdo se apoia? Não presuma que o fundo de uma página e o fundo de um painel são "quase iguais". Meça combinações candidatas antes de se comprometer — veja a Fase 2.3.
  • Escopo: nova construção, refinar um sistema existente ou comparar com um sistema anterior/irmão? Rotas para a Fase 8 se não for uma construção nova e limpa.
  • Distribuição: um projeto ou reutilizado em muitos? Esta única resposta decide se a Fase 6 (empacotamento) se aplica. Erre aqui e você superengenha algo de uso único ou subengenha algo que está prestes a se espalhar por três repositórios.

Fase 2 — Autorar tokens

Em ordem de prioridade — erre estes e tudo construído sobre eles herda a fundação errada.

2.1 — Cores são autoradas uma vez, como tripletos de canal brutos, nunca como hex livre.

--fire-rgb: 170 0 0;                          /* o único valor autorado */
--fire: rgb(var(--fire-rgb));                 /* derivado */
--fire-soft: rgb(var(--fire-rgb) / 0.18);     /* derivado */

Isso não é estilístico. Os modificadores de opacidade do Tailwind (e da maioria dos sistemas utilitários) (bg-fire/40) não podem compor um canal alfa em um valor hex opaco var(--x) — a classe resolve silenciosamente para nada, sem erro, sem aviso. Este bug exato é o que iniciou a passagem de fortalecimento da qual esse padrão vem. Um número autorado por cor também significa que há apenas um lugar para alterá-lo.

2.2 — Toda cor que pode ser renderizada como texto ganha uma variante -text, e os glifos a usam, nunca a base. Verifique o contraste calculando a luminância relativa WCAG (fórmula em assets/check-tokens.template.mjs), não a olho nu. Um matiz que atinge 4,5:1 contra uma superfície pode falhar contra outra — que é exatamente por que 2.3 importa.

2.3 — Se houver mais de um nível de superfície (página / painel / rebaixado), defina-o como uma escala de elevação real e meça a separação entre os níveis antes de se comprometer. "Um pouco mais claro" não é uma decisão, é um palpite. Um sistema real inverteu um modelo de elevação inteiro (tinta-como-página → vazio-como-página) depois de enviá-lo, puramente porque alguém finalmente calculou o contraste composto real: 1,04:1 de um lado, 1,19:1 do outro. Faça essa aritmética antes de construir sobre a escolha, não depois que uma parte interessada disser "os cartões parecem planos".

Uma vez que houver uma escala, todo token seguro para texto precisa ter o contraste verificado contra cada nível em que pode aparecer, não apenas aquele para o qual foi projetado.

2.4 — Movimento: uma curva de easing, um pequeno conjunto fixo de durações. Se alguma animação JS (framer-motion, GSAP, um requestAnimationFrame manual) consumir esses valores, exporte a curva e as durações como constantes JS junto com as CSS — uma variável CSS é invisível para JavaScript, e uma bezier ou duração digitada manualmente se desvia imediata e invisivelmente. Mantenha as versões CSS e JS verificadas entre si (Fase 4).

2.5 — Limites numéricos em qualquer coisa semelhante a brilho/gradiente devem ser números reais, verificados contra o valor realmente enviado — incluindo paradas de gradiente, não apenas cores simples de alfa único. "Brilho sutil" sem um teto imposto é como o brilho ambiente de página inteira retorna, um componente de cada vez, cada um individualmente com aparência razoável.

2.6 — Cada token recebe um comentário de uma linha dizendo quando usá-lo, não apenas como ele é renderizado.

Fase 3 — Construir primitivas

  • Componentes referenciam tokens exclusivamente. Sem hex, sem valores arbitrários, sem literais do tipo white/10 — estes são exatamente o que a guarda da Fase 4 verifica, então escrevê-los agora significa apenas falhar na verificação depois.
  • Qualquer uso de modificador de opacidade (bg-x/10) deve ter como alvo um token que seja realmente composível em alfa conforme 2.1 — verificável, então verifique, não avalie a olho.
  • Não codifique uma variante nas classes base de um componente se uma prop deve substituí-la. className="shadow-lg" embutido em cada cartão, com uma prop que deve substituir por shadow-root-earth, produz dois utilitários de box-shadow com especificidade igual — o vencedor é decidido pela ordem de origem na folha de estilo gerada, silenciosamente. Torne a variante uma tabela de consulta chaveada pela prop (Record<Variant, string>), nunca uma classe base mais uma substituição esperada.
  • Uma prop de estilo não substitui um elemento interativo real. Um cartão que parece clicável (cursor-pointer, elevação ao passar o mouse) via uma prop interactive, mas é uma <div>, dá a um usuário de mouse uma affordance que um usuário de teclado nunca recebe — sem anel de foco, sem role, sem ativação. Se algo deve ser clicado, renderize um <a> ou <button> (um par CardLink/CardButton), não uma alternância de estilo na versão passiva.
  • Para componentes interativos genuinamente complexos (modal, abas, toast), aproveite a plataforma. O <dialog> nativo fornece uma armadilha de foco e Escape-para-fechar gratuitamente; versões feitas à mão invariavelmente erram um desses. O roving tabindex para abas é a coisa mais comum que implementações de abas feitas à mão erram (cada aba inativa permanece um ponto de parada de Tab) — verifique explicitamente (os tabindexes se movem [0,-1,-1,-1] → [-1,0,-1,-1] na navegação por seta), não presuma.
  • Se o sistema precisar de ativos de ícone/marca personalizados, fixe as regras de desenho antecipadamente (grade, peso do traço, estilo de ponta) e imponha-as da mesma forma que as regras de cor — isso também é trabalho da Fase 4.

Fase 4 — Proteger

Escreva um script de verificação pequeno, idealmente com zero dependências. Este é o artefato de maior alavancagem em todo o processo — cada bug em references/bug-catalog.md era uma regra que existia apenas em prosa até que alguém a codificou aqui.

Cobertura mínima (adapte assets/check-tokens.template.mjs):

  • Cada token que um componente ou predefinição referencia realmente existe.
  • Nenhum hex digitado manualmente ou cor de opacidade literal no código-fonte do componente.
  • Contraste WCAG para cada token seguro para texto contra cada nível de superfície em que pode aparecer (2.3).
  • Limites numéricos documentados impostos como números no valor real enviado — incluindo a parada mais brilhante de um gradiente, não apenas cores simples (2.5).
  • Constantes de movimento JS correspondem às suas contrapartes de token CSS (2.4).
  • Regras estruturais que são fáceis de violar acidentalmente — por exemplo, "sem brilho de fundo de página inteira": verifique se um utilitário de brilho nunca é aplicado a um elemento de nível de página, não apenas que o alfa do token é limitado.
  • Escopo qualquer regra que possa corresponder a prosa comum (por exemplo, uma regra sobre "uma segunda curva de easing") para contextos de código reais — atributos de classe, valores CSS — não texto arbitrário. Um linter que sinaliza sua própria documentação acaba sendo desabilitado, o que anula o propósito.

A verificação deve eventualmente ser executada contra projetos consumidores, não apenas o próprio repositório do sistema. Esta é a maior lição disponível aqui: em um sistema real, toda violação de regra que realmente aconteceu — onze tamanhos de fonte abaixo de 24px, três tamanhos diferentes de <h2> em um site, cinco valores de letter-spacing concorrentes, uma segunda curva de easing, durações inventadas — aconteceu em um projeto consumindo o sistema, e a verificação interna nunca olhou lá. Por muito tempo, estava protegendo código que nunca havia quebrado uma regra. Envie o verificador para que seja executável contra código-fonte arbitrário (npx your-check ./src) e dê a ele uma escotilha de escape com escopo para exceções genuínas (uma convenção de comentário your-check-allow: <rule> — <reason>), em vez de fazer as pessoas desabilitarem a verificação inteira.

Teste negativamente cada verificação antes de confiar nela. Quebre deliberadamente cada regra em uma cópia de rascunho e confirme que o script realmente falha nela. Uma verificação que nunca foi observada falhar não é verificada — você não sabe se funciona ou está silenciosamente inerte.

Fase 5 — Documentar

Três arquivos, divididos por público-alvo — resista ao impulso de adicionar um quarto. Um quarto documento (um "design.md" agregado, um segundo guia de estilo como documento) é um segundo lugar para os mesmos valores se desviarem; três que cada um possui uma questão distinta (porquê / o-que-fazer / o-que-foi-decidido) é suficiente.

  • philosophy.md — o porquê, a identidade, o significado por trás das escolhas. Lido uma vez, raramente relido.
  • foundations.md — as regras operacionais. O que alguém verifica antes de construir algo novo. Deve mapear aproximadamente 1:1 para o que a guarda da Fase 4 impõe — se uma regra está em um e não no outro, escolha qual está faltando e corrija.
  • decisions.md — um registro contínuo, entrada mais recente primeiro, de julgamentos específicos e porquê. Nunca exclua uma entrada substituída. Marque-a como substituída e explique o que mudou e porquê. Reverter uma decisão real (um modelo de elevação, uma hierarquia de acento) sem uma trilha de papel força a próxima pessoa — muitas vezes o você do futuro — a derivar o raciocínio do zero, ou pior, a quebrar silenciosamente o que a decisão original corrigiu.
  • Uma vitrine viva que renderiza os tokens e componentes reais — não uma descrição deles. Se não puder literalmente importar o pacote (um documento HTML estático de arquivo único, por exemplo), está carregando uma segunda cópia inline de cada valor, e essa cópia vai se desviar: a vitrine de um sistema real ficou silenciosamente duas versões atrás de seus próprios tokens antes que alguém a reconstruísse como algo que importa o pacote real. A correção mais rápida, se uma vitrine estática for inevitável por um tempo, é a Fase 4 protegendo a cópia inline contra a fonte real — mas planeje aposentá-la assim que o sistema estiver estável o suficiente para ter um consumidor real.
  • Se a vitrine for implantável, implante-a em uma URL real e visualize-a em uma viewport real e estreita. Um bug de layout que só aparece quando uma seção específica é mais estreita que seu conteúdo (um elemento decorativo intencionalmente transbordando alargando todo o documento, por exemplo) é invisível para todas as verificações estáticas — não é uma violação de token, não é uma falha de contraste, não é um erro de lint. Ele só existe em um navegador real em uma largura real. Um desses bugs foi enviado e sobreviveu a três versões porque o único lugar onde o sistema era visto era um arquivo local.
  • Escreva uma política de versionamento e a ordem para ler os documentos, uma vez que houver mais de um documento. Custa um parágrafo, salva alguém de derivá-lo novamente.

Fase 6 — Empacotar e distribuir

Somente se a Fase 1 disse "reutilizado em projetos".

  • Envie como um pacote instalável (package.json com um mapa exports). Nunca "copie estes arquivos para seu projeto" — copiar não tem caminho para uma correção downstream fluir de volta upstream, que é como a própria fonte da verdade de um sistema silenciosamente se torna a mais quebrada de duas cópias. Esta foi a causa raiz do primeiro bug em toda esta linhagem.
  • Se estiver distribuindo uma predefinição do Tailwind: o array content de uma predefinição NÃO é mesclado pelo Tailwind. O próprio array content de um consumidor substitui completamente o da predefinição. Este é o segundo bug mais caro no catálogo, e a correção "óbvia" — declarar os globs na predefinição e presumir que eles se combinam — não funciona; o build volta byte-idêntico, que é o indicador. A predefinição deve exportar seus globs, e cada peça de integração (README, um comando de scaffold se existir) deve mostrar os consumidores espalhando-os explicitamente: content: [...preset.content, ...yourGlobs]. Verifique isso com a própria API de resolução de configuração do bundler, não presuma — um artefato de build inalterado após uma "correção" é um sinal de bug, não uma coincidência.
  • Versione com tags, não apenas branches. Um pin de branch se move silenciosamente sob um consumidor no momento em que o branch do repositório de origem avança — que é exatamente como um consumidor pode acabar enviando uma versão não testada sem que ninguém decida isso. Se um consumidor precisar mover para uma nova tag, lembre-se de que lockfiles podem fixar o commit resolvido exato independentemente do que a tag em package.json diz — force a re-resolução e verifique se node_modules realmente relata a nova versão antes de confiar em um rebuild.
  • Se o pacote oferecer um comando de scaffold/init para novos consumidores, faça com que ele emita a configuração de conteúdo correta e espalhada desde o primeiro dia — não confie na disciplina de leitura de README de cada consumidor para uma armadilha séria o suficiente para ter sua própria entrada no registro de decisões.

Fase 7 — Verificar

Aplica-se continuamente, não apenas uma vez no final.

  • Teste contra uma instalação ou clone limpos, não o diretório de trabalho. Um diretório de trabalho esconde exportações ausentes, correções não commitadas e caches obsoletos que um consumidor real encontrará no primeiro dia.
  • Um artefato de build inalterado após uma "correção" é um sinal de que a correção não funcionou, não uma coincidência. Compare a saída real antes de acreditar que algo mudou.
  • Typechecking não é verificação. O bug mais sério neste catálogo — uma fonte renderizando no tipo de letra completamente errado — passou em todas as verificações estáticas disponíveis e só foi pego ao renderizar o componente em um consumidor real e olhar para ele. Renderize tudo pelo menos uma vez em algo real antes de considerar concluído.
  • Desconfie de APIs de plataforma de aparência conveniente para alegações de verificação. document.fonts.check() parece exatamente a ferramenta certa para "essa fonte realmente contém este glifo" e mente (relata disponibilidade mesmo quando a fonte está ausente em alguns navegadores). Teste o comportamento real, não uma API que promete verificar.

Fase 8 — Auditar ou evoluir

Para sistemas existentes. Aplique isto como uma passagem de diagnóstico antes de tocar em qualquer token ou componente.

  1. Execute a verificação da Fase 4 contra o sistema existente, mesmo que ele nunca tenha tido uma. Os resultados lhe dirão: (a) quais regras estão sendo violadas agora e (b) se alguma verificação que você esperava falhar não falhou — o que significa que pode estar faltando uma verificação.
  2. Diferencie entre violações quebráveis e violações acidentais.
    • Uma violação quebrável: um token cujo valor está errado e que você pode corrigir sem efeito colateral. Corrija diretamente.
    • Uma violação acidental: uma regra que o sistema nunca pretendeu seguir (por exemplo, "toda cor tem um canal alfa" quando seu sistema foi construído antes dessa regra existir). Decida se a regra deve ser aplicada retroativamente ou se o sistema existente obtém uma escotilha de escape com escopo (veja Fase 4) até uma migração planejada.
  3. Olhe para decisions.md se ele existir. Se alguma decisão importante não estiver documentada, adicione-a com uma nota sobre como você a descobriu.
  4. Verifique a consistência da vitrine contra o pacote enviado — veja a Fase 5, nota sobre desvio de vitrine. Se a vitrine é uma cópia estática, marque-a como obsoleta e priorize movê-la para importações reais.
  5. Teste a distribuição: se o sistema já está sendo consumido por vários projetos, verifique se cada consumidor tem a versão mais recente, ou pelo menos tenha um diff claro entre o que eles têm e o que o sistema declara. Isso é frequentemente a fonte mais dolorosa do "funciona na minha máquina", onde o sistema parece correto no repositório de origem, mas as importações reais estão desatualizadas.
  6. Produza um relatório listando:
    • O que foi corrigido imediatamente.
    • O que precisa de uma mudança quebrando e em que cronograma.
    • Quais verificações foram adicionadas ou faltando.
    • Uma estimativa de quanto do sistema existente está em conformidade com as regras atuais (porcentagem de tokens aprovados, componentes aprovados, etc.).

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Habilidades Relacionadas