skills/hungv47/agent-skills/design-system-generator

design-system-generator

SKILL.md

Design System Generator

Transform product artifacts into design systems that feel so natural users think "of course, how else would it be?"

Philosophy

Great design systems don't impose arbitrary aesthetics. They reveal what was always latent in the product's purpose. The goal is not to decorate but to crystallize the product's soul into visual and interaction patterns.

Before generating specifications, understand three things:

  1. Who feels what? The target audience's emotional state before, during, and after using the product
  2. What's the core tension? Every product resolves a tension. The design system should embody that resolution
  3. What must feel inevitable? The final system should feel like the only possible answer

Token Architecture

This skill uses a three-layer token system inspired by shadcn/ui and the W3C Design Tokens specification. Every visual decision flows through three levels of abstraction:

PRIMITIVE (what exists)     →  color.blue.500, spacing.4, font.size.md
SEMANTIC (what it means)    →  --primary, --muted-foreground, --border
COMPONENT (where it goes)   →  button.primary.background, input.border.default

The background/foreground convention: Every semantic role comes as a pair. The base name (e.g., --primary) is the background/fill. The -foreground suffix (e.g., --primary-foreground) is the text/icon color on that surface. Always pair them: bg-primary text-primary-foreground.

Color format: Use OKLCH (Oklch Lightness Chroma Hue) as the primary color space. OKLCH provides perceptually uniform steps — equal numeric changes produce visually equal brightness changes, which is critical for accessible color scales. Provide hex fallbacks for documentation readability.

See references/token-architecture.md for the complete token system specification.

Input Requirements

Gather from the user:

  • Product description or PRD
  • Target audience profile (demographics, psychographics, context of use)
  • User flow or key screens/wireframes
  • Brand constraints if any (existing logos, colors, fonts)
  • Competitive context (optional but helpful)

If missing critical inputs, ask. Don't hallucinate audience or product details.

Output Structure

Generate a design system document with these sections:

1. Emotional Foundation (Mandatory First Step)

Before any visual decisions, establish:

AUDIENCE EMOTIONAL MAPPING
--------------------------
Before product: [emotional state - frustration, confusion, desire, etc.]
During product: [transformation happening]
After product: [desired emotional outcome]

CORE TENSION: [what problem/desire the product resolves]
DESIGN PROMISE: [one sentence: what the design must communicate]

Example:

AUDIENCE: Busy professionals tracking personal goals
Before: Overwhelmed, scattered, guilty about unfulfilled intentions
During: Clarity emerging, small wins accumulating
After: Empowered, in control, proud of progress

CORE TENSION: Ambition vs. time scarcity
DESIGN PROMISE: Progress should feel effortless and inevitable

2. Primitive Tokens

Define the raw palette — all available values before any semantic meaning.

Neutral Base

Select a neutral base that matches the brand personality. Each base creates a distinct feel:

Base Undertone Feels Like
Neutral Pure gray Clean, stark, digital-native
Stone Warm gray Grounded, earthy, natural
Zinc Cool gray Industrial, precise, technical
Gray Blue-gray Corporate, reliable, familiar
Slate Blue-tinted Professional, established, calm
NEUTRAL BASE: [selected base]

Light mode scale:
  50:  [oklch value] / [hex]    -- Backgrounds, subtle fills
  100: [oklch value] / [hex]    -- Alternate backgrounds
  200: [oklch value] / [hex]    -- Borders, dividers
  300: [oklch value] / [hex]    -- Disabled text, placeholders
  400: [oklch value] / [hex]    -- Muted text
  500: [oklch value] / [hex]    -- Secondary text
  600: [oklch value] / [hex]    -- Body text (light bg)
  700: [oklch value] / [hex]    -- Headings
  800: [oklch value] / [hex]    -- High emphasis
  900: [oklch value] / [hex]    -- Maximum emphasis
  950: [oklch value] / [hex]    -- Near-black

Dark mode scale:
  [reversed scale with adjusted lightness/chroma]

Brand Colors

BRAND COLOR PRIMITIVES
----------------------
Primary scale (50-950):
  [full scale with oklch + hex, derived from the emotional foundation]

Secondary scale (50-950):
  [if needed — only when the brand demands a true second hue]

Accent scale (50-950):
  [for delight, celebration, highlights]

Destructive scale (50-950):
  [reds for error/danger states]

Typography Primitives

Select fonts that embody the emotional foundation. Reference references/typography-psychology.md.

FONT FAMILIES
-------------
Display: [Font name] - [why it fits the emotional promise]
Body:    [Font name] - [why it fits]
Mono:    [Font name] (if needed)

