Design Canon — engine de disciplina de design
Gera tokens de design determinísticos aplicando uma disciplina (método) aos valores de qualquer design system. Emite seis formatos sem dependência externa.
O MODELO: disciplina ⊥ marca
Duas coisas ortogonais. Não as confunda — é o eixo inteiro da skill.
|
O quê |
De onde vem |
| Disciplina (preset) |
O método: razão da escala de tipo, set de grids canônicos, pesos de régua, regras de alinhamento, semântica de cor (identificador vs. livre), estratégia de fallback de fonte. A régua. |
--preset (embutido no script) ou um config custom |
| Marca (input) |
Os valores: paleta, fontes, tamanho base. O conteúdo. |
--config DS.json e/ou flags (--primary, --base, --face) |
Você renderiza os valores da marca através de uma disciplina. O mesmo DS da MSCS pode sair pela disciplina Vignelli (cor = identificador, dois tamanhos, régua dura) ou pela blank (sem opiniões, só normaliza). A disciplina nunca troca os valores da marca — ela impõe a estrutura e avisa quando a marca viola o método.
QUANDO USAR
- Tokens de design para handoff dev a partir de uma paleta/tipografia (qualquer marca)
- Normalizar um DS existente em tokens multi-formato (CSS / SCSS / Tailwind / JSON / W3C / Style Dictionary)
- Aplicar rigor de método (Vignelli, suíço) a um DS de cliente ou ao DS da casa
- Sistema de identidade: grid + escala de tipo + cor como identificador
- Spec de sinalização / wayfinding (presets que definem signage, ex.: vignelli)
Quando NÃO usar: redigir copy de marca (isso é mscreative-voice/supercopy); desenhar layout final no navegador (isso é trabalho de front-end, não de tokens). Esta skill produz os tokens e o método, não a peça.
GERADOR
Script único, autocontido, em scripts/design_canon.py. Os presets vivem embutidos nele (fonte de verdade), então roda mesmo sem nenhuma referência carregada.
python3 scripts/design_canon.py --list-presets # disciplinas disponíveis
python3 scripts/design_canon.py --config DS.json --format tailwind # SEU DS no @theme do Tailwind v4
python3 scripts/design_canon.py --config DS.json --preset vignelli --format css
python3 scripts/design_canon.py --preset vignelli --primary "#0039A6" # troca só a cor identificadora
python3 scripts/design_canon.py --config DS.json --format w3c # W3C Design Tokens
python3 scripts/design_canon.py --config DS.json --format style-dictionary
python3 scripts/design_canon.py --config DS.json --format scss
python3 scripts/design_canon.py --preset vignelli --grid 4x8 # mapa coluna × módulo
python3 scripts/design_canon.py --preset vignelli --signage # tabela de painéis
Flags batem sobre o config (precedência: flag > config > default do preset). Avisos de disciplina (paleta diluindo a cor-identificador, limite de tamanhos de tipo) saem em stderr — não poluem o token output.
Config da marca (JSON)
{
"name": "MSCS DS V3.0",
"base_px": 16,
"prefix": "ms",
"palette": { "primary": "#B4C636", "bg": "#0A0A0E", "fg": "#B2A898" },
"fonts": { "serif": "Fraunces", "sans": "Inter Tight", "mono": "IBM Plex Mono" }
}
Só palette é o mínimo útil. O resto cai no default do preset. Schema completo: references/config_schema.md. Exemplo pronto: assets/examples/mscs_ds_v3.json.
Formatos de saída
css (:root custom properties) · scss (maps) · tailwind (bloco @theme v4, namespaces --color-*/--font-*/--text-*) · json (payload legível) · w3c (Design Tokens spec, $value/$type) · style-dictionary (nós aninhados com value).
PRESETS (disciplinas)
| Preset |
Disciplina |
Quando |
blank |
Passthrough sem opiniões. Escala modular ~1.25, grids de coluna comuns, sem régua, sem semântica de cor. |
Só normalizar um DS existente em tokens. Default. |
vignelli |
O Canon: cor = identificador (uma por linha), dois tamanhos de tipo (heading ≈ 2× body), cinco grids, réguas 2/1/0.5pt, flush-left, signage Grandi Stazioni. |
Rigor editorial/identidade. Detalhe em references/vignelli.md. |
swiss |
Estilo tipográfico internacional: grade matemática, escala modular, máx. três tamanhos, flush-left. |
Objetividade, sistemas densos de informação. |
Documentação dos presets e como adicionar um: references/presets.md.
REGRAS DURAS (não violar)
Invariantes do método. Quebrar descaracteriza a engine.
- Disciplina ⊥ marca. O preset impõe estrutura; a marca fornece valores. Nunca deixe um valor de marca virar regra de método, nem um default de disciplina sobrescrever um valor que a marca declarou.
- Fallback de render é obrigatório. Toda família de fonte recebe um fallback de métrica compatível instalado (
'Liberation Sans' antes de Arial e do genérico) — senão o headless cai para Noto/Calibri e quebra a grotesca. Confirme com fc-match antes de publicar.
- Keyword genérica de fonte vai por último (
sans-serif, monospace…); famílias com espaço são aspeadas.
- Avisos de disciplina vão pra
stderr, nunca misturados no token output.
- Gerador determinístico. Zero rede, zero credencial. Presets embutidos no script.
- Sob disciplina
identifier (vignelli/swiss): cor é identificador, uma por linha/sistema. O engine avisa se a paleta tem acentos demais — respeite o aviso ou troque de preset.
- Sob
vignelli: dois tamanhos de tipo vivos por página (heading ≈ 2× body), flush-left, o tipo pendura na régua. Os demais degraus existem só para capas/specs.
ARMADILHA — Helvetica/house face em headless
A house face de uma grotesca não existe na maioria dos ambientes headless. Ao rasterizar (cairosvg, Chromium headless) ou alimentar arte para um modelo de imagem, o render cai para Noto Sans (lê como Calibri) e quebra a grotesca. O engine já anexa 'Liberation Sans' antes de Arial em toda família sans por isso. Sempre confira um render com fc-match <fonte> no ambiente antes de publicar.
FALLBACK_INLINE
Usar quando scripts/ e references/ não carregarem.
Tokens mínimos (CSS, disciplina blank, base 16px)
:root{
--ds-color-primary:#2D2D2D; --ds-color-bg:#FFFFFF; --ds-color-fg:#111111;
--ds-font-sans:'Inter','Liberation Sans',Arial,sans-serif;
--ds-text-base:16px; --ds-text-lg:20px; --ds-text-3xl:39px; /* escala ~1.25 */
}
Sob Vignelli: troque para dois tamanhos (--v-text-body:16px; --v-text-heading:32px), adicione réguas (--v-rule-major:2pt; --v-rule-minor:.5pt), paleta-identificador, flush-left.
QA mínimo
1---2name: design-canon3description: Aplica uma DISCIPLINA de design (preset) aos tokens de QUALQUER design system e emite em CSS, SCSS, Tailwind v4 @theme, JSON, W3C Design Tokens e Style Dictionary. Modelo — disciplina ⊥ marca - o preset traz o método (razão de escala de tipo, grids, pesos de régua, semântica de cor, fallback de fonte); a marca traz os valores (paleta, fontes, base) via config JSON ou flags. Presets - vignelli (Canon), swiss (estilo internacional), blank (passthrough). Determinístico, zero rede. MANDATORY TRIGGERS — design tokens, tokens de design, design system, gerar/exportar tokens, Tailwind theme, @theme, W3C design tokens, style dictionary, escala de tipo, type scale, set de grid, pesos de régua, paleta como identificador, handoff dev, normalizar design system, método Vignelli, estilo suíço, swiss style, converter paleta em tokens. Use SEMPRE que o pedido for gerar, normalizar, exportar ou disciplinar tokens de design a partir de paleta/tipografia/grid — mesmo sem citar a skill.4---56# Design Canon — engine de disciplina de design78Gera tokens de design determinísticos aplicando uma **disciplina** (método) aos **valores** de qualquer design system. Emite seis formatos sem dependência externa.910## O MODELO: disciplina ⊥ marca1112Duas coisas ortogonais. Não as confunda — é o eixo inteiro da skill.1314| | O quê | De onde vem |15|---|---|---|16| **Disciplina** (preset) | O método: razão da escala de tipo, set de grids canônicos, pesos de régua, regras de alinhamento, semântica de cor (identificador vs. livre), estratégia de fallback de fonte. **A régua.** | `--preset` (embutido no script) ou um config custom |17| **Marca** (input) | Os valores: paleta, fontes, tamanho base. **O conteúdo.** | `--config DS.json` e/ou flags (`--primary`, `--base`, `--face`) |1819Você renderiza os valores da marca **através de** uma disciplina. O mesmo DS da MSCS pode sair pela disciplina Vignelli (cor = identificador, dois tamanhos, régua dura) ou pela `blank` (sem opiniões, só normaliza). A disciplina nunca troca os valores da marca — ela impõe a *estrutura* e *avisa* quando a marca viola o método.2021## QUANDO USAR2223- Tokens de design para handoff dev a partir de uma paleta/tipografia (qualquer marca)24- Normalizar um DS existente em tokens multi-formato (CSS / SCSS / Tailwind / JSON / W3C / Style Dictionary)25- Aplicar rigor de método (Vignelli, suíço) a um DS de cliente ou ao DS da casa26- Sistema de identidade: grid + escala de tipo + cor como identificador27- Spec de sinalização / wayfinding (presets que definem signage, ex.: vignelli)2829**Quando NÃO usar:** redigir copy de marca (isso é `mscreative-voice`/`supercopy`); desenhar layout final no navegador (isso é trabalho de front-end, não de tokens). Esta skill produz os *tokens* e o *método*, não a peça.3031## GERADOR3233Script único, autocontido, em `scripts/design_canon.py`. Os presets vivem embutidos nele (fonte de verdade), então roda mesmo sem nenhuma referência carregada.3435```bash36python3 scripts/design_canon.py --list-presets # disciplinas disponíveis37python3 scripts/design_canon.py --config DS.json --format tailwind # SEU DS no @theme do Tailwind v438python3 scripts/design_canon.py --config DS.json --preset vignelli --format css39python3 scripts/design_canon.py --preset vignelli --primary "#0039A6" # troca só a cor identificadora40python3 scripts/design_canon.py --config DS.json --format w3c # W3C Design Tokens41python3 scripts/design_canon.py --config DS.json --format style-dictionary42python3 scripts/design_canon.py --config DS.json --format scss43python3 scripts/design_canon.py --preset vignelli --grid 4x8 # mapa coluna × módulo44python3 scripts/design_canon.py --preset vignelli --signage # tabela de painéis45```4647Flags batem sobre o config (precedência: flag > config > default do preset). Avisos de disciplina (paleta diluindo a cor-identificador, limite de tamanhos de tipo) saem em `stderr` — não poluem o token output.4849### Config da marca (JSON)5051```json52{53 "name": "MSCS DS V3.0",54 "base_px": 16,55 "prefix": "ms",56 "palette": { "primary": "#B4C636", "bg": "#0A0A0E", "fg": "#B2A898" },57 "fonts": { "serif": "Fraunces", "sans": "Inter Tight", "mono": "IBM Plex Mono" }58}59```6061Só `palette` é o mínimo útil. O resto cai no default do preset. Schema completo: `references/config_schema.md`. Exemplo pronto: `assets/examples/mscs_ds_v3.json`.6263### Formatos de saída6465`css` (`:root` custom properties) · `scss` (maps) · `tailwind` (bloco `@theme` v4, namespaces `--color-*`/`--font-*`/`--text-*`) · `json` (payload legível) · `w3c` (Design Tokens spec, `$value`/`$type`) · `style-dictionary` (nós aninhados com `value`).6667## PRESETS (disciplinas)6869| Preset | Disciplina | Quando |70|---|---|---|71| `blank` | Passthrough sem opiniões. Escala modular ~1.25, grids de coluna comuns, sem régua, sem semântica de cor. | Só normalizar um DS existente em tokens. **Default.** |72| `vignelli` | O Canon: cor = identificador (uma por linha), dois tamanhos de tipo (heading ≈ 2× body), cinco grids, réguas 2/1/0.5pt, flush-left, signage Grandi Stazioni. | Rigor editorial/identidade. Detalhe em `references/vignelli.md`. |73| `swiss` | Estilo tipográfico internacional: grade matemática, escala modular, máx. três tamanhos, flush-left. | Objetividade, sistemas densos de informação. |7475Documentação dos presets e como adicionar um: `references/presets.md`.7677## REGRAS DURAS (não violar)7879Invariantes do método. Quebrar descaracteriza a engine.80811. **Disciplina ⊥ marca.** O preset impõe estrutura; a marca fornece valores. Nunca deixe um valor de marca virar regra de método, nem um default de disciplina sobrescrever um valor que a marca declarou.822. **Fallback de render é obrigatório.** Toda família de fonte recebe um fallback de métrica compatível instalado (`'Liberation Sans'` antes de Arial e do genérico) — senão o headless cai para Noto/Calibri e quebra a grotesca. Confirme com `fc-match` antes de publicar.833. **Keyword genérica de fonte vai por último** (`sans-serif`, `monospace`…); famílias com espaço são aspeadas.844. **Avisos de disciplina vão pra `stderr`**, nunca misturados no token output.855. **Gerador determinístico.** Zero rede, zero credencial. Presets embutidos no script.866. **Sob disciplina `identifier` (vignelli/swiss):** cor é identificador, uma por linha/sistema. O engine avisa se a paleta tem acentos demais — respeite o aviso ou troque de preset.877. **Sob `vignelli`:** dois tamanhos de tipo vivos por página (heading ≈ 2× body), flush-left, o tipo pendura na régua. Os demais degraus existem só para capas/specs.8889## ARMADILHA — Helvetica/house face em headless9091A house face de uma grotesca não existe na maioria dos ambientes headless. Ao rasterizar (cairosvg, Chromium headless) ou alimentar arte para um modelo de imagem, o render cai para Noto Sans (lê como Calibri) e quebra a grotesca. O engine já anexa `'Liberation Sans'` antes de Arial em toda família sans por isso. **Sempre confira um render** com `fc-match <fonte>` no ambiente antes de publicar.9293## FALLBACK_INLINE9495> Usar quando `scripts/` e `references/` não carregarem.9697### Tokens mínimos (CSS, disciplina blank, base 16px)9899```css100:root{101 --ds-color-primary:#2D2D2D; --ds-color-bg:#FFFFFF; --ds-color-fg:#111111;102 --ds-font-sans:'Inter','Liberation Sans',Arial,sans-serif;103 --ds-text-base:16px; --ds-text-lg:20px; --ds-text-3xl:39px; /* escala ~1.25 */104}105```106107Sob Vignelli: troque para dois tamanhos (`--v-text-body:16px; --v-text-heading:32px`), adicione réguas (`--v-rule-major:2pt; --v-rule-minor:.5pt`), paleta-identificador, flush-left.108109### QA mínimo110111- [ ] Disciplina e marca não se contaminaram (preset = estrutura; config = valores)112- [ ] Toda família sans tem `'Liberation Sans'` antes de Arial / do genérico113- [ ] Keyword genérica (`sans-serif`/`monospace`) está por último114- [ ] Formato pedido bate (Tailwind = `@theme` com `--color-*`/`--text-*`; W3C = `$value`/`$type`)115- [ ] Avisos de disciplina foram pra stderr, não pro arquivo de tokens116- [ ] Sob `vignelli`/`swiss`: paleta não diluiu a cor-identificador