Spec Reference

Every required field, every recommended section, every YAML rule.

What’s in a DESIGN.md

A DESIGN.md is a standard Markdown file. The top of the file is YAML frontmatter (between --- delimiters). Below the closing --- is a prose Markdown body.

---
# YAML frontmatter: machine-readable token bundle
name: Stripe
spec: webdesignhot/0.1
colors:
  bg: '#ffffff'
  ...
---

# Stripe

Prose body: 15 canonical sections covering visual theme,
color roles, typography usage, component patterns, motion,
voice, lineage, and agent prompt guide.

The frontmatter is what the CLI, MCP, and export commands read. The prose body is what coding agents read during generation — it provides the semantic context that token values alone don’t convey.

Linear — webdesignhot/0.1 spec, dark theme

Every token documented in this reference produces output like the above. The frame is rendered from Linear's DESIGN.md frontmatter — no hand-tweaked CSS.

Required frontmatter fields

| Field | Type | Example | |---|---|---| | name | string | Stripe | | tagline | string | Infrastructure for the internet economy | | spec | string | webdesignhot/0.1 | | colors | object | see colors block | | typography | object | see typography block |

Every valid DESIGN.md must have all five. design-md lint reports an error if any are missing.

These fields are not required but are present in most catalog entries and improve agent output quality.

| Field | Type | Purpose | |---|---|---| | categories | string[] | Taxonomy — ['saas', 'fintech'] | | tags | string[] | Freeform labels — ['dark-mode', 'minimal'] | | source_url | string | Production URL the tokens were extracted from | | lineage | object | Brand influences; see lineage block | | aliases | object | Tailwind/shadcn role mapping; see aliases block | | radii | object | Corner-radius scale | | spacing | object | Spacing scale | | shadow | object | Box-shadow definitions | | motion | object | Easing and duration tokens | | breakpoints | object | Viewport breakpoints in px | | components | object | Per-component token overrides | | dark | object | Dark-mode palette (single-theme entries) | | themes | object | Multi-theme config (multi-theme entries) |

colors block

The colors object maps semantic role names to hex values. Single-theme entries have a flat map:

colors:
  bg: '#ffffff'
  surface: '#f6f9fc'
  border: '#e6ebf1'
  text: '#0a2540'
  text-dim: '#425466'
  text-faint: '#8898aa'
  brand: '#635bff'
  brand-alt: '#0055de'
  on-brand: '#ffffff'
  success: '#09825d'
  warning: '#b5830a'
  danger: '#cd3d64'

Core roles every entry should define:

| Role | Meaning | |---|---| | bg | Page/canvas background | | surface | Card, panel, elevated surface | | border | Default border color | | text | Primary body text | | text-dim | Secondary/muted text | | brand | Primary interactive color (buttons, links, focus rings) | | on-brand | Text/icon color on a brand-colored surface |

Semantic state roles (optional but recommended):

| Role | Use | |---|---| | success | Positive confirmation states | | warning | Caution, degraded states | | danger | Destructive actions, error states |

Multi-theme entries nest palettes by theme name — see the themes block.

typography block

The typography object has named style slots. Each slot accepts family, size, weight, lineHeight, and letterSpacing:

typography:
  display:
    family: '"Sohne Kraftig", -apple-system, sans-serif'
    weight: '500'
    letterSpacing: '-0.025em'
  body:
    family: '"Sohne Buch", -apple-system, sans-serif'
    size: '16px'
    weight: '400'
    lineHeight: '1.6'
  mono:
    family: '"Sohne Mono", "Fira Code", monospace'
    size: '13px'
    lineHeight: '1.5'
  scale:
    xs: '12px'
    sm: '14px'
    base: '16px'
    lg: '18px'
    xl: '20px'
    '2xl': '24px'
    '3xl': '30px'
    '4xl': '36px'

The three named slots (display, body, mono) are expected. scale is a flat size map — agents use it when generating typography utilities.

radius block

Corner-radius scale. Values are CSS length strings:

radii:
  none: '0px'
  sm: '4px'
  md: '8px'
  lg: '12px'
  xl: '16px'
  full: '9999px'

