ultrahand: theme
Construa o tema de um projeto uma vez e evolua a partir daí. O tema é um arquivo de tokens de design mais um breve registro de suas decisões, mantido no projeto, para que todo design e revisão posterior se baseiem na mesma fundação, em vez de começar uma nova aparência. O formato do arquivo está em shared/theme/README.md; as regras estão em shared/theme/rules.md, e cada regra cita shared/theme/sources.md.
Todo tema mantém os itens não negociáveis (NN-1 a NN-12: camadas, grid de 8 pontos, ambos os esquemas, contraste, uma escala tipográfica real e o restante) e faz uma escolha nova em cada eixo criativo (CR-1 a CR-10: matiz, neutros, voz tipográfica, cantos, profundidade, densidade…). As regras são fixas para que todo tema pareça bem feito; os eixos são abertos para que não haja dois produtos com a mesma aparência. Leia rules.md antes de começar.
Os scripts abaixo estão em ${CLAUDE_PLUGIN_ROOT}/shared/theme/.
1. Descubra o que existe
Olhe antes de perguntar. Para um design que existe apenas como artefato de canvas, liste os
arquivos do artefato e leia design/ a partir dali. No projeto, procure por design/THEME.md, *.tokens.json,
tokens/, uma configuração do Style Dictionary e o código de tema da plataforma: propriedades CSS customizadas,
tailwind.config.*, Flutter ThemeData / ColorScheme, assets de cor do SwiftUI,
Compose MaterialTheme. O resultado define o modo:
| Encontrado | Modo |
|---|---|
| Um arquivo de tema e THEME.md | Evoluir (passo 4). Nunca o regenere. |
| Nenhum arquivo de tema, mas código estilizado | Extrair (passo 2), depois evoluir. |
| Nada (um novo produto) | Criar (passo 3). |
2. Extraia o tema que o código já possui
O objetivo é capturar a aparência atual, limpa, e não redesenhar.
- Execute
node scan.mjs <src dir>(adicione--jsonpara as listas completas). Ele lista cada cor, valor de espaçamento, raio e tamanho de fonte com contagens e localizações, agrupa cores quase duplicadas e sinaliza espaçamentos fora do grid. Leia também o código de tema da plataforma: os valores que um objeto de tema nomeia são os pretendidos, e os valores brutos espalhados são os desvios. - Nomeie os papéis. Para cada cluster de cor, descubra para que é usado (fundo de página, texto do corpo, botões, bordas, erros) e mapeie para um papel semântico (README.md lista os obrigatórios). Um papel, um valor: quando dois quase duplicados servem a um papel, mantenha o mais usado.
- Ajuste às regras. Dobre o espaçamento na escala NN-2, tamanhos em uma escala tipográfica
(NN-6), raios em uma escala curta (NN-7). Corrija falhas de contraste movendo-se ao longo dos
passos tonais do mesmo matiz (NN-4). Cada mudança é uma alteração visível no produto, então liste-as
como uma tabela (
13px → 12px, 4 lugares) para o proprietário aprovar, e mantenha tudo o que eles quiserem inalterado. - Preencha as lacunas. A maioria dos códigos não tem modo escuro, anel de foco e papéis
on-. Projete-os na própria paleta do tema (NN-3, NN-10) em vez de adicionar genéricos. - Inventarie os componentes. Liste os componentes reutilizáveis (procure em
components/,ui/,widgets/,views/), suas variantes e onde cada um é definido. Observe qualquer trabalho feito por dois componentes diferentes: é um candidato a mesclagem (EV-4), não algo para copiar no tema. - Registre a personalidade que já possui. Posicione a aparência existente em cada eixo
criativo e escreva em THEME.md. Escolhas dadas pela marca (matiz do logotipo, fontes licenciadas) são
locked(travadas); o restante sãoopen(abertas).
Em seguida, escreva os arquivos (passo 5).
3. Crie um novo tema
- Personalidade. Peça três adjetivos e para quem é, além de qualquer coisa fixa: cores da marca, logotipo, fontes, plataforma (aplicativos nativos iOS ou Android tendem a usar a fonte e cores do sistema; o tema se mapeia sobre eles [HIG-COLOR] [M3-COMPOSE]).
- Três direções. Proponha três direções que difiram em pelo menos três eixos criativos, cada uma com uma justificativa de uma linha ligada aos adjetivos. Evite a aparência padrão que rules.md descreve, a menos que o proprietário a queira. Mostre-as lado a lado (passo 6), e deixe o proprietário escolher uma ou misturá-las.
- Construa.
- Paleta: para cada cor chave (primária, neutra, mais erro e qualquer destaque), uma escala tonal de cerca de 10–13 passos do escuro ao claro [M3-HCT] [M3-COMPOSE], para que cada papel possa encontrar um passo que atenda ao contraste em ambos os esquemas.
- Cores semânticas: cada papel obrigatório, cada um com seu valor escuro, cada
on-Xprojetado contraX. - Espaço: a escala NN-2, depois espaçamento semântico por função: passos
insetpara padding, egap-related,gap-groupegap-sectionpara que a regra de composição de que lacunas entre grupos são claramente maiores que lacunas dentro deles (SEC-2 em shared/composition/principles.md) seja incorporada. - Tipografia: uma escala da proporção escolhida (CR-5), com papéis display, headline, title, body, label; body no padrão da plataforma (16 na web, 17 pt no iOS; 13–14 apenas para uma ferramenta de desktop densa, veja NN-6).
- Forma, profundidade, movimento, foco: uma escala de raio no estilo de canto escolhido; níveis de elevação no método de profundidade escolhido; tokens de duração e easing; um anel de foco de 2 px ou mais.
- Componentes: apenas os tokens de componente que um componente precisa para diferir de seu papel (EV-2). A maioria dos componentes não precisa de nenhum.
Comece cada valor na versão 1.0.0.
4. Evolua um tema existente
Para uma solicitação como "adicione uma cor de aviso", "precisamos de uma tabela mais densa", "deixe mais
quente", ou uma skill de design ou theme-review propondo adições:
- Leia THEME.md e os tokens primeiro (EV-1). Respeite decisões
locked; se a solicitação precisar que uma seja alterada, diga e peça. - Reutilize um papel existente se um se encaixar (EV-2). Adicione um token apenas para uma lacuna real, aliado a um passo primitivo existente (EV-3).
- Uma mudança ampla ("mais quente", "mais divertido") move um eixo criativo
open: desloque os primitivos, mantenha cada nome semântico e reexecute a verificação de contraste. Os nomes permanecem verdadeiros através de um rebranding (NN-11). - Aposente com
$deprecatednomeando a substituição; remova em uma versão posterior (EV-6). - Aumente a versão e adicione uma linha de changelog dizendo o que mudou e quais telas precisaram disso (EV-5).
5. Escreva e verifique
- Escreva
design/theme.tokens.json(ou a localização de tokens existente do projeto) edesign/THEME.md, seguindo README.md. example.tokens.json mostra a estrutura. - Execute
node check.mjs design/theme.tokens.jsone corrija todos os erros. Um aviso precisa de uma correção ou de uma razão em THEME.md. - Entregue ao código. Para a web,
node css.mjs design/theme.tokens.json --out <path>/theme.cssfornece propriedades CSS customizadas com modo escuro embutido. Para outras plataformas, ou várias de uma vez, recomende o Style Dictionary, que lê este formato e escreve Swift, Android, Compose e Flutter [STYLE-DICT]. Ofereça-se para substituir os valores brutos que a varredura encontrou por tokens; não faça isso sem perguntar, pois toca em todos os arquivos estilizados.
6. Mostre o tema
Construa um espécime no canvas do plugin (shared/canvas/; seu README tem o contrato) para que o
proprietário veja o tema funcionando, não uma lista de códigos hexadecimais:
node "${CLAUDE_PLUGIN_ROOT}/shared/theme/css.mjs" design/theme.tokens.json --style --out theme.html
node "${CLAUDE_PLUGIN_ROOT}/shared/canvas/build.mjs" \
--presets "${CLAUDE_PLUGIN_ROOT}/skills/desktop/references/presets.md" \
--head theme.html --screen screen.html --title "<Produto> tema" --out index.html
O screen.html do espécime usa apenas as propriedades customizadas do tema e mostra: papéis de
cor como texto on-X em X com a proporção medida; a escala tipográfica com texto real; a
escala de espaçamento; níveis de raio e elevação; cada componente inventariado em seus estados; e uma
pequena tela realista (uma lista e um formulário) construída a partir disso. Os toggles de Claro / Escuro e
texto em 200% do canvas testam ambos os esquemas e o escalonamento de texto. Se o tema precisar de uma fonte web,
coloque seu <link> no mesmo arquivo head.
Comparando direções (passo 3): emita cada direção sem --style, com escopo usando
--selector '[data-state="a"]' (depois b, c), e cole-as no topo do próprio <style> do modelo de tela:
o canvas define data-state dentro da tela, onde o head da página não pode alcançar. Declare states
a, b, c em config.json com os nomes das direções como rótulos, e o seletor de Estado alterna entre eles.
Publique index.html como um artefato. Quando o design em si é um artefato, republique-o
construído com o tema (--head theme.html) e inclua os dois arquivos design/.
7. Apresente
Compartilhe o link do artefato. Em poucas linhas: o modo (criado, extraído ou evoluído), a
versão, onde a personalidade está nos eixos criativos e por quê, o que está travado e o que está
aberto, quaisquer mudanças de ajuste que o proprietário precisa aprovar, o resultado da verificação e o
próximo passo: projetar com ele (as skills mobile, tablet e desktop o leem), ou auditar o
código contra ele com theme-review.