Add a UI/UX design phase (/define-design, /update-design) and a platform app generation phase (/generate-app web|flutter|winui3) to the workflow, positioned between /setup-project and /add-feature. - commands: define-design, generate-app, update-design - add-feature: check docs/design/ before implementation; update design files first when a feature changes the UI - skills: ui-design, design-tokens, platform-ui-generation - docs/design/ structure documented (source of truth = ui-blueprint.json; SVGs are references only; generated UI follows design-tokens.json) - README and AGENTS.md updated with the new workflow
5.4 KiB
| name | description |
|---|---|
| design-tokens | Guide for creating and maintaining design-tokens.json, the single source of styling values for Web, Flutter, and WinUI 3. Use when creating or updating design tokens. |
Design Tokens Skill
This skill explains how to create and maintain docs/design/design-tokens.json — the single source of truth for all styling values (color, typography, spacing, radius, shadow, motion, breakpoints). Generated platform code must read from these tokens and must never hard-code values.
Core Principle
One token definition → many platform outputs. Never hard-code a color, size, or spacing in generated code.
Format
Use a JSON structure inspired by the Design Tokens Community Group format. Every token is an object with $type and $value:
{
"color": {
"background": {
"primary": { "$type": "color", "$value": "#0F172A" }
}
},
"spacing": {
"md": { "$type": "dimension", "$value": "16px" }
}
}
Supported $type values: color, dimension, fontFamily, fontWeight, duration, cubicBezier, number, strokeStyle.
Token Groups
design-tokens.json should include these groups (omit a group only if it truly does not apply):
- color — semantic color tokens
- typography — font families, sizes, weights, line heights
- spacing — spacing scale (xs, sm, md, lg, xl, …)
- radius — border radius scale
- shadow / elevation — box-shadow / elevation tokens
- motion — animation durations and easings
- breakpoint — responsive breakpoints (include when
webis a target)
Rules
Naming tokens
- Use semantic names, not descriptive names.
color.text.primary(good) vscolor.slate-900(bad). - Use a consistent scale for numeric families:
sm,md,lg,xl— or numeric4,8,12— pick one and stick to it. - Group by role then by emphasis:
color.background.primary,color.background.muted,color.text.primary,color.text.secondary,color.accent.primary,color.state.success,color.state.danger. - Token names are referenced verbatim in
ui-blueprint.json(e.g."padding": "lg"). They must match exactly.
Using semantic color names
- Define colors by role (background, text, accent, border, state, overlay) and emphasis (primary, secondary, muted).
- Do not expose raw hex scales as the only option. If you need a raw scale, keep it in a separate
color.palettegroup and reference it from semantic tokens. - Provide both light and dark values where the app supports them:
color.background.primary(light) andcolor.background.primary-dark, or adarksub-object — pick one convention and document it inplatform-mapping.md.
Avoiding hard-coded values in generated code
- Generated Web code uses CSS variables / Tailwind theme keys / theme objects derived from tokens.
- Generated Flutter code uses
ThemeData,ColorScheme, and constants derived from tokens. - Generated WinUI 3 code uses
ResourceDictionaryentries derived from tokens. - Never inline
#0F172Aor16pxin generated source. Always reference the token-derived variable/resource. - If a value is needed that has no token, add the token to
design-tokens.jsonfirst, then use it.
Mapping tokens to platform-specific code
design-tokens.json is platform-agnostic. The conversion to each platform is documented in docs/design/platform-mapping.md and performed by the platform-ui-generation skill. This skill only defines and maintains the tokens.
Example
{
"color": {
"background": {
"primary": { "$type": "color", "$value": "#0F172A" },
"muted": { "$type": "color", "$value": "#1E293B" }
},
"text": {
"primary": { "$type": "color", "$value": "#F8FAFC" },
"secondary": { "$type": "color", "$value": "#94A3B8" }
},
"accent": {
"primary": { "$type": "color", "$value": "#38BDF8" }
},
"state": {
"success": { "$type": "color", "$value": "#22C55E" },
"danger": { "$type": "color", "$value": "#EF4444" }
}
},
"typography": {
"fontFamily": {
"base": { "$type": "fontFamily", "$value": "Inter, system-ui, sans-serif" }
},
"size": {
"sm": { "$type": "dimension", "$value": "14px" },
"md": { "$type": "dimension", "$value": "16px" },
"lg": { "$type": "dimension", "$value": "20px" }
}
},
"spacing": {
"sm": { "$type": "dimension", "$value": "8px" },
"md": { "$type": "dimension", "$value": "16px" },
"lg": { "$type": "dimension", "$value": "24px" }
},
"radius": {
"card": { "$type": "dimension", "$value": "16px" },
"pill": { "$type": "dimension", "$value": "9999px" }
},
"shadow": {
"card": { "$type": "shadow", "$value": "0 4px 12px rgba(0,0,0,0.15)" }
},
"motion": {
"duration": {
"fast": { "$type": "duration", "$value": "120ms" },
"base": { "$type": "duration", "$value": "200ms" }
}
},
"breakpoint": {
"sm": { "$type": "dimension", "$value": "640px" },
"md": { "$type": "dimension", "$value": "768px" },
"lg": { "$type": "dimension", "$value": "1024px" }
}
}
Maintenance Checklist
When updating tokens:
- JSON is valid.
- Token names referenced in
ui-blueprint.jsonstill exist (no broken references after a rename). - New tokens follow the naming and semantic-name rules.
- No duplicate tokens (same role under two names).
platform-mapping.mdstill covers how every token group maps to each target platform.