Construir um sistema de design
O vocabulário está em references/glossary.md, os padrões para proibições e larguras em references/taste.md. A aparência do próprio aplicativo é a fonte. Não invente nenhum valor de cor, fonte, sombra, gradiente ou movimento que ele já não possua, a menos que a pessoa tenha escolhido uma fonte de design e confirmado uma amostra.
Os scripts estão em scripts/ desta skill. Execute-os a partir da raiz do repositório com node e leia --help primeiro. scripts/capture.mjs tira as capturas de tela que scripts/capture-guard.mjs bloqueia (ele bloqueia toda escrita), e scripts/pixdiff.mjs as compara. Capture e pixdiff precisam de Playwright e um Chromium, que scripts/find-chromium.mjs encontra ou explica como instalar.
Etapas
-
Enquadramento. Leia AGENTS.md ou CLAUDE.md, o manifesto e a árvore de rotas. Escreva a reclamação nas palavras da pessoa, a primeira mudança visível que a responde e o fluxo piloto (aquele que a reclamação nomeia, senão o fluxo com mais famílias de componentes e um formulário com estado de erro). Adicione
.design-system/a.git/info/excludepara que nenhuma nota, captura ou arquivo temporário seja commitado. Use o branch que a pessoa nomeou como branch de execução, ou crie um e escreva o branch em que você começou em.design-system/start-branch, queland.mjsrecusa. Ofereçareferences/taste.mduma vez com suas proibições não selecionadas e salve a cópia aceita em.design-system/taste.md. Não pergunte mais nada. Use o padrão, registre-o comodefault (unanswered)e prossiga. Concluído quando a reclamação, o piloto, o branch e o arquivo de taste aceito estiverem escritos. -
Inventário e baselines. Liste cada superfície, seus estados e se ela escreve dados. Conte valores brutos em ocorrências (
#fff,text-gray-500,p-[13px]) comscripts/check-system.mjs --no-allowlist --no-self-test --json, e agrupe componentes em famílias. Capture cada superfície em cada estado na largura mais estreita e mais larga suportada (390 e 1280 por padrão), uma navegação nova por largura, antes de qualquer edição. Com o aplicativo rodando (porta 3000 aqui), liste cada superfície como uma linhasurface<TAB>route<TAB>statesem.design-system/surfaces.tsve cada escrita que o aplicativo envia comoMETHOD URLem.design-system/writes.txt, copiado do log de rede, então executenode <this skill>/scripts/capture.mjs --base http://localhost:3000 --kind before --out .design-system/captures --surfaces .design-system/surfaces.tsv --writes .design-system/writes.txt. Ele se recusa a iniciar sem--writes(ou--no-backendpara um aplicativo que não envia escritas), prova que cada escrita está bloqueada antes de abrir o navegador, salva a árvore de acessibilidade de cada captura e sai com código 1 em qualquer captura que perdeu. Exclua o que nada usa, em seu próprio commit. Concluído quando cada superfície tem uma linha de base ou uma razãonot captureddeclarada. -
Tokens. Agrupe valores brutos por função, nomeie-os por propósito e emparelhe cada superfície com seu primeiro plano (
references/tokens.md). Executetoken-mappingaté que cada valor bruto mapeie para uma função, uma mesclagem ou uma exceção listada. Mesclagens dentro da tolerância são decisões. Acima da tolerância, abra um portão por cluster cujo padrão é a mesclagem. Faça cada troca de valor idêntico em todas as rotas. Concluído quandotoken-mappingrelata zero lacunas fora da lista de exceções epixdiff.mjscom tolerância 0 relata 0% para cada superfície que uma troca tocou. -
Componentes. Construa a família mais usada de ponta a ponta primeiro (
references/components.md). O primitivo de texto e o primitivo de texto pequeno são enviados na onda 1 junto com o Button. Documente cada um comcomponent-docs. Mostre a família à pessoa antes da expansão, porque um bug central encontrado depois que as telas consomem o sistema custa uma varredura (um campo desabilitado ainda desenhado em vermelho, um Combobox 2 px mais alto que o Input, ações de painel que não quebram linha, um upload de arquivo que falha silenciosamente). Concluído quando cada componente canônico tem uma linha de registro e um documento, e seus estados desabilitado, obrigatório, erro e texto longo são capturados no showcase e mostrados à pessoa. -
Verificações. Copie
scripts/check-system.mjsescripts/oklch.mjspara dentro descripts/do repositório, execute--init, depois--init-allowlistuma vez. Uma regra só conta depois que é vista falhando: plante uma violação em uma pasta verificada, execute--files <plant> --no-allowlist, veja a saída com código 1 nomeando a regra, depois exclua a planta. A allowlist e o ratchet só encolhem. Uma proibição é enviada com sua regra de verificação na mesma mudança. Regras de cópia são enviadas com suas isenções, com escopo de elemento, para texto que deve permanecer literal (citações, termos, strings de versão) e para strings de payload que uma máquina ou pessoa cola em outro lugar (um prompt, um exemplo de API, um valor de área de transferência), porque reescrevê-los muda o que outra pessoa recebe. Concluído quando a verificação sai com 0 em um clone limpo,--self-testtermina com "all as expected", e cada regra adicionada na execução foi vista falhando em sua planta nesta sessão. -
Piloto. Mova o fluxo piloto com um codemod que você lê hunk por hunk. Capture depois com o mesmo comando da linha de base, larguras, temas e dados, mudando apenas
--kind after, então executepixdiff.mjsnas duas pastas. Uma diferença inexplicada é um defeito. Percorra o fluxo pelo teclado, force seus estados de erro e carregamento, então executeui-reviewnas capturas after. Concluído quando cada diferença nas capturas remonta a uma decisão ou portão. Uma mudança renderizada sem captura é relatada comochecks-only. -
Prontidão. Antes de uma migração se expandir, as cinco auditorias abaixo são válidas ou carregam uma isenção registrada.
-
Entrega. Reexecute as contagens. Relate o que o sistema cobre em números, primeiros os padrões não respondidos, depois o que foi encontrado e não corrigido, classificado. Ofereça a migração com seu tamanho. Não a inicie. Concluído quando cada número no relatório nomeia o comando que o produziu.
Auditorias de prontidão
Uma lacuna encontrada depois que as telas consomem o sistema custa uma varredura. Uma lacuna encontrada antes custa uma linha. Execute estas no final da etapa 5 e novamente antes da primeira onda. Escreva cada resultado em .design-system/readiness.md com uma palavra de veredito.
- Paridade de slot e prop. Cada prop de cada primitivo legado que tem locais de chamada tem uma prop correspondente no novo primitivo ou uma linha de lacuna.
- Contratos de comportamento. Uma tabela "o que dispara quando" por primitivo interativo, cada linha um teste (
references/components.md). - Paridade de tom. Cada primitivo pressionável e de linha cruzado com cada tom de status mais muted. Cada célula vazia é uma linha de lacuna ou declarada como não suportada.
- Strings fixas. Cada consulta de teste legada por nome de função ou texto tem um nome padrão no novo primitivo e uma substituição de rótulo.
- Telas mais difíceis. Um local de chamada mais difícil por família renderizado no showcase, com uma captura de tela.
Uma família que não está pronta não é migrada. Suas telas permanecem no legado.
Nunca
- Enviar por push, publicar ou implantar, a menos que a pessoa peça nesta sessão.
- Commitar no branch em que a execução começou. Crie o branch de execução primeiro.
- Stash, ou trocar de branches em um checkout sujo. Um checkout sujo recebe o branch de execução em sua própria worktree (
git worktree add). - Excluir algo que outro pacote ou uma API pública exporta. Pare, e liste como um portão com seus importadores.
- Pular uma etapa em silêncio. Se o aplicativo não compilar ou executar, o relatório diz
code-complete, not runtime-verifiede nomeia o que não foi exercitado. - Chamar seu próprio trabalho de
verified. Em um host que não pode iniciar outros agentes, execute as etapas em ordem, verifique cada uma a partir de uma leitura nova do diff e das capturas, e marque esses vereditos comoself-verified.
Regras
- Cheiros de valor bruto são
#fff,rgb(,text-gray-500,p-[13px]estyle={{ padding: 12 }}. Cada um mapeia para um token semântico ou uma exceção listada. - Um primitivo ausente é uma linha de lacuna, nunca um workaround dentro de uma superfície.
- Mesclagens de cor dentro de delta E OK 2 e mesclagens de espaçamento dentro de 2 px são decisões. Largura de borda, peso e easing não têm tolerância.
- Uma mudança que apenas adiciona semântica (um nome, uma função,
aria-current) é uma decisão. Uma que remove ou reestrutura semântica é um portão. - Errado:
{saving ? "Saving..." : "Save"}. Certo: o rótulo inativo permanece, um spinner fica dentro da mesma caixa,aria-busyé definido. - Uma correção que se repete duas vezes se torna uma regra de verificação ou um script, não outra frase.
- Uma linha de base nunca é editada para fazer um diff passar. Uma verificação que sinaliza código correto é corrigida na verificação, com um caso plantado que prova a correção, nunca dobrando o código.
- Uma contagem que nenhum script produziu, ou uma verificação nunca vista falhando, não é relatada.
Concluído
A verificação sai com 0 em um clone limpo com cada regra vista falhando, cada rota responde 200 na compilação de produção (capture.mjs --status), o piloto corresponde à sua linha de base exceto pelas mudanças intencionais listadas, e cada contagem de entrega vem de um script.
references/traps.md lista armadilhas de comportamento por ID. references/tokens.md contém camadas, nomes, tolerâncias e predefinições de movimento.