What Is design.md
design.md is a machine-readable YAML-frontmatter file that encodes a complete design system.
Any site can expose one at /design.md (light) and /design.dark.md (dark). The gallery at
designsmd.vercel.app curates 156+ ready-made ones across aesthetic categories.
Step 1 — Identify the Design Source
A — User provides a design.md URL
Fetch it directly. Go to Step 2.
B — User wants Vercel / Geist
Fetch both in parallel:
- Light:
https://vercel.com/design.md - Dark:
https://vercel.com/design.dark.md
Ask which theme to apply if not specified. If both fetches fail, load
references/geist.md as fallback. Go to Step 2.
C — User wants to browse the gallery (or has no design in mind)
Do this proactively — do not just tell the user to go browse themselves.
- Fetch
https://designsmd.vercel.app/and read the full category + entry list - Ask the user: "What kind of aesthetic or vibe are you going for?" Give examples from actual gallery categories: Dark, Minimal, Bold, Brutalist, Organic, Healthcare, Finance, Gaming, Music, Editorial, Fashion, etc.
- Based on their answer, pick 3-5 matching systems and show:
- Name + one-line description (e.g. "3D viewport: studio grey, mesh cyan, normal magenta")
- Category
- Once the user picks one, fetch its page:
https://designsmd.vercel.app/design/{category}--{slug}The full design.md YAML + markdown is embedded in the page. Parse it. Go to Step 2.
URL slug format: category and name lowercased, spaces to hyphens. Examples:
https://designsmd.vercel.app/design/dark--3d-sculpthttps://designsmd.vercel.app/design/minimal--ai-labshttps://designsmd.vercel.app/design/bold--arcade-neon-pop
Always fetch the gallery fresh — the count may have grown beyond 156.
D — User describes a style (no URL, no gallery pick)
- Synthesize a design.md-compatible spec from their description or reference images
- Use the gallery YAML frontmatter format (see Step 2 below)
- Show the spec to the user for confirmation before building
E — User provides a Figma file URL
Use the Figma MCP to extract tokens directly:
- Call
get_variable_defswith the file key and a node ID from the URL to get all Variables (colors, spacing, radius, etc.) - Call
search_design_systemwith queries like "color", "spacing", "typography" to get styles and component specs from the file's linked libraries - If the file has no variables, call
get_design_contexton a representative node to extract visual specs from the design itself - Map the extracted values into design.md YAML format (see Step 2)
- Show the synthesized spec to the user for confirmation. Go to Step 2.
Step 2 — Parse the Tokens
Gallery format (designsmd.vercel.app — YAML frontmatter)
---
name: System Name
description: Short aesthetic description
colors:
primary: "#0F1112" # primary text / foreground
secondary: "#6F7478" # secondary text
tertiary: "#00A36C" # accent / CTA
neutral: "#FAFAF8" # page background
surface: "#FFFFFF" # card / panel background
on-primary: "#FFFFFF" # text on primary-colored surfaces
typography:
display:
fontFamily: IBM Plex Sans
fontSize: 3.5rem
fontWeight: 500
letterSpacing: "-0.02em"
h1:
fontFamily: IBM Plex Sans
fontSize: 2rem
fontWeight: 500
body:
fontFamily: IBM Plex Sans
fontSize: 0.95rem
lineHeight: 1.6
label:
fontFamily: IBM Plex Mono
fontSize: 0.72rem
rounded:
sm: 3px
md: 5px
lg: 8px
spacing:
sm: 8px
md: 16px
lg: 32px
components:
button-primary:
backgroundColor: "{colors.tertiary}" # {token.ref} resolves to actual value
textColor: "{colors.on-primary}"
rounded: "{rounded.md}"
padding: 12px 20px
card:
backgroundColor: "{colors.surface}"
textColor: "{colors.primary}"
rounded: "{rounded.lg}"
padding: 24px
---
Resolve all {token.ref} references before applying.
Geist / vercel.com format (flat markdown token list)
Extract: color names + hex values, typography scale (size/weight/letter-spacing),
spacing scale, border-radius sizes, shadow definitions, motion easing + durations.
See references/geist.md for the full token structure.
Step 3 — Apply Tokens as Source of Truth
Every color, size, and spacing value in the UI must trace back to the token sheet.
Colors
colors.primary/gray-1000→ primary text, headingscolors.secondary/gray-900→ secondary text, captionscolors.tertiary→ accent, CTA buttons, linkscolors.neutral/background-100→ page backgroundcolors.surface/background-200→ card / panel surfaces- Semantic: error = red accent, success = green, warning = amber, info = blue
Typography
display/heading-*→ hero and page headingsh1-h3/heading-*→ section headingsbody/copy-*→ paragraph textlabel/label-*→ UI labels, metadata, captions- Load specified font families from Google Fonts / CDN if not system fonts
Spacing and Layout
- Use
spacing.sm/md/lgor scale steps only — no invented intermediate values - Within a component: smallest steps; between sections: largest
Components
- Apply component specs directly after resolving
{token.ref}values - For Geist: component heights are sm=32px, md=40px, lg=48px
Interactive States
- Hover: one step lighter/darker on the gray or accent scale
- Focus ring:
0 0 0 2px <background>, 0 0 0 4px <tertiary>— always visible - Disabled: secondary color at reduced opacity
Step 4 — Implement
Declare tokens as CSS custom properties at :root:
:root {
--color-bg: #fafaf8;
--color-text: #0f1112;
--color-accent: #00a36c;
--color-surface: #ffffff;
--font-sans: 'IBM Plex Sans', sans-serif;
--font-mono: 'IBM Plex Mono', monospace;
--radius-sm: 3px;
--radius-md: 5px;
--radius-lg: 8px;
--space-sm: 8px;
--space-md: 16px;
--space-lg: 32px;
}
Token audit before finishing:
- No magic hex values outside the token sheet
- Typography uses spec sizes and families, not browser defaults
- Spacing follows the scale
- Hover / focus / disabled states handled
- WCAG AA contrast: 4.5:1 body text, 3:1 large text / UI components