SIZE SCALE (base 16px):
  xs:   12px / 0.75rem
  sm:   14px / 0.875rem
  base: 16px / 1rem
  lg:   18px / 1.125rem
  xl:   20px / 1.25rem
  2xl:  24px / 1.5rem
  3xl:  30px / 1.875rem
  4xl:  36px / 2.25rem
  5xl:  48px / 3rem

WEIGHT SCALE:
  regular:  400 -- Body text
  medium:   500 -- Labels, emphasis
  semibold: 600 -- Headlines, buttons
  bold:     700 -- Hero text

LINE HEIGHT:
  tight:    1.25 -- Headlines, display
  normal:   1.5  -- Body text
  relaxed:  1.75 -- Long-form reading

LETTER SPACING:
  tight:   -0.025em -- Display, large text
  normal:  0        -- Body
  wide:    0.025em  -- Labels, caps, small text

Spacing & Radius Primitives

SPACING SCALE (base 4px):
  0:  0
  1:  4px / 0.25rem
  2:  8px / 0.5rem
  3:  12px / 0.75rem
  4:  16px / 1rem
  5:  20px / 1.25rem
  6:  24px / 1.5rem
  8:  32px / 2rem
  10: 40px / 2.5rem
  12: 48px / 3rem
  16: 64px / 4rem
  20: 80px / 5rem
  24: 96px / 6rem

RADIUS SCALE:
  none: 0
  sm:   0.25rem / 4px
  md:   0.375rem / 6px
  lg:   0.5rem / 8px
  xl:   0.75rem / 12px
  2xl:  1rem / 16px
  full: 9999px

3. Semantic Tokens

Map primitives to UI roles. This is the design system's API — the contract between design decisions and implementation. Every value references a primitive, never a raw value.

The Complete Semantic Token Map

SEMANTIC TOKENS (light / dark)
==============================

--- Core Surfaces ---
--background:            [page background]
--foreground:            [default text on page background]

--card:                  [card/elevated surface]
--card-foreground:       [text on card]

--popover:               [dropdown/tooltip/overlay surface]
--popover-foreground:    [text on popover]

--- Interactive ---
--primary:               [main brand action — buttons, links]
--primary-foreground:    [text/icon on primary]

--secondary:             [secondary actions, subtle buttons]
--secondary-foreground:  [text on secondary]

--accent:                [hover highlights, subtle emphasis]
--accent-foreground:     [text on accent]

--destructive:           [danger/error actions]
--destructive-foreground:[text on destructive]

--muted:                 [disabled backgrounds, subtle fills]
--muted-foreground:      [placeholder text, disabled text, captions]

--- Structural ---
--border:                [default border color]
--input:                 [input field border color]
--ring:                  [focus ring color]

--- Global Shape ---
--radius:                [global border radius — brand personality]

--- Data Visualization ---
--chart-1:               [primary chart color]
--chart-2:               [secondary chart color]
--chart-3:               [tertiary chart color]
--chart-4:               [quaternary chart color]
--chart-5:               [quinary chart color]

--- Sidebar (complex apps) ---
--sidebar:               [sidebar background]
--sidebar-foreground:    [sidebar text]
--sidebar-primary:       [sidebar active/selected item]
--sidebar-primary-foreground: [text on sidebar active item]
--sidebar-accent:        [sidebar hover state]
--sidebar-accent-foreground:  [text on sidebar hover]
--sidebar-border:        [sidebar border/divider]
--sidebar-ring:          [sidebar focus ring]

Radius as brand personality: The --radius token is a single value that defines the entire brand feel:

Radius Personality
0 Sharp, serious, enterprise
0.25rem Professional, restrained
0.375rem Balanced, modern default
0.5rem Friendly, approachable
0.75rem Soft, consumer-friendly
1rem+ Playful, app-like

Mapping Example

Show explicitly how primitives map to semantic tokens:

MAPPING: Primitives → Semantic
===============================
Given: primary = blue, neutral base = slate

Light Mode:
  --background:           slate.50     oklch(0.984 0.003 247)  / #f8fafc
  --foreground:           slate.950    oklch(0.129 0.042 264)  / #020617
  --primary:              blue.600     oklch(0.546 0.245 262)  / #2563eb
  --primary-foreground:   white        oklch(1 0 0)            / #ffffff
  --muted:                slate.100    oklch(0.968 0.007 247)  / #f1f5f9
  --muted-foreground:     slate.500    oklch(0.554 0.046 257)  / #64748b
  --border:               slate.200    oklch(0.929 0.013 255)  / #e2e8f0
  --input:                slate.200    oklch(0.929 0.013 255)  / #e2e8f0
  --ring:                 blue.600     oklch(0.546 0.245 262)  / #2563eb
  --radius:               0.625rem

