design.md Specification

v1.0

The design.md format was originated by Google Labs as a structured way to communicate design intent to AI coding agents. Stylebase extends the base format with versioning, AI enforcement rules, component specifications, and a JSON Schema for machine validation.

This page is the complete reference for building valid design.md files.

File Structure

A design.md file has two parts:

Part 1: YAML Front Matter

Machine-readable tokens between --- delimiters. Colors, typography, spacing, components, and AI rules.

Part 2: Markdown Body

Human-readable design philosophy, usage guidelines, and anti-patterns. Read by AI for context and judgment.

---
version: "1.0"
name: "My Design System"
colors:
  primary: "#171717"
  ...
typography:
  ...
---

# My Design System

## Design Philosophy
...

YAML Front Matter Reference

version string required

Spec version identifier. Format: MAJOR.MINOR

version: "1.0"
name string (1-100 chars) required

Human-readable name for the design system.

name: "Clean SaaS"
description string (5-500 chars) required

One-line description of design intent and use case.

description: "Minimal dashboard system with Geist typography"
colors object required

Color tokens as hex values. All values must match ^#([0-9a-fA-F]6|[0-9a-fA-F]8)$

Required fields (16):

primaryprimary-foregroundsecondarysecondary-foreground accentaccent-foregroundbackgroundsurface bordertext-primarytext-secondarytext-muted successwarningerrorinfo

Optional: surface-raised, border-strong, and custom additional colors.

typography object required

Font definitions and type scale.

Required: headline, body, scale

Optional: mono

Font definition fields:

  • family — string, font family name
  • weight — integer, 100–900
  • use — string (min 5 chars), describes when to use

Scale entry fields:

  • label — string identifier (xs, sm, base, lg, etc.)
  • size — CSS length (e.g., "16px")
  • lineHeight — CSS length (e.g., "24px")
spacing object required

Spacing scale definition.

  • base — integer (1–16), the base unit
  • scale — array of integers, the spacing values
  • unit — "px", "rem", or "em"
rounded object required

Border-radius tokens. All values are CSS lengths.

Required keys: none, sm, md, lg, full

components object required

Component design specifications. Required: button, input, card.

button.variants[]:

  • name, background, text, radius, weight (all required)
  • border (optional)

button.sizes[]:

  • name, height, padding, fontSize

input:

  • background, border, radius, height, focusRing, placeholder

card:

  • background, border, radius, padding (required)
  • shadow, hoverBorder, hoverShadow (optional)
x-stylebase object optional

Stylebase-specific extensions for versioning and AI enforcement.

  • version — semver (e.g., "1.0.0")
  • template — template slug identifier
  • generated-by — tool that generated the file
  • ai-rules.always — array of mandatory behaviors
  • ai-rules.never — array of hard constraints

Markdown Body

The body after the closing --- provides context that AI agents use for design judgment. Recommended sections:

## Design Philosophy
## Color Usage
## Typography Rules
## Spacing Philosophy
## Component Principles
## What This System Is Not

Validation Rules

