Design System Extractor
Analyse an existing website, HTML file, or screenshot and synthesise a semantic design system into a DESIGN.md file. The output is optimised for use with the design-loop skill and general page generation.
When to Use
- Starting a new project based on an existing site's visual language
- Documenting a site's design system that was never formally written down
- Preparing
.design/DESIGN.md before running the design loop
- Extracting brand guidelines from a client's existing website
- Creating consistency documentation for a multi-page project
- Extracting design tokens from a Google Stitch project
Workflow
Step 1: Identify the Source
Ask the user for one of:
| Source |
Method |
| Live URL |
Browse via Playwright CLI or scraper, screenshot + extract HTML |
| Local HTML file |
Read the file directly |
| Screenshot image |
Analyse visually (limited — no exact hex extraction) |
| Existing project |
Scan site/public/ for HTML files to analyse |
| Stitch project |
Use @google/stitch-sdk to fetch screen HTML + design theme |
Step 2: Extract Raw Design Data
From a Live URL
Browse the site using Playwright CLI:
playwright-cli -s=design open {url}
playwright-cli -s=design screenshot --filename=.design/screenshots/source-desktop.png
Extract the full HTML — either via scraper MCP or by reading the page source
Resize and screenshot mobile (375px):
playwright-cli -s=design resize 375 812
playwright-cli -s=design screenshot --filename=.design/screenshots/source-mobile.png
Close the session: playwright-cli -s=design close
From a Local HTML File
Read the file directly and extract design tokens from the source.
From a Screenshot Only
Analyse the image visually. Note: colour extraction will be approximate without HTML source. Flag this limitation in the output.
From a Google Stitch Project
If @google/stitch-sdk is installed and STITCH_API_KEY is set:
import { stitch } from "@google/stitch-sdk";
// List projects to find the target
const projects = await stitch.projects();
// Get project details (includes designTheme)
const project = stitch.project(projectId);
const screens = await project.screens();
// Get HTML from the main screen
const screen = screens[0]; // or find by title
const htmlUrl = await screen.getHtml();
const imageUrl = await screen.getImage();
The Stitch designTheme object provides structured tokens directly:
{
"colorMode": "DARK",
"font": "INTER",
"roundness": "ROUND_EIGHT",
"customColor": "#40baf7",
"saturation": 3
}
Map these to DESIGN.md sections:
colorMode → Theme (Light/Dark)
font → Typography font family
roundness → Component border-radius (ROUND_EIGHT = 8px, ROUND_SIXTEEN = 16px, etc.)
customColor → Primary brand colour
saturation → Colour vibrancy (1-5 scale)
Then also download and analyse the HTML for the full palette (Stitch's theme object only has the primary colour — the full palette is in the generated CSS).
Step 3: Analyse Design Tokens
Extract these from the HTML/CSS source:
Colours
Look in these locations (priority order):
- CSS custom properties —
:root { --primary: #hex; } or @theme blocks
- Tailwind config —
<script> block with tailwind.config or @theme in <style>
- Inline styles —
style="color: #hex" or style="background: #hex"
- Tailwind classes —
bg-blue-600, text-gray-900 (map to palette)
- Computed from screenshot — last resort, approximate
For each colour found, determine its role:
| Role |
How to identify |
| Primary |
Buttons, links, active states, brand elements |
| Background |
<body> or <html> background |
| Surface |
Cards, containers, elevated elements |
| Text Primary |
<h1>, <h2>, main body text |
| Text Secondary |
Captions, metadata, muted text |
| Border |
Dividers, input borders, card borders |
| Accent |
Badges, notifications, highlights |
Typography
Extract:
| Token |
Where to find |
| Font families |
Google Fonts <link>, @import, font-family in CSS |
| Heading weights |
font-bold, font-semibold, or explicit font-weight |
| Body size |
Base font-size on <body> or root |
| Line height |
leading-* classes or line-height CSS |
| Letter spacing |
tracking-* classes or letter-spacing CSS |
Components
Identify patterns for:
- Buttons — shape (rounded-full, rounded-lg), colours, padding, hover states
- Cards — background, border, shadow, border-radius, padding
- Navigation — sticky/static, background treatment, active indicator
- Forms — input style, focus ring, label positioning
- Hero sections — layout pattern, overlay treatment, CTA placement
Spacing & Layout
- Max content width — look for
max-w-* or explicit max-width
- Section padding — typical vertical padding between sections
- Grid system — column count, gap values
- Whitespace philosophy — tight, balanced, generous, or dramatic
Step 4: Synthesise into Natural Language
Critical: The DESIGN.md should describe the design in semantic, natural language supported by exact values. This is not a CSS dump — it's a document a designer or AI can read to understand and reproduce the visual language.
| Don't write |
Write instead |
rounded-xl |
"Softly rounded corners (12px)" |
shadow-md |
"Subtle elevation with diffused shadow" |
#1E40AF |
"Deep Ocean Blue (#1E40AF) for primary actions" |
py-16 |
"Generous section spacing with breathing room" |
Step 5: Write DESIGN.md
Output the file to .design/DESIGN.md (or user-specified path).
Follow the structure from the design-loop skill's references/site-template.md — specifically the DESIGN.md Template section. The key sections are:
- Visual Theme & Atmosphere — mood, vibe, philosophy
- Colour Palette & Roles — table with role, name, hex, usage
- Typography — font families, weights, sizes, line heights
- Component Styles — buttons, cards, nav, forms
- Layout Principles — max width, spacing, grid, whitespace
- Design System Notes for Generation — the copy-paste block for baton prompts
Step 6: Verify Accuracy
If browser automation is available:
- Generate a small test section (e.g. a card + button + heading) using the extracted design system
- Screenshot it alongside the original
- Compare visually — adjust any values that don't match
Step 7: Report to User
Present:
- Summary of extracted tokens (colour count, fonts, component patterns)
- The generated DESIGN.md location
- Any tokens that were approximate (flagged with ⚠️)
- Suggestions for manual review (colours from screenshots, ambiguous typography)
Handling Multiple Pages
If the site has multiple pages with different styles:
- Analyse the homepage first — it usually has the most complete design language
- Spot-check 2-3 inner pages for consistency
- Note any page-specific overrides in the Component Styles section
- If pages are wildly different, ask the user which page to use as the canonical source
Tips
- Tailwind sites are easiest — the config block has everything
- Google Fonts links are gold — they specify exact families and weights
- CSS custom properties are reliable — they represent intentional design tokens
- Inline Tailwind classes need interpretation —
bg-slate-900 needs mapping to a role
- Screenshots are last resort — accurate hex extraction from images is unreliable
- Dark mode: Check for
.dark class overrides or prefers-color-scheme media queries
Common Pitfalls
- ❌ Listing raw CSS values without semantic description
- ❌ Missing the dark mode palette (check for
.dark class or media query)
- ❌ Ignoring component patterns (just listing colours isn't enough)
- ❌ Not including Section 6 (the copy-paste generation block)
- ❌ Approximate colours from screenshots without flagging the uncertainty
1---2name: design-system3description: Extract a complete design system from an existing website or screenshot into a DESIGN.md file. Analyses colours, typography, component styles, spacing, and atmosphere through browser automation and HTML inspection. Produces a semantic design system document optimised for consistent page generation. Triggers: 'extract design system', 'design system', 'create DESIGN.md', 'analyse the design', 'what design does this site use', 'extract styles from', 'reverse engineer the design'.4---56# Design System Extractor78Analyse an existing website, HTML file, or screenshot and synthesise a semantic design system into a `DESIGN.md` file. The output is optimised for use with the `design-loop` skill and general page generation.910## When to Use1112- Starting a new project based on an existing site's visual language13- Documenting a site's design system that was never formally written down14- Preparing `.design/DESIGN.md` before running the design loop15- Extracting brand guidelines from a client's existing website16- Creating consistency documentation for a multi-page project17- Extracting design tokens from a Google Stitch project1819## Workflow2021### Step 1: Identify the Source2223Ask the user for one of:2425| Source | Method |26|--------|--------|27| **Live URL** | Browse via Playwright CLI or scraper, screenshot + extract HTML |28| **Local HTML file** | Read the file directly |29| **Screenshot image** | Analyse visually (limited — no exact hex extraction) |30| **Existing project** | Scan `site/public/` for HTML files to analyse |31| **Stitch project** | Use `@google/stitch-sdk` to fetch screen HTML + design theme |3233### Step 2: Extract Raw Design Data3435#### From a Live URL36371. **Browse the site** using Playwright CLI:38 ```39 playwright-cli -s=design open {url}40 playwright-cli -s=design screenshot --filename=.design/screenshots/source-desktop.png41 ```42432. **Extract the full HTML** — either via scraper MCP or by reading the page source44453. **Resize and screenshot mobile** (375px):46 ```47 playwright-cli -s=design resize 375 81248 playwright-cli -s=design screenshot --filename=.design/screenshots/source-mobile.png49 ```50514. Close the session: `playwright-cli -s=design close`5253#### From a Local HTML File5455Read the file directly and extract design tokens from the source.5657#### From a Screenshot Only5859Analyse the image visually. Note: colour extraction will be approximate without HTML source. Flag this limitation in the output.6061#### From a Google Stitch Project6263If `@google/stitch-sdk` is installed and `STITCH_API_KEY` is set:6465```typescript66import { stitch } from "@google/stitch-sdk";6768// List projects to find the target69const projects = await stitch.projects();7071// Get project details (includes designTheme)72const project = stitch.project(projectId);73const screens = await project.screens();7475// Get HTML from the main screen76const screen = screens[0]; // or find by title77const htmlUrl = await screen.getHtml();78const imageUrl = await screen.getImage();79```8081The Stitch `designTheme` object provides structured tokens directly:8283```json84{85 "colorMode": "DARK",86 "font": "INTER",87 "roundness": "ROUND_EIGHT",88 "customColor": "#40baf7",89 "saturation": 390}91```9293Map these to DESIGN.md sections:94- `colorMode` → Theme (Light/Dark)95- `font` → Typography font family96- `roundness` → Component border-radius (`ROUND_EIGHT` = 8px, `ROUND_SIXTEEN` = 16px, etc.)97- `customColor` → Primary brand colour98- `saturation` → Colour vibrancy (1-5 scale)99100Then also download and analyse the HTML for the full palette (Stitch's theme object only has the primary colour — the full palette is in the generated CSS).101102### Step 3: Analyse Design Tokens103104Extract these from the HTML/CSS source:105106#### Colours107108Look in these locations (priority order):1091101. **CSS custom properties** — `:root { --primary: #hex; }` or `@theme` blocks1112. **Tailwind config** — `<script>` block with `tailwind.config` or `@theme` in `<style>`1123. **Inline styles** — `style="color: #hex"` or `style="background: #hex"`1134. **Tailwind classes** — `bg-blue-600`, `text-gray-900` (map to palette)1145. **Computed from screenshot** — last resort, approximate115116For each colour found, determine its **role**:117118| Role | How to identify |119|------|-----------------|120| Primary | Buttons, links, active states, brand elements |121| Background | `<body>` or `<html>` background |122| Surface | Cards, containers, elevated elements |123| Text Primary | `<h1>`, `<h2>`, main body text |124| Text Secondary | Captions, metadata, muted text |125| Border | Dividers, input borders, card borders |126| Accent | Badges, notifications, highlights |127128#### Typography129130Extract:131132| Token | Where to find |133|-------|---------------|134| Font families | Google Fonts `<link>`, `@import`, `font-family` in CSS |135| Heading weights | `font-bold`, `font-semibold`, or explicit `font-weight` |136| Body size | Base `font-size` on `<body>` or root |137| Line height | `leading-*` classes or `line-height` CSS |138| Letter spacing | `tracking-*` classes or `letter-spacing` CSS |139140#### Components141142Identify patterns for:143144- **Buttons** — shape (rounded-full, rounded-lg), colours, padding, hover states145- **Cards** — background, border, shadow, border-radius, padding146- **Navigation** — sticky/static, background treatment, active indicator147- **Forms** — input style, focus ring, label positioning148- **Hero sections** — layout pattern, overlay treatment, CTA placement149150#### Spacing & Layout151152- **Max content width** — look for `max-w-*` or explicit `max-width`153- **Section padding** — typical vertical padding between sections154- **Grid system** — column count, gap values155- **Whitespace philosophy** — tight, balanced, generous, or dramatic156157### Step 4: Synthesise into Natural Language158159**Critical**: The DESIGN.md should describe the design in **semantic, natural language** supported by exact values. This is not a CSS dump — it's a document a designer or AI can read to understand and reproduce the visual language.160161| Don't write | Write instead |162|-------------|---------------|163| `rounded-xl` | "Softly rounded corners (12px)" |164| `shadow-md` | "Subtle elevation with diffused shadow" |165| `#1E40AF` | "Deep Ocean Blue (#1E40AF) for primary actions" |166| `py-16` | "Generous section spacing with breathing room" |167168### Step 5: Write DESIGN.md169170Output the file to `.design/DESIGN.md` (or user-specified path).171172Follow the structure from the `design-loop` skill's `references/site-template.md` — specifically the DESIGN.md Template section. The key sections are:1731741. **Visual Theme & Atmosphere** — mood, vibe, philosophy1752. **Colour Palette & Roles** — table with role, name, hex, usage1763. **Typography** — font families, weights, sizes, line heights1774. **Component Styles** — buttons, cards, nav, forms1785. **Layout Principles** — max width, spacing, grid, whitespace1796. **Design System Notes for Generation** — the copy-paste block for baton prompts180181### Step 6: Verify Accuracy182183If browser automation is available:1841851. Generate a small test section (e.g. a card + button + heading) using the extracted design system1862. Screenshot it alongside the original1873. Compare visually — adjust any values that don't match188189### Step 7: Report to User190191Present:192- Summary of extracted tokens (colour count, fonts, component patterns)193- The generated DESIGN.md location194- Any tokens that were approximate (flagged with ⚠️)195- Suggestions for manual review (colours from screenshots, ambiguous typography)196197## Handling Multiple Pages198199If the site has multiple pages with different styles:2002011. Analyse the **homepage first** — it usually has the most complete design language2022. Spot-check 2-3 inner pages for consistency2033. Note any **page-specific overrides** in the Component Styles section2044. If pages are wildly different, ask the user which page to use as the canonical source205206## Tips207208- **Tailwind sites are easiest** — the config block has everything209- **Google Fonts links are gold** — they specify exact families and weights210- **CSS custom properties are reliable** — they represent intentional design tokens211- **Inline Tailwind classes need interpretation** — `bg-slate-900` needs mapping to a role212- **Screenshots are last resort** — accurate hex extraction from images is unreliable213- **Dark mode**: Check for `.dark` class overrides or `prefers-color-scheme` media queries214215## Common Pitfalls216217- ❌ Listing raw CSS values without semantic description218- ❌ Missing the dark mode palette (check for `.dark` class or media query)219- ❌ Ignoring component patterns (just listing colours isn't enough)220- ❌ Not including Section 6 (the copy-paste generation block)221- ❌ Approximate colours from screenshots without flagging the uncertainty