Dark Mode:
  --background:           slate.950    oklch(0.129 0.042 264)  / #020617
  --foreground:           slate.50     oklch(0.984 0.003 247)  / #f8fafc
  --primary:              blue.500     oklch(0.623 0.214 259)  / #3b82f6
  --primary-foreground:   slate.950    oklch(0.129 0.042 264)  / #020617
  --muted:                slate.800    oklch(0.279 0.041 260)  / #1e293b
  --muted-foreground:     slate.400    oklch(0.704 0.04 256)   / #94a3b8
  --border:               slate.800    oklch(0.279 0.041 260)  / #1e293b
  --input:                slate.800    oklch(0.279 0.041 260)  / #1e293b
  --ring:                 blue.500     oklch(0.623 0.214 259)  / #3b82f6
  --radius:               0.625rem

4. Component Tokens

Map semantic tokens to specific components. This layer is optional for simple systems but valuable for complex or multi-brand products.

COMPONENT TOKENS
================
button.primary.background:     var(--primary)
button.primary.foreground:     var(--primary-foreground)
button.primary.hover:          [primary with adjusted lightness]
button.secondary.background:   var(--secondary)
button.secondary.foreground:   var(--secondary-foreground)
button.destructive.background: var(--destructive)
button.destructive.foreground: var(--destructive-foreground)
button.ghost.background:       transparent
button.ghost.foreground:       var(--foreground)
button.ghost.hover:            var(--accent)

input.background:              var(--background)
input.border:                  var(--input)
input.border.focus:            var(--ring)
input.placeholder:             var(--muted-foreground)

card.background:               var(--card)
card.foreground:               var(--card-foreground)
card.border:                   var(--border)

badge.default.background:      var(--primary)
badge.default.foreground:      var(--primary-foreground)
badge.secondary.background:    var(--secondary)
badge.secondary.foreground:    var(--secondary-foreground)
badge.destructive.background:  var(--destructive)
badge.destructive.foreground:  var(--destructive-foreground)
badge.outline.background:      transparent
badge.outline.border:          var(--border)

5. Component Patterns

Reference references/component-patterns.md for full patterns. Key specs here:

Buttons

BUTTON HIERARCHY
----------------
1. PRIMARY (one per view max)
   Tokens: bg-primary text-primary-foreground
   Hover: primary with +5% lightness
   Use: The ONE action you want users to take

2. SECONDARY
   Tokens: bg-secondary text-secondary-foreground
   Hover: secondary with +5% lightness
   Use: Alternative valid paths

3. DESTRUCTIVE
   Tokens: bg-destructive text-destructive-foreground
   Use: Delete, remove, cancel subscription

4. OUTLINE
   Tokens: border-input bg-background text-foreground
   Hover: bg-accent text-accent-foreground
   Use: Lower-priority actions

5. GHOST
   Tokens: bg-transparent text-foreground
   Hover: bg-accent text-accent-foreground
   Use: Toolbar actions, inline actions

6. LINK
   Tokens: text-primary underline
   Use: Inline text actions

BUTTON SIZES:
  sm:   h-8 px-3 text-xs     rounded-[calc(var(--radius)-2px)]
  md:   h-9 px-4 text-sm     rounded-[var(--radius)]
  lg:   h-10 px-6 text-sm    rounded-[var(--radius)]
  xl:   h-11 px-8 text-base  rounded-[var(--radius)]
  icon: h-9 w-9              rounded-[var(--radius)]

Form Elements

INPUT FIELDS
------------
Height: h-9 (36px) to h-10 (40px)
Padding: px-3 py-1
Border: 1px solid var(--input)
Focus: ring-2 ring-[var(--ring)] ring-offset-2
Radius: rounded-[var(--radius)]
Background: var(--background)
Text: var(--foreground)
Placeholder: var(--muted-foreground)

Label: text-sm font-medium text-foreground
Helper: text-xs text-muted-foreground
Error: text-xs text-destructive

VALIDATION:
- Inline on blur, not keystroke
- Error: border-destructive + error message below
- Success: subtle checkmark (optional)

Cards

CARD SPECIFICATION
------------------
Background: var(--card)
Border: 1px solid var(--border)
Radius: rounded-[var(--radius)]
Shadow: sm (light mode), none (dark mode)
Padding: p-6

Card Header: pb-2
Card Title: text-lg font-semibold text-card-foreground
Card Description: text-sm text-muted-foreground
Card Content: pt-0
Card Footer: pt-4 flex items-center

6. Motion & Interaction