Most entries define sm, md, lg. full is used for pill buttons and avatar circles.

spacing block

Base spacing scale. Values are numbers (pixels) or CSS strings:

spacing:
  '1': '4px'
  '2': '8px'
  '3': '12px'
  '4': '16px'
  '5': '20px'
  '6': '24px'
  '8': '32px'
  '10': '40px'
  '12': '48px'
  '16': '64px'

Keys follow Tailwind’s numeric convention so agents can map them to utility classes directly.

shadow block

Box-shadow definitions by elevation level:

shadow:
  sm: '0 1px 2px rgba(0,0,0,0.06)'
  md: '0 4px 16px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.04)'
  lg: '0 16px 48px rgba(0,0,0,0.12), 0 4px 12px rgba(0,0,0,0.06)'
  focus: '0 0 0 3px rgba(99,91,255,0.25)'

focus is a special role — it defines the keyboard focus ring color. Agents use it for :focus-visible styles.

motion block

Easing curves and duration tokens in milliseconds:

motion:
  ease: 'cubic-bezier(0.4, 0, 0.2, 1)'
  ease-in: 'cubic-bezier(0.4, 0, 1, 1)'
  ease-out: 'cubic-bezier(0, 0, 0.2, 1)'
  duration-fast: 150
  duration-standard: 240
  duration-slow: 320
  reduced-motion: 'respects prefers-reduced-motion: reduce'

ease is the general-purpose curve for hover/focus. duration-fast covers micro-interactions; duration-standard covers panel opens; duration-slow covers dialog entrances.

breakpoints block

Viewport widths in pixels:

breakpoints:
  sm: 640
  md: 768
  lg: 1024
  xl: 1280
  2xl: 1440

Keys match Tailwind’s default names. Agents use these when writing @media queries or Tailwind responsive prefixes.

components block

Per-component token overrides. Each key is a canonical component slot name:

components:
  button-primary:
    bg: '#635bff'
    text: '#ffffff'
    radius: '6px'
    font-weight: '500'
    padding: '10px 18px'
  button-secondary:
    bg: 'transparent'
    border: '#e6ebf1'
    text: '#0a2540'
    radius: '6px'
  card:
    bg: '#ffffff'
    border: '#e6ebf1'
    radius: '8px'
    shadow: '0 4px 16px rgba(0,0,0,0.08)'
    padding: '24px'
  input:
    bg: '#ffffff'
    border: '#e6ebf1'
    border-focus: '#635bff'
    radius: '6px'
    padding: '10px 14px'
    font-size: '15px'
  badge:
    radius: '4px'
    font-size: '12px'
    font-weight: '500'
    padding: '2px 8px'

Canonical component slots: button-primary, button-secondary, button-ghost, card, input, select, checkbox, badge, tag, tooltip, dialog, nav, nav-item, sidebar, table, table-row.

Slots are not exhaustive — add any component your design system defines. The naming convention is kebab-case.

lineage block

Documents brand influences and design heritage. Agents use this when generating prose commentary:

lineage:
  summary: >
    Clean Swiss-modernist roots filtered through SF tech minimalism. 
    Heavy Dieter Rams influence — purpose-first, no decoration that doesn't 
    serve the function.
  influences:
    - name: Swiss International Style
      role: Grid discipline, typographic hierarchy, white space
      url: https://en.wikipedia.org/wiki/International_typographic_style
    - name: Dieter Rams
      role: Ten principles of good design; form follows function
      url: https://en.wikipedia.org/wiki/Dieter_Rams
    - name: Linear
      role: Inspiration for tight spacing and monochromatic neutrals
      url: https://linear.app

influences entries are objects with name, role, and url. The url must be a valid absolute URL — design-md lint validates this. Internal references like url: "see source_url" will fail validation.

aliases block

Maps shadcn/ui and Tailwind semantic role names to this design’s token names:

