What does design-md · DESIGN.md Design Contract Workflow do?
Extract scattered design decisions from style code and distill them into a DESIGN.md—a design contract that both AI agents and humans can read. This skill covers the complete loop:
Research (optional online) → Extract → Scaffold → Apply to Code → Verify → CI Gate
DESIGN.md is a concept introduced by Google Stitch: a plain-text design system document kept at the project root, ensuring visual consistency in any UI output produced by AI coding agents that read it.
AGENTS.mdgoverns "how to build",DESIGN.mdgoverns "what it looks like".
Directory Structure
| Location | Purpose |
|---|---|
scripts/wcag.py | WCAG 2.1 contrast engine: parses tokens.css / design-tokens.json, auto-pairs tokens per convention (text 4.5:1, UI 3:1), exit code can be used as CI gate |
scripts/extract.py | Extracts design token drafts from any URL (color rank / font stack / border-radius), outputs tokens-draft.json + DESIGN.draft.md skeleton |
scripts/scaffold.py | One-command generation from token JSON: tokens.css (dual-form tokens) + tailwind.extend.js + preview.html visual catalog + contrast report |
scripts/fetch_ref.py | Fetches reference DESIGN.md from awesome-design-md (84 brands, raw → gh API dual-channel fallback) |
scripts/research.py | DeepSeek Search/Fetch online research (paid direct API, disabled by default: requires explicit user consent then --yes-billing; key read from local file / environment variable, never echoed) |
references/spec.md | DESIGN.md file spec: frontmatter + YAML tokens + 11-section body + style rules |
references/lessons.md | Hard-learned lessons: dual-form tokens, alpha-dilution pitfalls, accent-splitting, data contracts, etc. (from real production audits) |
references/research.md | DeepSeek Search/Fetch API usage + awesome-design-md reference library catalog (84 slugs full list) |
references/verify.md | Verification checklist + CI wiring template (npm script / GitHub Actions) |
templates/design-tokens.example.json | Runnable example input (dual theme, all passes AA), just adapt it |
Quick Start
# 0) Environment: python3 ≥ 3.9, standard library only
python3 scripts/wcag.py --help
# 1) Research (optional): Extract token draft from a reference site
python3 scripts/extract.py --url https://example.com --out-dir ./design-draft
# → design-draft/tokens-draft.json + design-draft/DESIGN.draft.md
# 2) Pull a well-known brand's DESIGN.md for reference (inspiration, not copying)
python3 scripts/fetch_ref.py --list # See 84 slugs
python3 scripts/fetch_ref.py --slug linear.app # → ./DESIGN.reference-linear.app.md
# 2b) (Optional) DeepSeek online research—paid direct API (CN¥5 / 1000 successful requests), disabled by default:
# Run with --yes-billing only after user explicit consent; key provided via local file, never enters conversation/log
python3 scripts/research.py --yes-billing check # Verify key (default reads %USERPROFILE%\.deepseek\api_key)
python3 scripts/research.py --yes-billing search --query "fintech dashboard design site:dribbble.com" --count 8
# 3) Generate complete token project (input: your aligned tokens JSON)
python3 scripts/scaffold.py --tokens my-tokens.json --out ./design-out
# → tokens.css / design-tokens.json / tailwind.extend.js / preview.html / contrast-report.txt
# 4) Verify (run standalone or in CI)
python3 scripts/wcag.py --tokens ./design-out/tokens.css # CSS input
python3 scripts/wcag.py --tokens ./design-out/design-tokens.json # JSON input
python3 scripts/wcag.py --pair "#E6E9EF:#0A0C10:4.5" # Quick single-pair hex check
Standard Workflow (execution order for agents)
- Define Requirements: Read project state (any existing DESIGN.md / tokens / component library?), clarify theme direction (dark-first? brand colors? industry tone—finance, developer tooling, healthcare…).
- Research (optional): Use methods in
references/research.mdfor design research—DeepSeek Search for reference sites (paid direct API and disabled by default: first present cost to user and obtain explicit consent before using --yes-billing; fall back to built-in scraping if not agreed), DeepSeek Fetch / built-in scrape to read pages as Markdown; pull 1-3 industry-matched DESIGN.md from awesome-design-md. - Extract/Draft:
extract.pyproduces draft → organize roles manually/agent according to the 11-section structure inreferences/spec.md(turn "#5e6ad2 appearing 200 times" into "brand primary color, for CTA and focus rings"). - Scaffold: Organize into a spec-compliant tokens JSON →
scaffold.pyproduces full engineering files (including preview page for user review). - Apply: Wire tokens.css / Tailwind mappings into the project; implement components according to DESIGN.md §4 component rules.
- Verify:
wcag.pyall green + go through each item inreferences/verify.mdchecklist; wire the gate into CI (see verify.md template). - Iterate: Any color value change → must re-run
wcag.py, never rely on visual intuition; record design decision changes back into DESIGN.md (version notes).
Hard Rules (Must Follow)
- Contrast is not based on visual feeling: Run
wcag.pyon any color change. Text ≥4.5:1, UI controls/borders ≥3:1. - Dual-form tokens: Output both
--x(hex) and--x-rgb(channels) for every color; otherwise Tailwind opacity modifiers silently break (see lessons.md #1). - Do not use alpha dilution like
bg-{warn}/10for light backgrounds—light backgrounds must be independent tokens (--warn-soft). Testing shows dilution methods worsen contrast on light themes. - Split brand color into two tiers:
--accent(text/links) and--accent-solid(solid background buttons). A single value cannot simultaneously satisfy "bright text on dark background" and "dark background under white text" both ≥4.5:1. - Use
--border-strongfor interactive boundaries (3:1);--borderis for decorative separation only. - Honestly mark Known Gaps: Anything not extracted (form error states, light variant, private font fallbacks) truthfully record in DESIGN.md, do not fake completeness.
- Reference ≠ Copying: awesome-design-md analyzes public CSS characteristics of each brand; when citing, read their "methods" (layering, rhythm, trade-offs), do not impersonate a brand identity; commercial projects beware of trademark and font licensing.
Safety
- Never echo any API Key. Key resolution order:
--key-file→ environment variableDEEPSEEK_API_KEY→ environment variableDEEPSEEK_API_KEY_FILE→ default file%USERPROFILE%\.deepseek\api_key(recommend users create it in their terminal; the key never passes through conversation/log).research.pymasks all key output assk-***. - Billing protection (disabled by default, 2026-10): DeepSeek Search/Fetch are direct-pay billing APIs (CN¥5 per 1000 successful requests each; account-level Search 100 QPS / Fetch 25 QPS). If
research.pyruns without--yes-billing(and environment variableDEEPSEEK_BILLING_CONSENTis not1), it directly refuses (exit 3)—the agent must first explain the cost to the user and obtain explicit consent before adding the flag; pay-as-you-go environments like opencode are considered not consented by default. - When key is not configured, do not assume "must be online" as per docstring—
extract.pyuses local urllib fetching; DeepSeek is only an enhancement. - Fetching respects robots.txt and rate limits;
extract.pyby default fetches at most 5 stylesheets, each capped at 512KB.
Relationship with Other Capabilities
- awesome-design-md (VoltAgent, MIT): A collection of 84 real-site DESIGN.md analyses. This skill provides
fetch_ref.pyfor one-click usage; it's the "reference material library", this skill is the "workflow engine". - DeepSeek Search/Fetch:
https://api.deepseek.com/v1/tools/search|fetch. Real-time web search and content fetching during the design research phase (supportssite:/lang:/after:syntax). Per-request billing (CN¥5 per 1000 successful requests—only counted if "response 200 and result non-empty"; failures/timeouts/empty results not billed). Account-level rate limits: Search 100 QPS / Fetch 25 QPS (exceeding returns 429;research.pyautomatically backs off and retries). This skill providesscripts/research.pyas a wrapper (key never echoed; disabled by default—requires explicit user consent and--yes-billing, see §Safety). - Google Stitch official lint (optional):
npx @google/design.md lint DESIGN.md.