Geração de Cores
A semente (só o tom main/400 de cada paleta) é o único valor que vem do Figma — o resto da escala (lighter…darker + os pares on-*) é calculado, não desenhado à mão. Compare a semente no Figma com o resultado gerado:
Use o gerador abaixo para explorar/testar escalas antes de propor uma cor nova — é a mesma implementação (scripts/tokens/generator.js) usada no build real, não uma simulação à parte.
Ferramenta: Gerenciador de Tokens
Seção intitulada “Ferramenta: Gerenciador de Tokens”Como funciona
Seção intitulada “Como funciona”tokens/ seeds/ # única coisa editada a mão color.seeds.tokens.json # 1 hex por paleta (12 paletas), input do generator spacing.tokens.json # valores fixos, grade de 8pt (docs/diretrizes-de-design-tokens.md 3.1) radius.tokens.json # idem font-size.tokens.json # idem generated/ # nunca editado a mao color.tokens.json # DTCG, output de resolve-color.js — consumido pelo Style Dictionary color.legacy-resolved.tokens.json # output de build-tokens.js — consumido só pelo splice em _light.scss dist/ # output do Style Dictionary (build de teste, ver secao abaixo)Figma (só sementes) — semi-manual, ver "Sync com Figma" ↓tokens/seeds/color.seeds.tokens.json — DTCG, 1 hex por paleta ↓scripts/tokens/generator.js — puro: escala 50..900 + on-colors (APCA) ↓ ├─► scripts/tokens/build-tokens.js → tokens/generated/color.legacy-resolved.tokens.json │ → região marcada de src/scss/themes/_light.scss (mecanismo de PRODUÇÃO hoje) │ └─► scripts/tokens/resolve-color.js → tokens/generated/color.tokens.json (DTCG) → style-dictionary.config.js → tokens/dist/tokens.css (build de TESTE, paralelo)Hoje existem dois caminhos de saída porque o Style Dictionary ainda não substituiu o mecanismo de produção — ver “Style Dictionary (build de teste)” abaixo pra entender por quê e o que falta pra unificar.
src/stories/foundations/TokenManager.stories.ts (Storybook, “Foundations/Gerenciador de Tokens”)
importa as mesmas funções puras de scripts/tokens/generator.js — a lógica
de geração de escala e contraste não está mais duplicada entre a story e o
build.
Como atualizar uma cor
Seção intitulada “Como atualizar uma cor”- Edite
tokens/seeds/color.seeds.tokens.json(não edite_light.scssdiretamente — a região entre/* @mds-tokens:generated:start */e/* @mds-tokens:generated:end */é sobrescrita a cada build). - Rode
npm run tokens. - Revise o diff de
src/scss/themes/_light.scssetokens/generated/color.legacy-resolved.tokens.jsonantes de commitar. npm run tokens:verifyroda em CI (modo--check) e falha se alguém esquecer de rodar o passo 2.
Sync com Figma (semi-manual, por enquanto)
Seção intitulada “Sync com Figma (semi-manual, por enquanto)”O Figma (“Design System 2.0”) é a fonte de verdade das cores-semente, mas a sincronização ainda não é automatizada via API — é feita rodando Claude com as ferramentas MCP do Figma:
- Abrir o arquivo Figma e localizar as variáveis de semente (
_Brand-*,_Blue,_Aqua, etc. na coleção_Primitives/Colors). - Rodar
get_variable_defsnessas variáveis via Claude. - Atualizar os hex correspondentes em
tokens/seeds/color.seeds.tokens.json. - Rodar
npm run tokense revisar o diff.
brand-varejo foi removido do conjunto de paletas (2026-09-22, decisão de
design — não existe mais).
Escopo do que é gerado
Seção intitulada “Escopo do que é gerado”Duas regiões marcadas em _light.scss, ambas mecânicas a partir de
palettes.config.js:
@mds-tokens:generated— a camada de paletas (--mds-colors-palettes-<prefixo>-*, incluindogray) e os aliases semânticos (--mds-colors-primary-*,-secondary-*,-danger-*,-warning-*,-info-*,-success-*), sóvar()apontando pra paleta certa.@mds-tokens:generated-themes— os blocos&[data-primary="<prefixo>"](“modelo de tema”: troca qual paleta vira--mds-colors-primary-*via atributo), um por paleta comselectableAsPrimary: trueempalettes.config.js. Adicionado em 2026-09-22 — antes desses blocos serem gerados, eles removiam/comentavam de forma inconsistente uma linha--mds-colors-ui-primary(quebrada em 9 dos 10 blocos, referenciando uma variável inexistente; ver histórico do arquivo). Verificado que essa linha não tinha efeito real (comentada ou apontando pra var inexistente) antes de deixar de gerá-la — 130 das 140 declarações de tema batem exatamente contra o CSS compilado da produção anterior; as 10 que somem são exatamente essa linha morta.
O resto de _light.scss (buttons-*, menu-*, control-*, highlight-*,
item-*, ui-*, background-*, foreground-*) continua curado à mão —
são decisões de design sobre qual papel semântico usar em qual estado, não
cor calculável. _dark.scss está fora de escopo por
enquanto (dark mode é uma iniciativa separada, ainda não retomada).
Algoritmo de on-color (importante)
Seção intitulada “Algoritmo de on-color (importante)”Reverso-engenhado em 2026-09-22 a partir dos valores de produção — não é
o mesmo algoritmo que TokenManager.stories.ts usava até então
(selectOnColor, que buscava o melhor contraste dentro da própria escala
50..900). O valor real de produção segue um padrão diferente:
- cada paleta tem exatamente 2 candidatos: branco e preto, cada um
misturado com ~3% do matiz da própria semente (
computeOnCandidatesemgenerator.js) — pra o texto nunca ficar num branco/preto sem matiz; - para cada step, escolhe-se o candidato com maior contraste APCA em
magnitude absoluta (
pickOnColor).
Essa combinação reproduz 344 das 350 variáveis geradas byte-a-byte
contra a produção atual (sobre as 12 paletas restantes, sem brand-varejo).
As 6 exceções conhecidas:
| Variável | Produção | Gerado | Motivo |
|---|---|---|---|
brand-mobiis-on-light / on-lighter |
valor único | tint/shade padrão | drift manual já documentado no DESIGN.md (patch do primary-light) |
brand-log-light (+ seu on-) |
usa step 300 (tint 25%) | usa step 200 (tint 50%, padrão) | essa paleta parece usar um mapeamento de step diferente das outras — não normalizado ainda, ver STEP_MAP em palettes.config.js |
aqua-on-dark, brand-on-light |
prefere preto | prefere branco | empate técnico (diferença de ~2-4 Lc no APCA); WCAG concorda com a produção nesses 2 casos mas erra em ~6 outros (subpondera azul), então não foi adotado como critério geral |
brand-mobiis-dark |
#3068bc |
#3068bb |
arredondamento de 1 unidade de hex, irrelevante |
Nenhuma dessas foi “corrigida” à força — optei por manter a fórmula consistente entre as 13 paletas em vez de replicar a exceção; se alguma dessas 8 for intencional (não um erro antigo), ela deveria ser resolvida no Figma (semente ou step diferente), não hardcoded de volta no SCSS.
Style Dictionary (build de teste, 2026-09-22)
Seção intitulada “Style Dictionary (build de teste, 2026-09-22)”Rodar npm run tokens:sd gera tokens/dist/tokens.css a partir de:
tokens/generated/color.tokens.json (DTCG, saída de resolve-color.js) +
tokens/seeds/{spacing,radius,font-size}.tokens.json (valores estáticos,
sem generator — vêm direto da seção 3.1 do
documento de diretrizes).
Validado byte-a-byte contra produção: as 216 custom properties que o
Style Dictionary gera (cor + spacing + radius + font-size) batem
exatamente com o CSS compilado real (_light.scss, _spacing.scss,
_radius.scss, _typography.scss) — sem nenhum transform ou format
customizado, só estruturando o JSON como { "mds": { "<categoria>": {...} } }
pra a transform css nativa (transformGroup: 'css', kebab-case) já
produzir o nome certo (--mds-colors-palettes-brand-main,
--mds-spacing-md…).
Por que ainda é um build paralelo, não o mecanismo de produção:
tokens/dist/tokens.css é um arquivo novo — trocar o mecanismo de
produção por ele significa os consumidores do pacote publicado passarem a
importar um arquivo a mais (hoje o splice na região marcada de
_light.scss não muda o contrato de arquivos publicados). Essa é uma
decisão consciente de fazer depois, não um efeito colateral silencioso.
O que falta pra virar produção:
- Decidir o contrato de arquivo (gerar dentro de
_light.scssvia um format customizado que produz só o texto, mantendo o splice; ou aceitar o arquivo novo e atualizar quem consome o pacote). - Consolidar a resolução de cor duplicada hoje entre
build-tokens.js(splice) eresolve-color.js(DTCG) — as duas chamamgenerator.js/palettes.config.js, só formatam a saída diferente. - Adicionar uma platform
js/tspro tema do projeto React + MUI (o motivo original de trazer o Style Dictionary pra esse projeto). - Trazer spacing/radius/font-size pra dentro do arquivo real (
_spacing.scssetc. continuam hand-authored hoje — só o build de teste os replica, eles não são gerados de fato ainda).
Próximos passos
Seção intitulada “Próximos passos”- Fechar os pontos acima pra promover o Style Dictionary de “build de teste” pra mecanismo de produção.
- Automatizar a sync com Figma via REST API, se o processo semi-manual virar gargalo.
- Decidir e normalizar as exceções documentadas na seção anterior com o time de design.
- Puxar os valores reais de elevação/blur do Figma (ver documento de diretrizes, seção 3.2) antes de trazer essas duas categorias pro pipeline.