aliases:
  # shadcn/ui → design.md role
  background: bg
  foreground: text
  primary: brand
  primary-foreground: on-brand
  secondary: surface
  secondary-foreground: text-dim
  muted: surface
  muted-foreground: text-faint
  border: border
  input: border
  ring: brand
  destructive: danger
  destructive-foreground: on-brand

This lets design-md export --to shadcn produce a globals.css that maps shadcn’s CSS variables to the brand’s actual tokens. Keys on the left are shadcn/Tailwind names; values on the right are keys in the colors block.

themes block

Multi-theme entries nest palettes under colors by theme name, and declare a themes config block:

themes:
  default: light
  available: [light, dark, high-contrast]
  switch-via: 'data-theme attribute on <html>; persisted in localStorage'
colors:
  light:
    bg: '#ffffff'
    text: '#0f172a'
    brand: '#7c3aed'
    surface: '#f8fafc'
    border: '#e2e8f0'
    on-brand: '#ffffff'
  dark:
    bg: '#0f0f0f'
    text: '#f8fafc'
    brand: '#a78bfa'
    surface: '#1a1a1a'
    border: '#2a2a2a'
    on-brand: '#0f0f0f'
  high-contrast:
    bg: '#000000'
    text: '#ffffff'
    brand: '#facc15'
    surface: '#111111'
    border: '#444444'
    on-brand: '#000000'

Single-theme entries with a dark mode use a flat colors block plus a separate dark block (not nested):

colors:
  bg: '#fafafa'
  text: '#0a0a0a'
  brand: '#16a34a'
  on-brand: '#ffffff'
dark:
  bg: '#0a0a0a'
  surface: '#141416'
  text: '#ededed'
  brand: '#22c55e'
  on-brand: '#0a0a0a'

The 15-section Markdown body

Below the closing ---, every catalog entry has a prose body with these 15 canonical sections in order:

| # | Section heading | Contents | |---|---|---| | 1 | Visual Theme & Atmosphere | Overall mood, aesthetic category, what first impression the design creates | | 2 | Color Palette & Usage | Role-by-role breakdown of colors with usage rules and frequency guidance | | 3 | Typography System | Font choices, size scale, weight hierarchy, when to use display vs body vs mono | | 4 | Component Styling Patterns | How buttons, cards, inputs, badges look and behave — what distinguishes them | | 5 | Layout & Spacing | Grid approach, container widths, density, whitespace philosophy | | 6 | Iconography | Icon style (outline/filled/duotone), stroke weight, sizing conventions | | 7 | Motion & Animation | Speed, easing, what gets animated vs what stays static | | 8 | Imagery & Media | Photography style, illustration treatment, video usage | | 9 | Accessibility | Contrast ratios, keyboard nav patterns, reduced-motion support, ARIA habits | | 10 | Voice & Tone | Writing style, length, vocabulary, what to avoid | | 11 | Dark Mode | How the dark variant changes mood, which tokens shift, what stays the same | | 12 | Lineage & Influences | Where the design came from, what it borrows from, what it rejects | | 13 | Do’s & Don’ts | Concrete dos and don’ts — specifics, not generic advice | | 14 | Agent Prompt Guide | How an AI agent should apply this design system — what to prioritize, what traps to avoid | | 15 | Quick Reference | Compact token cheat-sheet for scanning at a glance |

Sections don’t need to be long — three to five paragraphs each is normal. The value is specificity: “use brand only on interactive elements” is useful; “use color intentionally” is not.

Schema validation

design-md lint validates a DESIGN.md against the webdesignhot/0.1 schema:

design-md lint stripe.design.md

What it checks:

  • Required fields present (name, tagline, spec, colors, typography)
  • spec value is a recognized version string
  • colors has at minimum bg, text, brand, on-brand
  • lineage.influences[].url values are valid absolute URLs
  • typography has at minimum one named slot (body or display)
  • No unknown top-level keys that could indicate a typo (warns, not errors)
  • YAML parses without errors

Exit code 0 = valid. Exit code 1 = one or more errors. Errors print to stderr; clean output prints to stdout (useful for CI piping).

# CI usage
design-md lint DESIGN.md && echo "valid" || exit 1