MOTION PRINCIPLES
-----------------
Purpose: Guide attention, provide feedback, create delight
Never: Delay users, distract from content, add without purpose

TIMING TOKENS:
  instant: 0ms       -- State changes, toggles
  fast:    100-150ms  -- Micro-interactions, hovers, focus rings
  normal:  200-300ms  -- Transitions, reveals, collapses
  slow:    400-500ms  -- Page transitions, celebrations

EASING:
  ease-out:    entering elements (decelerate in)
  ease-in:     exiting elements (accelerate out)
  ease-in-out: moving elements, layout shifts
  spring:      playful interactions (if brand supports it)

INTERACTION FEEDBACK:
  Button press:  scale(0.98) + slight darken, fast timing
  Hover:         background token shift (e.g., accent), fast timing
  Focus:         ring-2 ring-[var(--ring)] ring-offset-2, instant
  Success:       brief pulse or checkmark, normal timing
  Error:         subtle shake (2px, 3 cycles), fast timing
  Loading:       skeleton shimmer or spinner, never frozen UI
  Accordion:     height transition, normal timing, ease-out

7. Accessibility Baseline

CONTRAST REQUIREMENTS (WCAG 2.1 AA):
  Normal text (<18px):     4.5:1 minimum
  Large text (18px+ bold): 3:1 minimum
  UI components:           3:1 minimum
  Focus indicators:        3:1 against adjacent colors

INTERACTIVE TARGETS:
  Minimum: 44x44px touch targets (WCAG 2.5.8)
  Spacing: 8px minimum between targets

FOCUS STATES:
  Visible focus ring on ALL interactive elements
  Style: ring-2 ring-[var(--ring)] ring-offset-2 ring-offset-[var(--background)]
  Never remove focus outline without replacement
  Keyboard navigation must work for all interactive patterns

COLOR INDEPENDENCE:
  Never use color alone to convey meaning
  Pair color with: icons, text labels, patterns, or position

MOTION SAFETY:
  Respect prefers-reduced-motion
  Provide reduced/no-animation fallbacks for all transitions

Process

  1. Extract the emotional foundation from product docs
  2. Select a neutral base that matches brand undertone
  3. Define primitive scales (colors in OKLCH, type, spacing, radius)
  4. Map primitives to semantic tokens using background/foreground pairs
  5. Select typography that embodies the brand voice
  6. Build color system around emotional moments
  7. Specify component tokens referencing semantic layer
  8. Add motion that feels natural, not decorative
  9. Verify every token pair meets WCAG contrast requirements
  10. Document dark mode values for every semantic token

Dark Mode Rules

Dark mode is not an afterthought — it's a parallel track built into the token system from step 1.

  • Every semantic token MUST have both light and dark values
  • Dark mode reduces saturation and shifts lightness, never inverts
  • Surface hierarchy uses multiple levels (background → card → popover), not just "black"
  • Primary colors shift lighter in dark mode for visibility
  • Foreground colors flip (dark text → light text) maintaining contrast ratios
  • Semantic colors (success, error, warning) preserve hue but adjust lightness
  • Borders become more subtle (lower contrast against dark surfaces)
  • Shadows are usually removed or replaced with subtle border differentiation

References

  • references/token-architecture.md - Three-layer token system, complete semantic token map, neutral presets
  • references/typography-psychology.md - Font personality mappings and pairing rules
  • references/color-emotion.md - Color psychology, OKLCH values, audience palettes
  • references/component-patterns.md - Common UI patterns with token consumption maps

Anti-Patterns

  • Token soup: Too many options create decision paralysis. ~20 semantic tokens cover an entire component library. Constrain choices.
  • Aesthetic without purpose: Every decision should trace back to user emotion and the design promise
  • Skipping the semantic layer: Never reference primitives directly in components. Always go through semantic tokens.
  • Mismatched pairs: Using bg-primary text-primary instead of bg-primary text-primary-foreground. The foreground must always be the readable counterpart.
  • Hex-only thinking: Use OKLCH for perceptually uniform color manipulation. Hex is for documentation readability.
  • Dark mode as inversion: Flipping black/white is not dark mode. It requires deliberate surface hierarchy and adjusted chroma.
  • Ignoring context: A fitness app and a banking app need different energy even if targeting similar demographics
  • Trend-chasing: Glassmorphism and gradients aren't personality. What's the actual emotional intent?
  • Radius inconsistency: Use one global --radius value. All components derive from it, creating visual coherence.
Weekly Installs
4
GitHub Stars
2
First Seen
Feb 28, 2026
Installed on
mcpjam4
gemini-cli4
claude-code4
junie4
windsurf4
zencoder4