Design Extractor
Scrapes a URL, analyzes the visual design system, and generates: DESIGN.md, tailwind-theme.css, accessibility-report.md, and a preview screenshot.
Announce at start: "I'm using the design-extractor skill."
Workflow
Ask for name — "What should I call this design?" (used for folder naming and frontmatter). Convert the answer to lowercase kebab-case for the folder name.
Scrape the URL — run:
firecrawl scrape "<url>" --format html -o /tmp/design-extract-raw.html
If that fails or returns thin content, try without --only-main-content to get the full page. For JS-heavy sites, add --wait-for 3000.
Capture screenshot — run:
firecrawl scrape "<url>" --format screenshot -o /tmp/design-extract-screenshot-raw.txt
Firecrawl returns a URL to the screenshot, not the binary file. Extract and download it:
SCREENSHOT_URL=$(head -1 /tmp/design-extract-screenshot-raw.txt | sed 's/Screenshot: //') && curl -sL "$SCREENSHOT_URL" -o /tmp/design-extract-preview.png
Verify it's a valid PNG: file /tmp/design-extract-preview.png should show "PNG image data".
Read the scraped file — the HTML file may be very large (500KB+). Don't try to read it all at once. Instead:
- Extract hex colors:
cat /tmp/design-extract-raw.html | grep -oE '#[0-9a-fA-F]{3,8}' | sort | uniq -c | sort -rn | head -30
- Look for font names:
cat /tmp/design-extract-raw.html | grep -ioE 'inter|roboto|SF Pro|system-ui|helvetica|poppins|outfit|geist|sohne' | sort | uniq -c | sort -rn
- Check dark mode:
cat /tmp/design-extract-raw.html | grep -oE 'data-theme="[^"]+"' | sort -u and cat /tmp/design-extract-raw.html | grep -oE 'color-scheme:[^;"]+' | sort -u
- Extract radius values:
cat /tmp/design-extract-raw.html | grep -oE 'border-radius:[^;"]+' | sort | uniq -c | sort -rn | head -10
- Then read portions of the file with offset/limit to examine specific style blocks and class patterns.
Extract design tokens — follow the Analysis Instructions below to identify colors, typography, spacing, shadows, radii, layout patterns, and responsive breakpoints. Also detect dark mode — see Dark Mode Detection below.
Generate DESIGN.md — structure extracted tokens into the format using the Output Template below. If dark mode was detected, include section 10 (Dark Mode).
Generate tailwind-theme.css — map extracted tokens to semantic Tailwind v4 theme variables using the Output Template below. If dark mode was detected, include the @media (prefers-color-scheme: dark) block.
Run accessibility checks — follow the Accessibility Check Instructions below. Generate accessibility-report.md. If dark mode was detected, run checks for both light and dark palettes.
Save to library — write all files to ~/.claude/designs/<name>/. Create the directory if needed:
mkdir -p ~/.claude/designs/<name>
Copy the screenshot: move /tmp/design-extract-preview.png to ~/.claude/designs/<name>/preview.png.
Update library index — read ~/.claude/designs/_index.md and append a row:
| <name> | <url> | <YYYY-MM-DD> | <color-count> | <aa-pass-rate>% | <dark-mode?> |
If a design with the same name already exists in the index, ask the user before overwriting.
Ask about project — "Want me to copy this into your current project's .claude/design/ directory?" If yes, create .claude/design/ and copy all files including preview.png.
Analysis Instructions
When reading the scraped HTML, extract design tokens using these guidelines:
Colors
Look for color values in all formats: hex (#xxx, #xxxxxx), rgb(), rgba(), hsl(), hsla(), CSS custom properties (--color-, ---color). Also look for Tailwind class patterns (bg-blue-500, text-gray-900, etc.) and infer the underlying values.
Categorize by usage context:
- Primary — dominant brand color, main CTAs, primary buttons. Look at the most prominent button or link color.
- Secondary — supporting brand color, secondary buttons/actions. Look for a second prominent color used for less important interactive elements.
- Accent — decorative elements, gradients, highlights, hover states. Look for colors used sparingly for emphasis.
- Neutral — text colors, labels, body copy, disabled states. Look at paragraph and heading text colors.
- Status — success (green-ish), warning (yellow/orange-ish), error (red-ish). Look in form validation, alerts, badges.
- Surface — page backgrounds, card backgrounds, section backgrounds. Look at body background, card/panel backgrounds.
- Border — default borders, dividers, focus rings. Look at input borders, card borders, horizontal rules.
Typography
Look for:
font-family declarations — capture the full stack
@font-face blocks — note the font name, weights available, and file URLs if visible
- Font size patterns — map to a scale (display/hero, heading, subheading, body, caption, code)
- Font weight patterns — note which weights are used where
- Line height and letter-spacing values — associate with each scale level
font-feature-settings — note any OpenType features (tabular numbers, stylistic sets)
Spacing
Look for repeated margin, padding, and gap values. Identify the scale pattern (e.g., 4px, 8px, 12px, 16px, 24px, 32px, 48px, 64px). Note which values appear most frequently.
Border Radius
Look for border-radius values and their context:
- Small (1-2px) — micro, subtle rounding
- Medium (4-6px) — buttons, inputs
- Large (8-12px) — cards, panels
- XL (16px+) — featured elements, pills
Shadows / Elevation
Look for box-shadow values. Categorize by visual depth:
- Level 0 — flat, no shadow
- Level 1 — subtle ambient shadow
- Level 2 — standard card shadow
- Level 3 — elevated, prominent shadow
- Level 4 — deep shadow (dropdowns, modals)
- Focus — ring/outline style for focus states
Layout
Look for:
max-width on containers — note the site's content width
- Grid patterns (
grid-template-columns, common column counts)
- Flexbox patterns (common flex arrangements)
- Section padding patterns
Responsive
Look for @media queries. Note:
- Breakpoint values (e.g., 640px, 768px, 1024px, 1280px)
- What changes at each breakpoint (layout shifts, font size changes, visibility toggles)
When Uncertain
If a token is ambiguous (e.g., a color could be primary or secondary), make your best judgment based on visual prominence and usage frequency. Add a <!-- uncertain: reason --> comment in the DESIGN.md output so the user can verify.
Dark Mode Detection
Look for dark mode indicators in the scraped HTML:
prefers-color-scheme media queries — @media (prefers-color-scheme: dark) blocks with alternate color values
- Dark mode class toggles —
.dark, [data-theme="dark"], .theme-dark, [color-scheme="dark"] selectors with alternate colors
- CSS custom property overrides —
:root variables redefined inside dark mode selectors or media queries
- Tailwind dark mode classes —
dark:bg-*, dark:text-* patterns in HTML
If dark mode is detected:
- Extract a complete alternate color palette (all the same roles: primary, secondary, accent, neutral, status, surface, border)
- Note which mechanism is used (media query vs class toggle)
- Include section 10 in DESIGN.md and the dark mode block in tailwind-theme.css
- Run accessibility checks for both light and dark palettes
If the site is dark-first (the default/only theme served is dark, like Linear), note this in the DESIGN.md — the main palette IS the dark palette. The tailwind-theme.css should include a comment suggesting where to add light mode overrides if needed, rather than a prefers-color-scheme: dark block.
If no dark mode is detected, skip section 10 and the dark CSS block. Do not fabricate a dark palette.
Output Templates
DESIGN.md
---
name: "<design-name>"
source: "<url>"
extracted: YYYY-MM-DD
tags:
- design-system
---
# <Design Name> Design System
## 1. Visual Theme & Atmosphere
One paragraph describing the overall aesthetic: mood, visual language, influences, best suited for what kind of projects.
## 2. Color Palette
### Primary
| Name | Hex | Role |
|------|-----|------|
| ... | #... | Brand, CTA |
### Secondary
| Name | Hex | Role |
|------|-----|------|
| ... | #... | Supporting brand, secondary actions |
### Accent
| Name | Hex | Role |
|------|-----|------|
| ... | #... | Decorative, gradients, highlights |
### Neutral
| Name | Hex | Role |
|------|-----|------|
| ... | #... | Text, labels, body |
### Status
| Name | Hex | Role |
|------|-----|------|
| Success | #... | Success states |
| Warning | #... | Warning states |
| Error | #... | Error states |
### Surface & Border
| Name | Hex | Role |
|------|-----|------|
| Background | #... | Page background |
| Card | #... | Card/panel background |
| Border | #... | Default border |
## 3. Typography
**Font Family:** `<font-name>`, <fallback-stack>
| Level | Size | Weight | Line Height | Letter Spacing | Notes |
|-------|------|--------|-------------|----------------|-------|
| Display | ...px | ... | ... | ... | |
| Heading | ...px | ... | ... | ... | |
| Subheading | ...px | ... | ... | ... | |
| Body | ...px | ... | ... | ... | |
| Caption | ...px | ... | ... | ... | |
| Code | ...px | ... | ... | ... | Monospace font |
## 4. Components
### Buttons
| Variant | Background | Text | Border | Radius | Notes |
|---------|------------|------|--------|--------|-------|
| Primary | ... | ... | ... | ... | |
| Secondary | ... | ... | ... | ... | |
| Ghost | ... | ... | ... | ... | |
| Disabled | ... | ... | ... | ... | |
### Cards
- Default: background, border, shadow, radius
- Elevated: shadow variant
- Interactive: hover state
### Form Elements
- Default input: border, radius, padding
- Focus: ring color, ring width
- Error: border color, message color
### Badges
- Variants observed with colors
## 5. Layout
- **Max content width:** ...px
- **Grid:** ... columns, ... gap
- **Container padding:** ...
## 6. Spacing
| Token | Value | Mapped to |
|-------|-------|-----------|
| xxs | ...px | Tight inline gaps |
| xs | ...px | Small gaps |
| s | ...px | Default small |
| m | ...px | Medium (anchor) |
| l | ...px | Sections, cards |
| xl | ...px | Large sections |
| xxl | ...px | Page-level |
## 7. Border Radius
| Token | Value | Context |
|-------|-------|---------|
| micro | ...px | Subtle rounding |
| button | ...px | Buttons, inputs |
| card | ...px | Cards, panels |
| featured | ...px | Featured elements |
## 8. Elevation
| Level | CSS Value | Usage |
|-------|-----------|-------|
| 0 (flat) | none | Default |
| 1 (subtle) | ... | Ambient |
| 2 (standard) | ... | Cards |
| 3 (elevated) | ... | Dropdowns |
| 4 (deep) | ... | Modals |
| Focus | ... | Focus rings |
## 9. Responsive Behavior
| Breakpoint | Width | Changes |
|------------|-------|---------|
| sm | ...px | ... |
| md | ...px | ... |
| lg | ...px | ... |
| xl | ...px | ... |
## 10. Dark Mode (if detected)
**Mechanism:** `<prefers-color-scheme | class toggle (.dark) | data attribute>`
### Dark Color Palette
| Token | Light | Dark | Role |
|-------|-------|------|------|
| text | #... | #... | Body text |
| background | #... | #... | Page background |
| primary | #... | #... | Brand, CTA |
| secondary | #... | #... | Supporting brand |
| accent | #... | #... | Decorative |
| muted | #... | #... | Secondary text |
| border | #... | #... | Borders |
| card | #... | #... | Card surfaces |
<!-- Only include this section if dark mode was detected in the source. Do not fabricate a dark palette. -->
tailwind-theme.css
/* Design: <design-name>
* Source: <url>
* Extracted: YYYY-MM-DD
*
* Import this file in your main stylesheet:
* @import "./tailwind-theme.css";
*
* Or copy the @theme block into your existing src/style.css
*/
@theme {
/* COLORS */
--color-text: #...;
--color-background: #...;
--color-primary: #...;
--color-secondary: #...;
--color-accent: #...;
--color-muted: #...;
--color-error: #...;
--color-success: #...;
--color-warning: #...;
--color-border: #...;
--color-card: #...;
/* FONT FAMILY */
/* NOTE: Font files need to be sourced and self-hosted as woff2.
* See: https://gwfh.mranftl.com/fonts
* Original font detected: <font-name> */
--font-sans: '<font-name>', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
/* FLUID SPACING */
--spacing-0: 0;
--spacing-xxs: clamp(0.25rem, 1vw, 0.5rem);
--spacing-xs: clamp(0.5rem, 1.5vw, 0.75rem);
--spacing-s: clamp(0.75rem, 2vw, 1rem);
--spacing-m: 1.25rem;
--spacing-l: clamp(1.25rem, 3vw, 2.5rem);
--spacing-xl: clamp(1.25rem, 5vw, 3.75rem);
--spacing-xxl: clamp(1.25rem, 10vw, 7.5rem);
/* BORDER RADIUS */
--radius-micro: ...;
--radius-button: ...;
--radius-card: ...;
--radius-featured: ...;
}
/* Color variants (auto-generated via color-mix in oklch) */
:root {
--color-primary-light: color-mix(in oklch, var(--color-primary), white 30%);
--color-primary-dark: color-mix(in oklch, var(--color-primary), black 20%);
--color-secondary-light: color-mix(in oklch, var(--color-secondary), white 30%);
--color-secondary-dark: color-mix(in oklch, var(--color-secondary), black 20%);
--color-accent-light: color-mix(in oklch, var(--color-accent), white 30%);
--color-accent-dark: color-mix(in oklch, var(--color-accent), black 20%);
}
/* @font-face — uncomment and update paths after sourcing woff2 files
@font-face {
font-family: '<font-name>';
src: url('/fonts/<font-file>-400.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
*/
/* Dark mode — only include if detected in source
* Uses prefers-color-scheme by default.
* If the source uses a class toggle (.dark), replace the @media query
* with: .dark { ... }
*/
/*
@media (prefers-color-scheme: dark) {
:root {
--color-text: #...;
--color-background: #...;
--color-primary: #...;
--color-secondary: #...;
--color-accent: #...;
--color-muted: #...;
--color-error: #...;
--color-success: #...;
--color-warning: #...;
--color-border: #...;
--color-card: #...;
--color-primary-light: color-mix(in oklch, var(--color-primary), white 30%);
--color-primary-dark: color-mix(in oklch, var(--color-primary), black 20%);
--color-secondary-light: color-mix(in oklch, var(--color-secondary), white 30%);
--color-secondary-dark: color-mix(in oklch, var(--color-secondary), black 20%);
--color-accent-light: color-mix(in oklch, var(--color-accent), white 30%);
--color-accent-dark: color-mix(in oklch, var(--color-accent), black 20%);
}
}
*/
accessibility-report.md
---
design: "<design-name>"
checked: YYYY-MM-DD
---
# Accessibility Report: <Design Name>
## Contrast Ratio Results
| Pair | Ratio | AA Normal | AA Large | AAA Normal | AAA Large |
|------|-------|-----------|----------|------------|-----------|
| background / text | X.X:1 | PASS/FAIL | PASS/FAIL | PASS/FAIL | PASS/FAIL |
| background / muted | X.X:1 | ... | ... | ... | ... |
| primary / white | X.X:1 | ... | ... | ... | ... |
| primary / background | X.X:1 | ... | ... | ... | ... |
| secondary / white | X.X:1 | ... | ... | ... | ... |
| secondary / background | X.X:1 | ... | ... | ... | ... |
| accent / text | X.X:1 | ... | ... | ... | ... |
| accent / background | X.X:1 | ... | ... | ... | ... |
| card / text | X.X:1 | ... | ... | ... | ... |
| card / muted | X.X:1 | ... | ... | ... | ... |
| error / white | X.X:1 | ... | ... | ... | ... |
| success / white | X.X:1 | ... | ... | ... | ... |
| warning / white | X.X:1 | ... | ... | ... | ... |
## Failures & Suggested Fixes
<!-- Only include this section if there are failures -->
| Pair | Current Ratio | Required | Suggestion |
|------|---------------|----------|------------|
| ... | X.X:1 | 4.5:1 (AA) | Darken/lighten <token> to #... |
## Colorblindness Simulation
| Pair | Protanopia | Deuteranopia | Tritanopia |
|------|------------|--------------|------------|
| ... | OK / FLAG | OK / FLAG | OK / FLAG |
<!-- FLAG means the two colors become difficult to distinguish under this type of color vision deficiency -->
## Summary
- **Total pairs checked:** N
- **AA pass rate:** N/N (X%)
- **AAA pass rate:** N/N (X%)
- **Critical failures (AA normal text):** N
- **Colorblindness flags:** N pairs flagged
Accessibility Check Instructions
When generating the accessibility report, perform these calculations for every surface/text color pair.
Contrast Ratios
- Convert each hex color to sRGB values (0-1 range):
R = hex/255, G = hex/255, B = hex/255
- Linearize each channel:
channel <= 0.03928 ? channel/12.92 : ((channel+0.055)/1.055)^2.4
- Calculate relative luminance:
L = 0.2126*R_lin + 0.7152*G_lin + 0.0722*B_lin
- Calculate contrast ratio:
(L_lighter + 0.05) / (L_darker + 0.05)
- Compare against thresholds:
- AA normal text: 4.5:1
- AA large text (18px+ bold or 24px+): 3:1
- AAA normal text: 7:1
- AAA large text: 4.5:1
Color Pairs to Check
Generate all meaningful surface/text combinations:
- background / text
- background / muted
- primary / white (#FFFFFF)
- primary / background
- secondary / white (#FFFFFF)
- secondary / background
- accent / text
- accent / background
- card / text
- card / muted
- error / white (#FFFFFF)
- success / white (#FFFFFF)
- warning / white (#FFFFFF) — or warning / text if warning is light
If additional surface/text pairs are evident from the design (e.g., dark section backgrounds with light text), include those too.
Colorblindness Simulation
For each pair of colors that serve different semantic purposes (e.g., success vs error, primary vs accent):
- Apply approximate transformation matrices for protanopia, deuteranopia, and tritanopia
- Compare the simulated colors — if they appear very similar (approximate visual delta < 3.0), flag the pair
- This is an approximation — flag as "possible issue" rather than claiming diagnostic precision
Common problems to watch for:
- Red/green pairs (protanopia, deuteranopia) — success vs error colors
- Blue/purple pairs (tritanopia) — primary vs accent when both are blue-purple range
Suggested Fixes
For each failing contrast pair, suggest the minimum color adjustment needed:
- Calculate what luminance the text/surface color would need to reach the threshold
- Suggest a specific hex value that meets the requirement
- Prefer darkening text or lightening surfaces (maintain the design intent)
Library Management
Saving to Library
- Create the design directory:
mkdir -p ~/.claude/designs/<name>
- Write all four files to
~/.claude/designs/<name>/ (DESIGN.md, tailwind-theme.css, accessibility-report.md, preview.png)
- Read
~/.claude/designs/_index.md
- Append a new row with: name, source URL, today's date, count of unique colors extracted, AA pass rate from the accessibility report
- Write the updated
_index.md
If a design with the same name already exists, ask: "A design called '' already exists in the library. Overwrite it?"
Copying to Project
When the user says "use the design" in any project:
- Read files from
~/.claude/designs/<name>/
- Create
.claude/design/ in the current project: mkdir -p .claude/design
- Copy all files (DESIGN.md, tailwind-theme.css, accessibility-report.md, preview.png)
- Confirm: "Copied design to
.claude/design/. The tailwind-theme.css is ready to import into your stylesheet."
Next Steps
After extraction completes, suggest these follow-up actions to the user:
- "Validate the theme" — invoke
design-system-standards to check that the generated tailwind-theme.css meets all token conventions (semantic naming, fluid spacing, contrast pairs documented)
- "Build components from this design" — invoke
frontend-design to create UI components (buttons, cards, forms, nav) that match the extracted design system. It will read .claude/design/DESIGN.md automatically if the design was copied to the project.
- "Check Tailwind v4 patterns" — invoke
tailwind-patterns to verify the @theme block follows current v4 best practices (CSS-first config, container queries, modern utility patterns)
Include these as a bulleted list in your final message to the user after saving the files.
See Also
- design-auditor — audit an existing project's design system instead of extracting from a URL
- design-system-standards — token conventions and Tailwind v4 patterns these files follow
- frontend-design — build production-grade UI components from a DESIGN.md
- tailwind-patterns — Tailwind v4 best practices and modern patterns
1---2name: design-extractor3description: Extract a visual design system from any website URL and generate a DESIGN.md, Tailwind v4 theme, and accessibility report. Use when the user says "extract the design from <url>", "grab the design from <url>", "get the design system from <url>", "pull the design from <url>", or similar. Requires Firecrawl CLI.4---56# Design Extractor78Scrapes a URL, analyzes the visual design system, and generates: DESIGN.md, tailwind-theme.css, accessibility-report.md, and a preview screenshot.910**Announce at start:** "I'm using the design-extractor skill."1112## Workflow13141. **Ask for name** — "What should I call this design?" (used for folder naming and frontmatter). Convert the answer to lowercase kebab-case for the folder name.15162. **Scrape the URL** — run:17 ```bash18 firecrawl scrape "<url>" --format html -o /tmp/design-extract-raw.html19 ```20 If that fails or returns thin content, try without `--only-main-content` to get the full page. For JS-heavy sites, add `--wait-for 3000`.21223. **Capture screenshot** — run:23 ```bash24 firecrawl scrape "<url>" --format screenshot -o /tmp/design-extract-screenshot-raw.txt25 ```26 Firecrawl returns a URL to the screenshot, not the binary file. Extract and download it:27 ```bash28 SCREENSHOT_URL=$(head -1 /tmp/design-extract-screenshot-raw.txt | sed 's/Screenshot: //') && curl -sL "$SCREENSHOT_URL" -o /tmp/design-extract-preview.png29 ```30 Verify it's a valid PNG: `file /tmp/design-extract-preview.png` should show "PNG image data".31324. **Read the scraped file** — the HTML file may be very large (500KB+). Don't try to read it all at once. Instead:33 - Extract hex colors: `cat /tmp/design-extract-raw.html | grep -oE '#[0-9a-fA-F]{3,8}' | sort | uniq -c | sort -rn | head -30`34 - Look for font names: `cat /tmp/design-extract-raw.html | grep -ioE 'inter|roboto|SF Pro|system-ui|helvetica|poppins|outfit|geist|sohne' | sort | uniq -c | sort -rn`35 - Check dark mode: `cat /tmp/design-extract-raw.html | grep -oE 'data-theme="[^"]+"' | sort -u` and `cat /tmp/design-extract-raw.html | grep -oE 'color-scheme:[^;"]+' | sort -u`36 - Extract radius values: `cat /tmp/design-extract-raw.html | grep -oE 'border-radius:[^;"]+' | sort | uniq -c | sort -rn | head -10`37 - Then read portions of the file with offset/limit to examine specific style blocks and class patterns.38395. **Extract design tokens** — follow the Analysis Instructions below to identify colors, typography, spacing, shadows, radii, layout patterns, and responsive breakpoints. Also detect dark mode — see Dark Mode Detection below.40416. **Generate DESIGN.md** — structure extracted tokens into the format using the Output Template below. If dark mode was detected, include section 10 (Dark Mode).42437. **Generate tailwind-theme.css** — map extracted tokens to semantic Tailwind v4 theme variables using the Output Template below. If dark mode was detected, include the `@media (prefers-color-scheme: dark)` block.44458. **Run accessibility checks** — follow the Accessibility Check Instructions below. Generate accessibility-report.md. If dark mode was detected, run checks for both light and dark palettes.46479. **Save to library** — write all files to `~/.claude/designs/<name>/`. Create the directory if needed:48 ```bash49 mkdir -p ~/.claude/designs/<name>50 ```51 Copy the screenshot: move `/tmp/design-extract-preview.png` to `~/.claude/designs/<name>/preview.png`.525310. **Update library index** — read `~/.claude/designs/_index.md` and append a row:54 ```55 | <name> | <url> | <YYYY-MM-DD> | <color-count> | <aa-pass-rate>% | <dark-mode?> |56 ```57 If a design with the same name already exists in the index, ask the user before overwriting.585911. **Ask about project** — "Want me to copy this into your current project's `.claude/design/` directory?" If yes, create `.claude/design/` and copy all files including preview.png.6061## Analysis Instructions6263When reading the scraped HTML, extract design tokens using these guidelines:6465### Colors6667Look for color values in all formats: hex (#xxx, #xxxxxx), rgb(), rgba(), hsl(), hsla(), CSS custom properties (--color-*, --*-color). Also look for Tailwind class patterns (bg-blue-500, text-gray-900, etc.) and infer the underlying values.6869Categorize by usage context:70- **Primary** — dominant brand color, main CTAs, primary buttons. Look at the most prominent button or link color.71- **Secondary** — supporting brand color, secondary buttons/actions. Look for a second prominent color used for less important interactive elements.72- **Accent** — decorative elements, gradients, highlights, hover states. Look for colors used sparingly for emphasis.73- **Neutral** — text colors, labels, body copy, disabled states. Look at paragraph and heading text colors.74- **Status** — success (green-ish), warning (yellow/orange-ish), error (red-ish). Look in form validation, alerts, badges.75- **Surface** — page backgrounds, card backgrounds, section backgrounds. Look at body background, card/panel backgrounds.76- **Border** — default borders, dividers, focus rings. Look at input borders, card borders, horizontal rules.7778### Typography7980Look for:81- `font-family` declarations — capture the full stack82- `@font-face` blocks — note the font name, weights available, and file URLs if visible83- Font size patterns — map to a scale (display/hero, heading, subheading, body, caption, code)84- Font weight patterns — note which weights are used where85- Line height and letter-spacing values — associate with each scale level86- `font-feature-settings` — note any OpenType features (tabular numbers, stylistic sets)8788### Spacing8990Look for repeated margin, padding, and gap values. Identify the scale pattern (e.g., 4px, 8px, 12px, 16px, 24px, 32px, 48px, 64px). Note which values appear most frequently.9192### Border Radius9394Look for `border-radius` values and their context:95- Small (1-2px) — micro, subtle rounding96- Medium (4-6px) — buttons, inputs97- Large (8-12px) — cards, panels98- XL (16px+) — featured elements, pills99100### Shadows / Elevation101102Look for `box-shadow` values. Categorize by visual depth:103- Level 0 — flat, no shadow104- Level 1 — subtle ambient shadow105- Level 2 — standard card shadow106- Level 3 — elevated, prominent shadow107- Level 4 — deep shadow (dropdowns, modals)108- Focus — ring/outline style for focus states109110### Layout111112Look for:113- `max-width` on containers — note the site's content width114- Grid patterns (`grid-template-columns`, common column counts)115- Flexbox patterns (common flex arrangements)116- Section padding patterns117118### Responsive119120Look for `@media` queries. Note:121- Breakpoint values (e.g., 640px, 768px, 1024px, 1280px)122- What changes at each breakpoint (layout shifts, font size changes, visibility toggles)123124### When Uncertain125126If a token is ambiguous (e.g., a color could be primary or secondary), make your best judgment based on visual prominence and usage frequency. Add a `<!-- uncertain: reason -->` comment in the DESIGN.md output so the user can verify.127128## Dark Mode Detection129130Look for dark mode indicators in the scraped HTML:1311321. **`prefers-color-scheme` media queries** — `@media (prefers-color-scheme: dark)` blocks with alternate color values1332. **Dark mode class toggles** — `.dark`, `[data-theme="dark"]`, `.theme-dark`, `[color-scheme="dark"]` selectors with alternate colors1343. **CSS custom property overrides** — `:root` variables redefined inside dark mode selectors or media queries1354. **Tailwind dark mode classes** — `dark:bg-*`, `dark:text-*` patterns in HTML136137If dark mode is detected:138- Extract a complete alternate color palette (all the same roles: primary, secondary, accent, neutral, status, surface, border)139- Note which mechanism is used (media query vs class toggle)140- Include section 10 in DESIGN.md and the dark mode block in tailwind-theme.css141- Run accessibility checks for both light and dark palettes142143If the site is **dark-first** (the default/only theme served is dark, like Linear), note this in the DESIGN.md — the main palette IS the dark palette. The tailwind-theme.css should include a comment suggesting where to add light mode overrides if needed, rather than a `prefers-color-scheme: dark` block.144145If no dark mode is detected, skip section 10 and the dark CSS block. Do not fabricate a dark palette.146147## Output Templates148149### DESIGN.md150151```markdown152---153name: "<design-name>"154source: "<url>"155extracted: YYYY-MM-DD156tags:157 - design-system158---159160# <Design Name> Design System161162## 1. Visual Theme & Atmosphere163164One paragraph describing the overall aesthetic: mood, visual language, influences, best suited for what kind of projects.165166## 2. Color Palette167168### Primary169| Name | Hex | Role |170|------|-----|------|171| ... | #... | Brand, CTA |172173### Secondary174| Name | Hex | Role |175|------|-----|------|176| ... | #... | Supporting brand, secondary actions |177178### Accent179| Name | Hex | Role |180|------|-----|------|181| ... | #... | Decorative, gradients, highlights |182183### Neutral184| Name | Hex | Role |185|------|-----|------|186| ... | #... | Text, labels, body |187188### Status189| Name | Hex | Role |190|------|-----|------|191| Success | #... | Success states |192| Warning | #... | Warning states |193| Error | #... | Error states |194195### Surface & Border196| Name | Hex | Role |197|------|-----|------|198| Background | #... | Page background |199| Card | #... | Card/panel background |200| Border | #... | Default border |201202## 3. Typography203204**Font Family:** `<font-name>`, <fallback-stack>205206| Level | Size | Weight | Line Height | Letter Spacing | Notes |207|-------|------|--------|-------------|----------------|-------|208| Display | ...px | ... | ... | ... | |209| Heading | ...px | ... | ... | ... | |210| Subheading | ...px | ... | ... | ... | |211| Body | ...px | ... | ... | ... | |212| Caption | ...px | ... | ... | ... | |213| Code | ...px | ... | ... | ... | Monospace font |214215## 4. Components216217### Buttons218| Variant | Background | Text | Border | Radius | Notes |219|---------|------------|------|--------|--------|-------|220| Primary | ... | ... | ... | ... | |221| Secondary | ... | ... | ... | ... | |222| Ghost | ... | ... | ... | ... | |223| Disabled | ... | ... | ... | ... | |224225### Cards226- Default: background, border, shadow, radius227- Elevated: shadow variant228- Interactive: hover state229230### Form Elements231- Default input: border, radius, padding232- Focus: ring color, ring width233- Error: border color, message color234235### Badges236- Variants observed with colors237238## 5. Layout239240- **Max content width:** ...px241- **Grid:** ... columns, ... gap242- **Container padding:** ...243244## 6. Spacing245246| Token | Value | Mapped to |247|-------|-------|-----------|248| xxs | ...px | Tight inline gaps |249| xs | ...px | Small gaps |250| s | ...px | Default small |251| m | ...px | Medium (anchor) |252| l | ...px | Sections, cards |253| xl | ...px | Large sections |254| xxl | ...px | Page-level |255256## 7. Border Radius257258| Token | Value | Context |259|-------|-------|---------|260| micro | ...px | Subtle rounding |261| button | ...px | Buttons, inputs |262| card | ...px | Cards, panels |263| featured | ...px | Featured elements |264265## 8. Elevation266267| Level | CSS Value | Usage |268|-------|-----------|-------|269| 0 (flat) | none | Default |270| 1 (subtle) | ... | Ambient |271| 2 (standard) | ... | Cards |272| 3 (elevated) | ... | Dropdowns |273| 4 (deep) | ... | Modals |274| Focus | ... | Focus rings |275276## 9. Responsive Behavior277278| Breakpoint | Width | Changes |279|------------|-------|---------|280| sm | ...px | ... |281| md | ...px | ... |282| lg | ...px | ... |283| xl | ...px | ... |284285## 10. Dark Mode (if detected)286287**Mechanism:** `<prefers-color-scheme | class toggle (.dark) | data attribute>`288289### Dark Color Palette290| Token | Light | Dark | Role |291|-------|-------|------|------|292| text | #... | #... | Body text |293| background | #... | #... | Page background |294| primary | #... | #... | Brand, CTA |295| secondary | #... | #... | Supporting brand |296| accent | #... | #... | Decorative |297| muted | #... | #... | Secondary text |298| border | #... | #... | Borders |299| card | #... | #... | Card surfaces |300301<!-- Only include this section if dark mode was detected in the source. Do not fabricate a dark palette. -->302```303304### tailwind-theme.css305306```css307/* Design: <design-name>308 * Source: <url>309 * Extracted: YYYY-MM-DD310 *311 * Import this file in your main stylesheet:312 * @import "./tailwind-theme.css";313 *314 * Or copy the @theme block into your existing src/style.css315 */316317@theme {318 /* COLORS */319 --color-text: #...;320 --color-background: #...;321 --color-primary: #...;322 --color-secondary: #...;323 --color-accent: #...;324 --color-muted: #...;325 --color-error: #...;326 --color-success: #...;327 --color-warning: #...;328 --color-border: #...;329 --color-card: #...;330331 /* FONT FAMILY */332 /* NOTE: Font files need to be sourced and self-hosted as woff2.333 * See: https://gwfh.mranftl.com/fonts334 * Original font detected: <font-name> */335 --font-sans: '<font-name>', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;336337 /* FLUID SPACING */338 --spacing-0: 0;339 --spacing-xxs: clamp(0.25rem, 1vw, 0.5rem);340 --spacing-xs: clamp(0.5rem, 1.5vw, 0.75rem);341 --spacing-s: clamp(0.75rem, 2vw, 1rem);342 --spacing-m: 1.25rem;343 --spacing-l: clamp(1.25rem, 3vw, 2.5rem);344 --spacing-xl: clamp(1.25rem, 5vw, 3.75rem);345 --spacing-xxl: clamp(1.25rem, 10vw, 7.5rem);346347 /* BORDER RADIUS */348 --radius-micro: ...;349 --radius-button: ...;350 --radius-card: ...;351 --radius-featured: ...;352}353354/* Color variants (auto-generated via color-mix in oklch) */355:root {356 --color-primary-light: color-mix(in oklch, var(--color-primary), white 30%);357 --color-primary-dark: color-mix(in oklch, var(--color-primary), black 20%);358 --color-secondary-light: color-mix(in oklch, var(--color-secondary), white 30%);359 --color-secondary-dark: color-mix(in oklch, var(--color-secondary), black 20%);360 --color-accent-light: color-mix(in oklch, var(--color-accent), white 30%);361 --color-accent-dark: color-mix(in oklch, var(--color-accent), black 20%);362}363364/* @font-face — uncomment and update paths after sourcing woff2 files365@font-face {366 font-family: '<font-name>';367 src: url('/fonts/<font-file>-400.woff2') format('woff2');368 font-weight: 400;369 font-style: normal;370 font-display: swap;371}372*/373374/* Dark mode — only include if detected in source375 * Uses prefers-color-scheme by default.376 * If the source uses a class toggle (.dark), replace the @media query377 * with: .dark { ... }378 */379/*380@media (prefers-color-scheme: dark) {381 :root {382 --color-text: #...;383 --color-background: #...;384 --color-primary: #...;385 --color-secondary: #...;386 --color-accent: #...;387 --color-muted: #...;388 --color-error: #...;389 --color-success: #...;390 --color-warning: #...;391 --color-border: #...;392 --color-card: #...;393394 --color-primary-light: color-mix(in oklch, var(--color-primary), white 30%);395 --color-primary-dark: color-mix(in oklch, var(--color-primary), black 20%);396 --color-secondary-light: color-mix(in oklch, var(--color-secondary), white 30%);397 --color-secondary-dark: color-mix(in oklch, var(--color-secondary), black 20%);398 --color-accent-light: color-mix(in oklch, var(--color-accent), white 30%);399 --color-accent-dark: color-mix(in oklch, var(--color-accent), black 20%);400 }401}402*/403```404405### accessibility-report.md406407```markdown408---409design: "<design-name>"410checked: YYYY-MM-DD411---412413# Accessibility Report: <Design Name>414415## Contrast Ratio Results416417| Pair | Ratio | AA Normal | AA Large | AAA Normal | AAA Large |418|------|-------|-----------|----------|------------|-----------|419| background / text | X.X:1 | PASS/FAIL | PASS/FAIL | PASS/FAIL | PASS/FAIL |420| background / muted | X.X:1 | ... | ... | ... | ... |421| primary / white | X.X:1 | ... | ... | ... | ... |422| primary / background | X.X:1 | ... | ... | ... | ... |423| secondary / white | X.X:1 | ... | ... | ... | ... |424| secondary / background | X.X:1 | ... | ... | ... | ... |425| accent / text | X.X:1 | ... | ... | ... | ... |426| accent / background | X.X:1 | ... | ... | ... | ... |427| card / text | X.X:1 | ... | ... | ... | ... |428| card / muted | X.X:1 | ... | ... | ... | ... |429| error / white | X.X:1 | ... | ... | ... | ... |430| success / white | X.X:1 | ... | ... | ... | ... |431| warning / white | X.X:1 | ... | ... | ... | ... |432433## Failures & Suggested Fixes434435<!-- Only include this section if there are failures -->436437| Pair | Current Ratio | Required | Suggestion |438|------|---------------|----------|------------|439| ... | X.X:1 | 4.5:1 (AA) | Darken/lighten <token> to #... |440441## Colorblindness Simulation442443| Pair | Protanopia | Deuteranopia | Tritanopia |444|------|------------|--------------|------------|445| ... | OK / FLAG | OK / FLAG | OK / FLAG |446447<!-- FLAG means the two colors become difficult to distinguish under this type of color vision deficiency -->448449## Summary450451- **Total pairs checked:** N452- **AA pass rate:** N/N (X%)453- **AAA pass rate:** N/N (X%)454- **Critical failures (AA normal text):** N455- **Colorblindness flags:** N pairs flagged456```457458## Accessibility Check Instructions459460When generating the accessibility report, perform these calculations for every surface/text color pair.461462### Contrast Ratios4634641. Convert each hex color to sRGB values (0-1 range): `R = hex/255`, `G = hex/255`, `B = hex/255`4652. Linearize each channel: `channel <= 0.03928 ? channel/12.92 : ((channel+0.055)/1.055)^2.4`4663. Calculate relative luminance: `L = 0.2126*R_lin + 0.7152*G_lin + 0.0722*B_lin`4674. Calculate contrast ratio: `(L_lighter + 0.05) / (L_darker + 0.05)`4685. Compare against thresholds:469 - **AA normal text**: 4.5:1470 - **AA large text** (18px+ bold or 24px+): 3:1471 - **AAA normal text**: 7:1472 - **AAA large text**: 4.5:1473474### Color Pairs to Check475476Generate all meaningful surface/text combinations:477- background / text478- background / muted479- primary / white (#FFFFFF)480- primary / background481- secondary / white (#FFFFFF)482- secondary / background483- accent / text484- accent / background485- card / text486- card / muted487- error / white (#FFFFFF)488- success / white (#FFFFFF)489- warning / white (#FFFFFF) — or warning / text if warning is light490491If additional surface/text pairs are evident from the design (e.g., dark section backgrounds with light text), include those too.492493### Colorblindness Simulation494495For each pair of colors that serve different semantic purposes (e.g., success vs error, primary vs accent):4964971. Apply approximate transformation matrices for protanopia, deuteranopia, and tritanopia4982. Compare the simulated colors — if they appear very similar (approximate visual delta < 3.0), flag the pair4993. This is an approximation — flag as "possible issue" rather than claiming diagnostic precision500501Common problems to watch for:502- Red/green pairs (protanopia, deuteranopia) — success vs error colors503- Blue/purple pairs (tritanopia) — primary vs accent when both are blue-purple range504505### Suggested Fixes506507For each failing contrast pair, suggest the minimum color adjustment needed:508- Calculate what luminance the text/surface color would need to reach the threshold509- Suggest a specific hex value that meets the requirement510- Prefer darkening text or lightening surfaces (maintain the design intent)511512## Library Management513514### Saving to Library5155161. Create the design directory: `mkdir -p ~/.claude/designs/<name>`5172. Write all four files to `~/.claude/designs/<name>/` (DESIGN.md, tailwind-theme.css, accessibility-report.md, preview.png)5183. Read `~/.claude/designs/_index.md`5194. Append a new row with: name, source URL, today's date, count of unique colors extracted, AA pass rate from the accessibility report5205. Write the updated `_index.md`521522If a design with the same name already exists, ask: "A design called '<name>' already exists in the library. Overwrite it?"523524### Copying to Project525526When the user says "use the <name> design" in any project:5275281. Read files from `~/.claude/designs/<name>/`5292. Create `.claude/design/` in the current project: `mkdir -p .claude/design`5303. Copy all files (DESIGN.md, tailwind-theme.css, accessibility-report.md, preview.png)5314. Confirm: "Copied <name> design to `.claude/design/`. The tailwind-theme.css is ready to import into your stylesheet."532533## Next Steps534535After extraction completes, suggest these follow-up actions to the user:5365371. **"Validate the theme"** — invoke `design-system-standards` to check that the generated tailwind-theme.css meets all token conventions (semantic naming, fluid spacing, contrast pairs documented)5382. **"Build components from this design"** — invoke `frontend-design` to create UI components (buttons, cards, forms, nav) that match the extracted design system. It will read `.claude/design/DESIGN.md` automatically if the design was copied to the project.5393. **"Check Tailwind v4 patterns"** — invoke `tailwind-patterns` to verify the `@theme` block follows current v4 best practices (CSS-first config, container queries, modern utility patterns)540541Include these as a bulleted list in your final message to the user after saving the files.542543## See Also544545- **design-auditor** — audit an existing project's design system instead of extracting from a URL546- **design-system-standards** — token conventions and Tailwind v4 patterns these files follow547- **frontend-design** — build production-grade UI components from a DESIGN.md548- **tailwind-patterns** — Tailwind v4 best practices and modern patterns