Required (errors)

  • * YAML front matter must be present (between --- delimiters)
  • * version, name, description fields must exist and be non-empty strings
  • * colors must include all 16 required tokens
  • * All color values must be valid hex (#RRGGBB or #RRGGBBAA)
  • * typography must include headline, body, and scale
  • * headline and body must have family (string), weight (100-900), use (min 5 chars)
  • * scale must have at least 4 entries, each with label, size, lineHeight
  • * spacing must include base (integer 1-16), scale (array), unit (px/rem/em)
  • * rounded must include none, sm, md, lg, full
  • * components must include button, input, card with all required sub-fields

Warnings

  • ! text-primary on background contrast ratio below 4.5:1 (WCAG AA)
  • ! text-secondary on background contrast ratio below 3:1 (WCAG AA large text)
  • ! No Markdown body present after YAML front matter
  • ! No x-stylebase extension block (recommended for AI enforcement)
  • ! Fewer than 8 type scale entries (recommended minimum)

JSON Schema

The canonical schema is available at /schema/v1.json. Use it with any JSON Schema validator (Ajv, jsonschema, etc.) to validate design.md YAML front matter.

v1.json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://stylebase.dev/schema/v1.json",
  "title": "design.md YAML Front Matter",
  "description": "JSON Schema for validating the YAML front matter of design.md files following the Stylebase specification v1.0",
  "type": "object",
  "required": ["version", "name", "description", "colors", "typography", "spacing", "rounded", "components"],
  "properties": {
    "version": {
      "type": "string",
      "description": "Spec version",
      "pattern": "^[0-9]+\\.[0-9]+$"
    },
    "name": {
      "type": "string",
      "description": "Human-readable template name",
      "minLength": 1,
      "maxLength": 100
    },
    "description": {
      "type": "string",
      "description": "One-line description of the design system",
      "minLength": 5,
      "maxLength": 500
    },
    "colors": {
      "type": "object",
      "description": "Color tokens as hex values",
      "required": [
        "primary",
        "primary-foreground",
        "secondary",
        "secondary-foreground",
        "accent",
        "accent-foreground",
        "background",
        "surface",
        "border",
        "text-primary",
        "text-secondary",
        "text-muted",
        "success",
        "warning",
        "error",
        "info"
      ],
      "properties": {
        "primary": { "$ref": "#/$defs/hexColor" },
        "primary-foreground": { "$ref": "#/$defs/hexColor" },
        "secondary": { "$ref": "#/$defs/hexColor" },
        "secondary-foreground": { "$ref": "#/$defs/hexColor" },
        "accent": { "$ref": "#/$defs/hexColor" },
        "accent-foreground": { "$ref": "#/$defs/hexColor" },
        "background": { "$ref": "#/$defs/hexColor" },
        "surface": { "$ref": "#/$defs/hexColor" },
        "surface-raised": { "$ref": "#/$defs/hexColor" },
        "border": { "$ref": "#/$defs/hexColor" },
        "border-strong": { "$ref": "#/$defs/hexColor" },
        "text-primary": { "$ref": "#/$defs/hexColor" },
        "text-secondary": { "$ref": "#/$defs/hexColor" },
        "text-muted": { "$ref": "#/$defs/hexColor" },
        "success": { "$ref": "#/$defs/hexColor" },
        "warning": { "$ref": "#/$defs/hexColor" },
        "error": { "$ref": "#/$defs/hexColor" },
        "info": { "$ref": "#/$defs/hexColor" }
      },
      "additionalProperties": { "$ref": "#/$defs/hexColor" }
    },
    "typography": {
      "type": "object",
      "description": "Typography definitions",
      "required": ["headline", "body", "scale"],
      "properties": {
        "headline": { "$ref": "#/$defs/fontDef" },
        "body": { "$ref": "#/$defs/fontDef" },
        "mono": { "$ref": "#/$defs/fontDef" },
        "scale": {
          "type": "array",
          "description": "Type scale from smallest to largest",
          "minItems": 4,
          "maxItems": 16,
          "items": {
            "type": "object",
            "required": ["label", "size", "lineHeight"],
            "properties": {
              "label": { "type": "string", "minLength": 1 },
              "size": { "$ref": "#/$defs/cssLength" },
              "lineHeight": { "$ref": "#/$defs/cssLength" }
            },
            "additionalProperties": false
          }
        }
      },
      "additionalProperties": false
    },
    "spacing": {
      "type": "object",
      "description": "Spacing scale definition",
      "required": ["base", "scale", "unit"],
      "properties": {
        "base": {
          "type": "integer",
          "minimum": 1,
          "maximum": 16,
          "description": "Base spacing unit in the defined unit"
        },
        "scale": {
          "type": "array",
          "items": { "type": "integer", "minimum": 0 },
          "minItems": 4,
          "description": "Array of spacing values in the defined unit"
        },
        "unit": {
          "type": "string",
          "enum": ["px", "rem", "em"],
          "description": "CSS unit for spacing values"
        }
      },
      "additionalProperties": false
    },
    "rounded": {
      "type": "object",
      "description": "Border-radius tokens",
      "required": ["none", "sm", "md", "lg", "full"],
      "properties": {
        "none": { "$ref": "#/$defs/cssLength" },
        "sm": { "$ref": "#/$defs/cssLength" },
        "md": { "$ref": "#/$defs/cssLength" },
        "lg": { "$ref": "#/$defs/cssLength" },
        "full": { "$ref": "#/$defs/cssLength" }
      },
      "additionalProperties": { "$ref": "#/$defs/cssLength" }
    },
    "components": {
      "type": "object",
      "description": "Component design specifications",
      "required": ["button", "input", "card"],
      "properties": {
        "button": {
          "type": "object",
          "required": ["variants", "sizes"],
          "properties": {
            "variants": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "required": ["name", "background", "text", "radius", "weight"],
                "properties": {
                  "name": { "type": "string", "minLength": 1 },
                  "background": { "type": "string" },
                  "text": { "$ref": "#/$defs/hexColor" },
                  "border": { "$ref": "#/$defs/hexColor" },
                  "radius": { "type": "string" },
                  "weight": { "type": "integer", "minimum": 100, "maximum": 900 }
                },
                "additionalProperties": false
              }
            },
            "sizes": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "required": ["name", "height", "padding", "fontSize"],
                "properties": {
                  "name": { "type": "string", "minLength": 1 },
                  "height": { "$ref": "#/$defs/cssLength" },
                  "padding": { "type": "string" },
                  "fontSize": { "$ref": "#/$defs/cssLength" }
                },
                "additionalProperties": false
              }
            }
          },
          "additionalProperties": false
        },
        "input": {
          "type": "object",
          "required": ["background", "border", "radius", "height", "focusRing", "placeholder"],
          "properties": {
            "background": { "$ref": "#/$defs/hexColor" },
            "border": { "$ref": "#/$defs/hexColor" },
            "radius": { "type": "string" },
            "height": { "$ref": "#/$defs/cssLength" },
            "focusRing": { "$ref": "#/$defs/hexColor" },
            "placeholder": { "$ref": "#/$defs/hexColor" }
          },
          "additionalProperties": false
        },
        "card": {
          "type": "object",
          "required": ["background", "border", "radius", "padding"],
          "properties": {
            "background": { "$ref": "#/$defs/hexColor" },
            "border": { "$ref": "#/$defs/hexColor" },
            "radius": { "type": "string" },
            "padding": { "type": "string" },
            "shadow": { "type": "string" },
            "hoverBorder": { "$ref": "#/$defs/hexColor" },
            "hoverShadow": { "type": "string" }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": true
    },
    "x-stylebase": {
      "type": "object",
      "description": "Stylebase-specific extensions",
      "properties": {
        "version": {
          "type": "string",
          "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
          "description": "Semantic version of the template"
        },
        "template": {
          "type": "string",
          "description": "Template slug identifier"
        },
        "generated-by": {
          "type": "string",
          "description": "Tool that generated this file"
        },
        "ai-rules": {
          "type": "object",
          "properties": {
            "always": {
              "type": "array",
              "items": { "type": "string", "minLength": 5 },
              "description": "Rules the AI must always follow"
            },
            "never": {
              "type": "array",
              "items": { "type": "string", "minLength": 5 },
              "description": "Rules the AI must never break"
            }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": true
    }
  },
  "additionalProperties": true,
  "$defs": {
    "hexColor": {
      "type": "string",
      "pattern": "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
      "description": "Hex color value (6 or 8 digit)"
    },
    "fontDef": {
      "type": "object",
      "required": ["family", "weight", "use"],
      "properties": {
        "family": { "type": "string", "minLength": 1 },
        "weight": { "type": "integer", "minimum": 100, "maximum": 900 },
        "use": { "type": "string", "minLength": 5, "description": "Description of when to use this font" }
      },
      "additionalProperties": false
    },
    "cssLength": {
      "type": "string",
      "pattern": "^[0-9]+(\\.[0-9]+)?(px|rem|em|%|vw|vh)$",
      "description": "CSS length value"
    }
  }
}

Complete Examples

---
version: "1.0"
name: "Clean SaaS"
description: "Minimal, whitespace-first design system for dashboard and SaaS applications. Geist typography, neutral palette, no gradients or decorative shadows."

colors:
  primary: "#171717"
  primary-foreground: "#fafafa"
  secondary: "#f5f5f5"
  secondary-foreground: "#171717"
  accent: "#2563eb"
  accent-foreground: "#ffffff"
  background: "#ffffff"
  surface: "#fafafa"
  surface-raised: "#ffffff"
  border: "#e5e5e5"
  border-strong: "#d4d4d4"
  text-primary: "#171717"
  text-secondary: "#525252"
  text-muted: "#a3a3a3"
  success: "#16a34a"
  warning: "#d97706"
  error: "#dc2626"
  info: "#2563eb"

typography:
  headline:
    family: "Geist"
    weight: 600
    use: "Page titles, section headers, modal headings"
  body:
    family: "Geist"
    weight: 400
    use: "Paragraph text, descriptions, form labels, table cells"
  mono:
    family: "Geist Mono"
    weight: 400
    use: "Code snippets, API keys, terminal output, data values"
  scale:
    - { label: "xs", size: "12px", lineHeight: "16px" }
    - { label: "sm", size: "14px", lineHeight: "20px" }
    - { label: "base", size: "16px", lineHeight: "24px" }
    - { label: "lg", size: "18px", lineHeight: "28px" }
    - { label: "xl", size: "20px", lineHeight: "28px" }
    - { label: "2xl", size: "24px", lineHeight: "32px" }
    - { label: "3xl", size: "30px", lineHeight: "36px" }
    - { label: "4xl", size: "36px", lineHeight: "40px" }

spacing:
  base: 4
  scale: [0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80, 96]
  unit: "px"

rounded:
  none: "0px"
  sm: "4px"
  md: "8px"
  lg: "12px"
  full: "9999px"

components:
  button:
    variants:
      - name: "primary"
        background: "#171717"
        text: "#fafafa"
        radius: "md"
        weight: 500
      - name: "secondary"
        background: "#f5f5f5"
        text: "#171717"
        radius: "md"
        weight: 500
      - name: "outline"
        background: "transparent"
        text: "#171717"
        border: "#e5e5e5"
        radius: "md"
        weight: 500
      - name: "ghost"
        background: "transparent"
        text: "#525252"
        radius: "md"
        weight: 500
      - name: "destructive"
        background: "#dc2626"
        text: "#ffffff"
        radius: "md"
        weight: 500
    sizes:
      - { name: "sm", height: "32px", padding: "0 12px", fontSize: "13px" }
      - { name: "md", height: "36px", padding: "0 16px", fontSize: "14px" }
      - { name: "lg", height: "40px", padding: "0 20px", fontSize: "14px" }
  input:
    background: "#ffffff"
    border: "#e5e5e5"
    radius: "md"
    height: "36px"
    focusRing: "#2563eb"
    placeholder: "#a3a3a3"
  card:
    background: "#ffffff"
    border: "#e5e5e5"
    radius: "lg"
    padding: "24px"
    shadow: "none"
    hoverBorder: "#d4d4d4"

x-stylebase:
  version: "1.0.0"
  template: "clean-saas"
  generated-by: "stylebase"
  ai-rules:
    always:
      - "Use Geist for all text. Never substitute with Inter, Helvetica, or system fonts."
      - "Use the 8-step spacing scale. No arbitrary values like 7px or 13px."
      - "Buttons always use the defined variants. Never invent new button styles."
      - "Cards have no shadow. Elevation is communicated through border weight only."
      - "Use accent (#2563eb) for interactive elements: links, focus rings, active states."
      - "Mono font for any data, code, or machine-readable value."
    never:
      - "Never use gradients. Not on buttons, backgrounds, or text."
      - "Never use drop shadows on cards or containers."
      - "Never use border-radius larger than lg (12px) except on pills (full)."
      - "Never use colors outside the 18 defined tokens."
      - "Never use font weights outside 400, 500, 600."
---

# Clean SaaS Design System

## Design Philosophy

Clean SaaS prioritizes clarity over decoration. Every pixel serves a function: guiding the user through data-dense dashboards, settings panels, and workflow screens. The system uses whitespace as the primary visual hierarchy tool — not shadows, not gradients, not color intensity.

The aesthetic is "invisible design." Users should notice their data, not the interface holding it. This means consistent spacing, predictable component behavior, and zero visual surprises.

## Color Usage

The palette is intentionally neutral. Primary (#171717) and its foreground (#fafafa) handle 80% of all UI. Accent blue (#2563eb) draws attention to interactive elements — links, focus rings, primary actions — and nothing else.

Semantic colors (success, warning, error, info) appear only in context: form validation, status badges, alert banners. They never appear in navigation, decorative elements, or background fills.

Surface colors create subtle depth: background (#ffffff) → surface (#fafafa) → surface-raised (#ffffff with border). No shadows required.

## Typography Rules

Geist is the only permitted sans-serif. Geist Mono is the only permitted monospace. No other fonts.

Headlines use weight 600. Body uses weight 400. Medium (500) is reserved for button labels and emphasis within body text. No bold (700+) in the system.

The 8-step type scale starts at 12px (xs) for captions and maxes at 36px (4xl) for page titles. Do not interpolate — use only the defined steps.

## Spacing Philosophy

Every spacing value is a multiple of 4px. The 13-step scale provides enough granularity for tight form layouts (4px gaps) and generous section padding (96px). Use the scale, not arbitrary values.

Component internal padding follows a pattern: cards use 24px, buttons use their size-specific padding, inputs match button height for alignment.

## Component Principles

Buttons have five variants, three sizes. Primary is always dark on light. Destructive is always red. Never create a sixth variant — if you need one, the design isn't clear enough.

Inputs are 36px tall by default, matching md button height. Focus is communicated with a 2px accent ring, not a color change on the input itself.

Cards are borderless containers by default. Elevation comes from the border token, not shadow. Hover state is a stronger border, not a lift effect.

## What This System Is Not

This is not a brand-heavy marketing system. It has no hero gradients, no oversized type, no decorative illustrations. Use it for internal tools, dashboards, admin panels, and SaaS products where the user's data is the hero.

Attribution & License

The design.md format was created by Google Labs and released as an open standard in April 2026. Stylebase extends this format under the MIT license.

All Stylebase templates, the JSON Schema, and the SKILL.md enforcement file are MIT licensed. Use them freely in any project.