
Design Spec Extraction
- 7 installs
- 5 repo stars
- Updated February 7, 2026
- cygnusfear/claude-stuff
Extracts JSON design specs from Figma exports, mockups, or screenshots, producing W3C DTCG-compliant tokens and component trees for code generation.
About
This skill turns visual sources like Figma exports or UI screenshots into structured, W3C DTCG-compliant JSON design specifications with component trees. A developer uses it for design-to-code generation and developer handoff.
- W3C DTCG-compliant token output with component trees
- Works from Figma exports, mockups, screenshots, or live captures
Design Spec Extraction by the numbers
- 7 all-time installs (skills.sh)
- Ranked #1,491 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cygnusfear/claude-stuff --skill design-spec-extractionAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 7 |
|---|---|
| repo stars | ★ 5 |
| Last updated | February 7, 2026 |
| Repository | cygnusfear/claude-stuff ↗ |
What it does
Extracts JSON design specs from Figma exports, mockups, or screenshots, producing W3C DTCG-compliant tokens and component trees for code generation.
Files
Design Specification Extraction
Extract comprehensive, production-ready JSON design specifications from visual inputs using a 7-pass serial subtask architecture that ensures complete coverage and cross-validation.
When to Use This Skill
- Extracting design tokens from Figma exports or screenshots
- Converting visual mockups into structured component specifications
- Creating developer handoff documentation from designs
- Generating design system documentation from existing UIs
- Preparing design data for code generation tools
- Analyzing website screenshots for design reverse-engineering
Output Format
The extraction produces JSON following the W3C Design Tokens Community Group (DTCG) 2025.10 format with extensions:
- $version: Schema version
- $source: Metadata (type, dimensions, extraction timestamp)
- tokens: Design tokens (colors, typography, spacing, sizing, shadows, radii)
- components: Hierarchical component tree with bounding boxes
- accessibility: WCAG analysis, contrast issues, semantic structure
- $extensions: Layout, component catalog, confidence scores
CRITICAL: File-Based Architecture
EVERY pass MUST write its output to a JSON file on disk. This is non-negotiable.
Directory Structure
Before starting extraction, create the output directory:
mkdir -p .design-specs/{project-name}Required File Outputs
| Pass | Output File | Description |
|---|---|---|
| 1 | .design-specs/{project}/pass-1-layout.json | Layout and structure |
| 2 | .design-specs/{project}/pass-2-colors.json | Color tokens |
| 3 | .design-specs/{project}/pass-3-typography.json | Typography tokens |
| 4 | .design-specs/{project}/pass-4-components.json | Component tree |
| 5 | .design-specs/{project}/pass-5-spacing.json | Spacing and dimensions |
| 6 | .design-specs/{project}/pass-6-states.json | States and accessibility |
| 7 | .design-specs/{project}/design-spec.json | Final consolidated output |
Why File-Based?
1. Persistence: Each pass result is saved, enabling resumption if interrupted 2. Debugging: Intermediate files allow inspection of each extraction phase 3. Validation: Each JSON file can be validated independently 4. Context Passing: Subtask agents read previous pass files directly 5. Audit Trail: Complete record of extraction process
Multipass Architecture
The extraction uses 7 serial passes. Each pass MUST: 1. Read previous pass JSON files from disk 2. Perform its analysis 3. WRITE its output to the designated JSON file 4. Complete before the next pass begins
Screenshot Input
|
v
[Pass 1] Source Analysis & Layout -----> pass-1-layout.json
|
v
[Pass 2] Color & Visual Style -----> pass-2-colors.json
|
v
[Pass 3] Typography Analysis -----> pass-3-typography.json
|
v
[Pass 4] Component Detection -----> pass-4-components.json
|
v
[Pass 5] Spacing & Dimensions -----> pass-5-spacing.json
|
v
[Pass 6] States & Accessibility -----> pass-6-states.json
|
v
[Pass 7] Consolidation -----> design-spec.json (FINAL)---
Pass 1: Source Analysis & Layout Structure
Objective: Establish foundational understanding of the design source and spatial organization.
Subtask Agent Prompt
You are Pass 1 of a 7-pass design specification extraction system. Your focus: LAYOUT AND STRUCTURE ONLY.
## CRITICAL REQUIREMENT
You MUST write your output to a JSON file. This is mandatory - do not just return JSON in your response.
OUTPUT FILE: `.design-specs/{project}/pass-1-layout.json`
Use the Write tool to save your analysis as valid JSON to this file.
## Input
- Screenshot: [attached image]
## Your Task
Analyze the screenshot and extract:
### 1. Source Metadata
- Identify source type: Figma export, Sketch export, website screenshot, mockup, or wireframe
- Detect dimensions and estimate device class (mobile/tablet/desktop)
- Note any visible design tool artifacts (rulers, grids, selection boxes)
### 2. Layout Type Detection
Determine the primary layout strategy:
- Single-column centered layout
- Multi-column grid (count columns, estimate gutters)
- Sidebar + main content
- Dashboard/admin layout
- Full-bleed/edge-to-edge
### 3. Region Identification
Map the major layout regions with bounding boxes:
- Header (position, height, sticky?)
- Navigation (type: sidebar, topnav, or none)
- Main content area
- Footer
- Any overlays, modals, or floating elements
### 4. Grid System Analysis
- Identify underlying grid (12-column, 4-column, etc.)
- Measure or estimate gutter width
- Note container max-width if visible
## Output Format
Return JSON:
{
"$schema": "pass-1-layout",
"$source": {
"type": "figma-export|website-screenshot|mockup|...",
"dimensions": { "width": N, "height": N, "aspectRatio": "W:H", "deviceClass": "..." },
"confidence": 0.0-1.0
},
"layout": {
"type": "single-column|multi-column|sidebar|...",
"regions": [
{ "name": "header", "bounds": {"x":0,"y":0,"width":W,"height":H}, "sticky": true|false },
{ "name": "navigation", "type": "sidebar|topnav|none", "bounds": {...} },
{ "name": "main", "bounds": {...} },
{ "name": "footer", "bounds": {...}, "present": true|false }
],
"gridSystem": {
"columns": N,
"gutter": "Npx",
"margin": "Npx",
"maxWidth": "Npx"
}
},
"containers": [
{
"id": "container-N",
"bounds": { "x": N, "y": N, "width": N, "height": N },
"layout": "grid|flex|block",
"parent": "parent-id|null",
"childCount": N
}
],
"sections": [
{
"id": "section-N",
"purpose": "hero|features|testimonials|cta|...",
"bounds": {...}
}
]
}
Use pixel values. Be precise with bounds. Note confidence level for uncertain areas.
## FINAL STEP - MANDATORY
Use the Write tool to save this JSON to: `.design-specs/{project}/pass-1-layout.json`
Do NOT proceed without writing the file. Confirm the file was written successfully.---
Pass 2: Color & Visual Style Extraction
Objective: Extract complete color palette with semantic mappings.
Subtask Agent Prompt
You are Pass 2 of a 7-pass design specification extraction system. Your focus: COLOR EXTRACTION.
## CRITICAL REQUIREMENT
You MUST write your output to a JSON file. This is mandatory - do not just return JSON in your response.
OUTPUT FILE: `.design-specs/{project}/pass-2-colors.json`
First, read the Pass 1 output: `.design-specs/{project}/pass-1-layout.json`
Then use the Write tool to save your analysis as valid JSON.
## Input
- Screenshot: [attached image]
- Layout data from Pass 1: Read from `.design-specs/{project}/pass-1-layout.json`
## Your Task
Extract ALL colors visible in this design:
### 1. Background Colors (by region)
- Page background
- Section/card backgrounds
- Header/footer backgrounds
- Modal/overlay backgrounds
- Input field backgrounds
- Button backgrounds (all variants)
### 2. Foreground Colors (text and icons)
- Primary heading text
- Body text
- Secondary/muted text
- Link text (if distinguishable)
- Icon colors
- Placeholder text
### 3. Border Colors
- Card/container borders
- Input field borders (default, focus, error states if visible)
- Divider/separator colors
### 4. Feedback Colors
- Error/danger indicators
- Success indicators
- Warning indicators
- Info indicators
### 5. Interactive Colors
- Primary action color (main CTA buttons)
- Secondary action color
- Hover states (if visible)
- Focus indicators
### Color Value Extraction
For each color, provide:
- Hex value (best estimate: #RRGGBB)
- Where it appears (semantic context)
- Suggested token name following pattern: color.[category].[variant]
## Output Format
Return JSON:
{
"$schema": "pass-2-colors",
"tokens": {
"colors": {
"primitive": {
"blue": {
"500": { "$value": "#3B82F6", "$type": "color", "$description": "Primary blue" },
"600": { "$value": "#2563EB", "$type": "color", "$description": "Primary blue dark" }
},
"gray": {
"50": { "$value": "#F9FAFB", "$type": "color" },
"100": { "$value": "#F3F4F6", "$type": "color" },
"500": { "$value": "#6B7280", "$type": "color" },
"900": { "$value": "#111827", "$type": "color" }
}
},
"semantic": {
"background": {
"default": { "$value": "{colors.primitive.gray.50}", "$type": "color", "$description": "Page background" },
"elevated": { "$value": "#FFFFFF", "$type": "color", "$description": "Card surfaces" }
},
"foreground": {
"default": { "$value": "{colors.primitive.gray.900}", "$type": "color", "$description": "Primary text" },
"muted": { "$value": "{colors.primitive.gray.500}", "$type": "color", "$description": "Secondary text" }
},
"interactive": {
"primary": { "$value": "{colors.primitive.blue.500}", "$type": "color", "$description": "Primary buttons, links" },
"primary-hover": { "$value": "{colors.primitive.blue.600}", "$type": "color", "$description": "Primary hover" }
},
"border": {
"default": { "$value": "{colors.primitive.gray.200}", "$type": "color", "$description": "Subtle borders" },
"focus": { "$value": "{colors.primitive.blue.500}", "$type": "color", "$description": "Focus rings" }
},
"feedback": {
"error": { "$value": "#EF4444", "$type": "color", "$description": "Error states" },
"success": { "$value": "#22C55E", "$type": "color", "$description": "Success states" },
"warning": { "$value": "#F59E0B", "$type": "color", "$description": "Warning states" },
"info": { "$value": "#3B82F6", "$type": "color", "$description": "Info states" }
}
}
}
},
"shadows": [
{
"name": "elevation-sm",
"$type": "shadow",
"$value": {
"offsetX": "0px",
"offsetY": "1px",
"blur": "2px",
"spread": "0px",
"color": "rgba(0,0,0,0.05)"
},
"$description": "Subtle elevation"
}
],
"gradients": [],
"componentColorMap": {
"button-primary": {
"background": "{colors.semantic.interactive.primary}",
"text": "#FFFFFF",
"border": "transparent"
}
}
}
Use DTCG $value and $type syntax. Include $description for AI readability.
## FINAL STEP - MANDATORY
Use the Write tool to save this JSON to: `.design-specs/{project}/pass-2-colors.json`
Do NOT proceed without writing the file. Confirm the file was written successfully.---
Pass 3: Typography Analysis
Objective: Extract complete typography system including fonts, sizes, weights, and text styles.
Subtask Agent Prompt
You are Pass 3 of a 7-pass design specification extraction system. Your focus: TYPOGRAPHY.
## CRITICAL REQUIREMENT
You MUST write your output to a JSON file. This is mandatory - do not just return JSON in your response.
OUTPUT FILE: `.design-specs/{project}/pass-3-typography.json`
First, read previous pass outputs:
- `.design-specs/{project}/pass-1-layout.json`
- `.design-specs/{project}/pass-2-colors.json`
Then use the Write tool to save your analysis as valid JSON.
## Input
- Screenshot: [attached image]
- Layout data from Pass 1: Read from `.design-specs/{project}/pass-1-layout.json`
- Color data from Pass 2: Read from `.design-specs/{project}/pass-2-colors.json`
## Your Task
Extract ALL typography information:
### 1. Font Family Detection
Analyze visible text to identify:
- Primary font family (body text, UI elements)
- Secondary font family (headings, if different)
- Monospace font (code blocks, if present)
- Is it serif, sans-serif, or display?
- Best guess at specific font name
### 2. Text Style Inventory
For EACH distinct text style visible, extract:
**Headings:**
- Display/Hero text (largest)
- H1, H2, H3, etc.
- Card titles
- Section headers
**Body:**
- Body large (lead paragraphs)
- Body regular (standard text)
- Body small (captions)
**UI Text:**
- Button labels
- Form labels
- Input text
- Link text
- Navigation items
- Badge/tag text
For each style, estimate:
- Font size (in px)
- Font weight (100-900 or light/regular/medium/bold)
- Line height (ratio like 1.5 or pixels)
- Letter spacing (normal, tight, wide)
- Text color (reference token from Pass 2)
- Text transform (none, uppercase, capitalize)
### 3. Typographic Hierarchy
- How many distinct size levels are there?
- What is the size scale ratio?
## Output Format
Return JSON:
{
"$schema": "pass-3-typography",
"tokens": {
"typography": {
"fontFamilies": {
"sans": { "$value": ["Inter", "system-ui", "sans-serif"], "$type": "fontFamily", "$description": "Primary font" },
"mono": { "$value": ["JetBrains Mono", "monospace"], "$type": "fontFamily", "$description": "Code font" }
},
"fontWeights": {
"regular": { "$value": 400, "$type": "fontWeight" },
"medium": { "$value": 500, "$type": "fontWeight" },
"semibold": { "$value": 600, "$type": "fontWeight" },
"bold": { "$value": 700, "$type": "fontWeight" }
},
"fontSizes": {
"xs": { "$value": "12px", "$type": "dimension" },
"sm": { "$value": "14px", "$type": "dimension" },
"base": { "$value": "16px", "$type": "dimension" },
"lg": { "$value": "18px", "$type": "dimension" },
"xl": { "$value": "20px", "$type": "dimension" },
"2xl": { "$value": "24px", "$type": "dimension" },
"3xl": { "$value": "30px", "$type": "dimension" },
"4xl": { "$value": "36px", "$type": "dimension" },
"5xl": { "$value": "48px", "$type": "dimension" }
},
"lineHeights": {
"tight": { "$value": 1.25, "$type": "number" },
"normal": { "$value": 1.5, "$type": "number" },
"relaxed": { "$value": 1.75, "$type": "number" }
},
"letterSpacing": {
"tighter": { "$value": "-0.05em", "$type": "dimension" },
"normal": { "$value": "0em", "$type": "dimension" },
"wide": { "$value": "0.05em", "$type": "dimension" }
},
"textStyles": {
"display": {
"$type": "typography",
"$value": {
"fontFamily": "{typography.fontFamilies.sans}",
"fontSize": "{typography.fontSizes.5xl}",
"fontWeight": "{typography.fontWeights.bold}",
"lineHeight": "{typography.lineHeights.tight}",
"letterSpacing": "{typography.letterSpacing.tighter}"
},
"$description": "Hero headlines"
},
"heading-1": {
"$type": "typography",
"$value": {
"fontFamily": "{typography.fontFamilies.sans}",
"fontSize": "{typography.fontSizes.4xl}",
"fontWeight": "{typography.fontWeights.bold}",
"lineHeight": "{typography.lineHeights.tight}"
},
"$description": "Page titles"
},
"heading-2": {
"$type": "typography",
"$value": {
"fontFamily": "{typography.fontFamilies.sans}",
"fontSize": "{typography.fontSizes.2xl}",
"fontWeight": "{typography.fontWeights.semibold}",
"lineHeight": "{typography.lineHeights.tight}"
},
"$description": "Section headings"
},
"body": {
"$type": "typography",
"$value": {
"fontFamily": "{typography.fontFamilies.sans}",
"fontSize": "{typography.fontSizes.base}",
"fontWeight": "{typography.fontWeights.regular}",
"lineHeight": "{typography.lineHeights.normal}"
},
"$description": "Standard body text"
},
"body-small": {
"$type": "typography",
"$value": {
"fontFamily": "{typography.fontFamilies.sans}",
"fontSize": "{typography.fontSizes.sm}",
"fontWeight": "{typography.fontWeights.regular}",
"lineHeight": "{typography.lineHeights.normal}"
},
"$description": "Secondary text, captions"
},
"button-label": {
"$type": "typography",
"$value": {
"fontFamily": "{typography.fontFamilies.sans}",
"fontSize": "{typography.fontSizes.sm}",
"fontWeight": "{typography.fontWeights.medium}",
"lineHeight": "{typography.lineHeights.tight}"
},
"$description": "Button text"
}
}
}
},
"typeScale": {
"ratio": 1.25,
"base": "16px",
"steps": [12, 14, 16, 20, 24, 30, 36, 48]
}
}
Reference tokens using {token.path} syntax per DTCG specification.
## FINAL STEP - MANDATORY
Use the Write tool to save this JSON to: `.design-specs/{project}/pass-3-typography.json`
Do NOT proceed without writing the file. Confirm the file was written successfully.---
Pass 4: Component Detection & Classification
Objective: Build hierarchical component tree with atomic design classification.
Subtask Agent Prompt
You are Pass 4 of a 7-pass design specification extraction system. Your focus: COMPONENT DETECTION.
## CRITICAL REQUIREMENT
You MUST write your output to a JSON file. This is mandatory - do not just return JSON in your response.
OUTPUT FILE: `.design-specs/{project}/pass-4-components.json`
First, read previous pass outputs:
- `.design-specs/{project}/pass-1-layout.json`
- `.design-specs/{project}/pass-2-colors.json`
- `.design-specs/{project}/pass-3-typography.json`
Then use the Write tool to save your analysis as valid JSON.
## Input
- Screenshot: [attached image]
- Layout data from Pass 1: Read from `.design-specs/{project}/pass-1-layout.json`
- Color data from Pass 2: Read from `.design-specs/{project}/pass-2-colors.json`
- Typography data from Pass 3: Read from `.design-specs/{project}/pass-3-typography.json`
## Your Task
Identify and classify ALL UI components:
### 1. Atomic Components (Atoms)
Simple, indivisible elements:
- Buttons (all variants: primary, secondary, icon, ghost)
- Icons (note semantic meaning)
- Inputs (text, password, search)
- Checkboxes, radios, toggles
- Labels and text elements
- Images and avatars
- Badges and tags
- Dividers
### 2. Molecular Components (Molecules)
Simple combinations of atoms:
- Form fields (label + input + helper)
- Search bars
- Navigation items
- Breadcrumbs
- Menu items
- List items
### 3. Organism Components (Organisms)
Complex, distinct UI sections:
- Navigation bars
- Headers
- Cards (all variants)
- Forms
- Tables
- Footers
- Hero sections
### 4. For Each Component, Extract:
- Unique ID (generated)
- Component type name
- Atomic level (atom/molecule/organism)
- Bounding box (x, y, width, height)
- Visual styles (link to tokens where possible)
- Content (text, icons)
- Current state (default, hover, active, disabled)
- Child components (for molecules/organisms)
### 5. Component Catalog
Create definitions for reusable component types:
- Suggested HTML element
- ARIA role
- Props/variants
- Token mappings
## Output Format
Return JSON:
{
"$schema": "pass-4-components",
"components": {
"$root": {
"id": "root",
"type": "Page",
"bounds": {"x":0,"y":0,"width":W,"height":H},
"children": [
{
"id": "header-1",
"type": "Header",
"name": "Main Navigation Header",
"atomicLevel": "organism",
"bounds": {"x":0,"y":0,"width":W,"height":80},
"styles": {
"background": { "color": "#FFFFFF", "tokenRef": "{colors.semantic.background.elevated}" },
"shadow": { "tokenRef": "{shadows.elevation-sm}" }
},
"children": [
{
"id": "logo-1",
"type": "Image",
"atomicLevel": "atom",
"bounds": {"x":24,"y":24,"width":120,"height":32},
"content": { "alt": "Company Logo" }
},
{
"id": "nav-1",
"type": "Navigation",
"atomicLevel": "molecule",
"bounds": {...},
"children": [
{
"id": "nav-item-1",
"type": "NavItem",
"atomicLevel": "atom",
"content": { "text": "Home" },
"states": { "current": "active" }
}
]
},
{
"id": "btn-signin",
"type": "Button",
"atomicLevel": "atom",
"bounds": {...},
"content": { "text": "Sign In" },
"variants": { "variant": "secondary", "size": "md" },
"states": { "current": "default" }
}
]
}
]
},
"catalog": {
"Button": {
"name": "Button",
"category": "action",
"atomicLevel": "atom",
"htmlElement": "button",
"ariaRole": "button",
"variants": [
{ "name": "variant", "values": ["primary", "secondary", "ghost", "destructive"] },
{ "name": "size", "values": ["sm", "md", "lg"] }
],
"tokens": {
"background": "{colors.semantic.interactive.primary}",
"color": "#FFFFFF",
"borderRadius": "{radii.md}",
"paddingX": "{spacing.4}",
"paddingY": "{spacing.2}"
},
"instances": ["btn-signin", "btn-cta-1"]
},
"Card": {
"name": "Card",
"category": "layout",
"atomicLevel": "organism",
"htmlElement": "article",
"ariaRole": "article",
"variants": [
{ "name": "variant", "values": ["default", "elevated", "outlined"] }
],
"tokens": {
"background": "{colors.semantic.background.elevated}",
"borderRadius": "{radii.lg}",
"shadow": "{shadows.elevation-md}",
"padding": "{spacing.6}"
},
"instances": ["card-1", "card-2"]
}
}
},
"statistics": {
"totalComponents": N,
"byType": {
"Button": N,
"Card": N,
"Input": N
},
"byAtomicLevel": {
"atom": N,
"molecule": N,
"organism": N
}
}
}
Be exhaustive. Every visible interactive or content element must be cataloged.
## FINAL STEP - MANDATORY
Use the Write tool to save this JSON to: `.design-specs/{project}/pass-4-components.json`
Do NOT proceed without writing the file. Confirm the file was written successfully.---
Pass 5: Spacing & Dimensions
Objective: Extract spacing scale, sizing tokens, borders, and radii.
Subtask Agent Prompt
You are Pass 5 of a 7-pass design specification extraction system. Your focus: SPACING AND DIMENSIONS.
## CRITICAL REQUIREMENT
You MUST write your output to a JSON file. This is mandatory - do not just return JSON in your response.
OUTPUT FILE: `.design-specs/{project}/pass-5-spacing.json`
First, read previous pass outputs:
- `.design-specs/{project}/pass-1-layout.json`
- `.design-specs/{project}/pass-4-components.json`
Then use the Write tool to save your analysis as valid JSON.
## Input
- Screenshot: [attached image]
- Layout data from Pass 1: Read from `.design-specs/{project}/pass-1-layout.json`
- Component data from Pass 4: Read from `.design-specs/{project}/pass-4-components.json`
## Your Task
Measure and systematize ALL spacing and dimension values:
### 1. Spacing Scale
Analyze gaps between elements to find the base spacing unit:
- Measure space between text and container edges (padding)
- Measure space between stacked elements (stack spacing)
- Measure space between inline elements (inline spacing)
- Measure grid/flex gaps
Identify the spacing scale:
- What is the base unit? (4px, 8px typical)
- What multipliers are used? (1x, 2x, 3x, 4x, 6x, 8x, 12x, 16x)
### 2. Component Sizing
Extract size patterns:
- Button heights (small, medium, large)
- Input field heights
- Icon sizes
- Avatar sizes
- Container max-widths
### 3. Border Properties
For each border type:
- Border width (1px, 2px, etc.)
- Border radius values (small, medium, large, full/circular)
### 4. Map to Component Styles
Link spacing values to specific components from Pass 4
## Output Format
Return JSON:
{
"$schema": "pass-5-spacing",
"tokens": {
"spacing": {
"scale": {
"0": { "$value": "0px", "$type": "dimension" },
"1": { "$value": "4px", "$type": "dimension", "$description": "Minimal spacing, icon gaps" },
"2": { "$value": "8px", "$type": "dimension", "$description": "Tight spacing, inline elements" },
"3": { "$value": "12px", "$type": "dimension" },
"4": { "$value": "16px", "$type": "dimension", "$description": "Default component padding" },
"5": { "$value": "20px", "$type": "dimension" },
"6": { "$value": "24px", "$type": "dimension", "$description": "Card padding, form gaps" },
"8": { "$value": "32px", "$type": "dimension", "$description": "Section spacing" },
"10": { "$value": "40px", "$type": "dimension" },
"12": { "$value": "48px", "$type": "dimension", "$description": "Large section gaps" },
"16": { "$value": "64px", "$type": "dimension", "$description": "Hero section padding" }
},
"semantic": {
"inset": {
"card": { "$value": "{spacing.scale.6}", "$type": "dimension", "$description": "Card internal padding" },
"section": { "$value": "{spacing.scale.8}", "$type": "dimension", "$description": "Section padding" }
},
"stack": {
"tight": { "$value": "{spacing.scale.2}", "$type": "dimension", "$description": "Compact vertical spacing" },
"default": { "$value": "{spacing.scale.4}", "$type": "dimension", "$description": "Standard vertical spacing" }
},
"gap": {
"grid": { "$value": "{spacing.scale.6}", "$type": "dimension", "$description": "Card grid gap" }
}
}
},
"sizing": {
"component": {
"button-sm": { "$value": "32px", "$type": "dimension" },
"button-md": { "$value": "40px", "$type": "dimension" },
"button-lg": { "$value": "48px", "$type": "dimension" },
"input-md": { "$value": "40px", "$type": "dimension" }
},
"icon": {
"sm": { "$value": "16px", "$type": "dimension" },
"md": { "$value": "20px", "$type": "dimension" },
"lg": { "$value": "24px", "$type": "dimension" }
},
"avatar": {
"sm": { "$value": "32px", "$type": "dimension" },
"md": { "$value": "40px", "$type": "dimension" },
"lg": { "$value": "48px", "$type": "dimension" }
}
},
"radii": {
"none": { "$value": "0px", "$type": "dimension" },
"sm": { "$value": "4px", "$type": "dimension" },
"md": { "$value": "8px", "$type": "dimension", "$description": "Default for cards, buttons" },
"lg": { "$value": "12px", "$type": "dimension" },
"xl": { "$value": "16px", "$type": "dimension" },
"full": { "$value": "9999px", "$type": "dimension", "$description": "Pills, avatars" }
},
"borders": {
"width": {
"thin": { "$value": "1px", "$type": "dimension", "$description": "Default borders" },
"medium": { "$value": "2px", "$type": "dimension", "$description": "Focus rings, emphasis" }
}
},
"container": {
"maxWidth": {
"sm": { "$value": "640px", "$type": "dimension" },
"md": { "$value": "768px", "$type": "dimension" },
"lg": { "$value": "1024px", "$type": "dimension" },
"xl": { "$value": "1280px", "$type": "dimension" }
}
}
},
"componentSpacing": {
"button": {
"paddingX": "{spacing.scale.4}",
"paddingY": "{spacing.scale.2}",
"gap": "{spacing.scale.2}"
},
"card": {
"padding": "{spacing.scale.6}",
"gap": "{spacing.scale.4}"
},
"input": {
"paddingX": "{spacing.scale.3}",
"paddingY": "{spacing.scale.2}"
}
}
}
Detect patterns and express them. Use 4px or 8px base unit convention.
## FINAL STEP - MANDATORY
Use the Write tool to save this JSON to: `.design-specs/{project}/pass-5-spacing.json`
Do NOT proceed without writing the file. Confirm the file was written successfully.---
Pass 6: Interactive States & Accessibility
Objective: Analyze interactive states and accessibility compliance.
Subtask Agent Prompt
You are Pass 6 of a 7-pass design specification extraction system. Your focus: STATES AND ACCESSIBILITY.
## CRITICAL REQUIREMENT
You MUST write your output to a JSON file. This is mandatory - do not just return JSON in your response.
OUTPUT FILE: `.design-specs/{project}/pass-6-states.json`
First, read previous pass outputs:
- `.design-specs/{project}/pass-2-colors.json`
- `.design-specs/{project}/pass-4-components.json`
Then use the Write tool to save your analysis as valid JSON.
## Input
- Screenshot: [attached image]
- Component data from Pass 4: Read from `.design-specs/{project}/pass-4-components.json`
- Color data from Pass 2: Read from `.design-specs/{project}/pass-2-colors.json`
## Your Task
### 1. Interactive States (infer from visual cues)
For each interactive component type, define state variations:
- Default/rest state
- Hover state (if visible or inferable - darken 5-10%)
- Active/pressed state (darken 10-15%, reduce shadow)
- Focus state (focus ring, 2px outline)
- Disabled state (opacity 0.5-0.6, muted colors)
- Loading state
State Changes:
- Color changes
- Shadow changes
- Border changes
- Opacity changes
- Transform effects
### 2. Accessibility Analysis
**Contrast Ratios:**
For each text-on-background combination:
- Calculate/estimate contrast ratio
- Check against WCAG AA (4.5:1 normal, 3:1 large)
- Check against WCAG AAA (7:1 normal, 4.5:1 large)
- Flag any failures
**Color Accessibility:**
- Red/green combinations (protanopia/deuteranopia)
- Blue/yellow combinations (tritanopia)
- Information conveyed by color alone
### 3. Semantic Hierarchy
- What should be the h1? (single per page)
- Heading hierarchy (h1 > h2 > h3, no skips)
- Landmark regions (header, nav, main, aside, footer)
### 4. Interactive Element Analysis
For each interactive element:
- Does it have visible text or clear label?
- What ARIA label might be needed?
- Is the clickable area sufficient (44x44px touch target)?
- Is there a visible focus indicator?
## Output Format
Return JSON:
{
"$schema": "pass-6-states",
"states": {
"button": {
"primary": {
"default": {
"background": "{colors.semantic.interactive.primary}",
"text": "#FFFFFF",
"border": "transparent",
"shadow": "{shadows.elevation-sm}"
},
"hover": {
"background": "{colors.semantic.interactive.primary-hover}",
"shadow": "{shadows.elevation-md}",
"$description": "Darken 10%, increase elevation"
},
"active": {
"background": "{colors.primitive.blue.700}",
"shadow": "none",
"transform": "scale(0.98)"
},
"focus": {
"outline": "2px solid {colors.semantic.interactive.primary}",
"outlineOffset": "2px"
},
"disabled": {
"background": "{colors.primitive.gray.300}",
"text": "{colors.primitive.gray.500}",
"cursor": "not-allowed",
"opacity": 0.6
}
}
},
"input": {
"default": {
"border": "{colors.semantic.border.default}",
"background": "#FFFFFF"
},
"hover": {
"border": "{colors.primitive.gray.400}"
},
"focus": {
"border": "{colors.semantic.border.focus}",
"outline": "2px solid {colors.semantic.interactive.primary}",
"outlineOffset": "-1px"
},
"error": {
"border": "{colors.semantic.feedback.error}",
"background": "#FEF2F2"
},
"disabled": {
"background": "{colors.primitive.gray.100}",
"opacity": 0.6
}
}
},
"transitions": {
"fast": {
"$type": "transition",
"$value": {
"duration": "150ms",
"timingFunction": [0.4, 0, 0.2, 1]
},
"$description": "Micro-interactions, hovers"
},
"normal": {
"$type": "transition",
"$value": {
"duration": "200ms",
"timingFunction": [0.4, 0, 0.2, 1]
},
"$description": "Standard transitions"
},
"slow": {
"$type": "transition",
"$value": {
"duration": "300ms",
"timingFunction": [0.4, 0, 0.2, 1]
},
"$description": "Page transitions, modals"
}
},
"accessibility": {
"contrastIssues": [
{
"element": "components.btn-secondary",
"foreground": "#9CA3AF",
"background": "#FFFFFF",
"ratio": 2.8,
"required": 4.5,
"wcagLevel": "AA",
"passes": false,
"recommendation": "Darken text to #6B7280 for 4.5:1 ratio"
}
],
"colorBlindnessIssues": [
{
"type": "deuteranopia",
"affectedElements": ["error-state", "success-state"],
"recommendation": "Add icons alongside color indicators"
}
],
"semanticHierarchy": {
"headings": [
{ "level": 1, "text": "Welcome to Our Platform", "componentRef": "hero-title" },
{ "level": 2, "text": "Features", "componentRef": "features-heading" }
],
"landmarks": [
{ "role": "banner", "componentRef": "header-1" },
{ "role": "navigation", "componentRef": "nav-1" },
{ "role": "main", "componentRef": "main-content" },
{ "role": "contentinfo", "componentRef": "footer-1" }
]
},
"touchTargets": {
"minimumSize": "44px",
"violations": [
{
"componentRef": "icon-btn-close",
"actualSize": "32x32",
"recommendation": "Increase to 44x44px minimum"
}
]
},
"interactiveElements": [
{
"componentRef": "icon-btn-menu",
"type": "IconButton",
"hasVisibleLabel": false,
"suggestedAriaLabel": "Open menu"
}
]
}
}
Infer states from visual context. When states are not visible, provide reasonable defaults.
## FINAL STEP - MANDATORY
Use the Write tool to save this JSON to: `.design-specs/{project}/pass-6-states.json`
Do NOT proceed without writing the file. Confirm the file was written successfully.---
Pass 7: Consolidation & Validation
Objective: Merge all passes into final spec, validate completeness, resolve conflicts.
Subtask Agent Prompt
You are Pass 7 (FINAL) of a 7-pass design specification extraction system. Your focus: CONSOLIDATION.
## CRITICAL REQUIREMENT
You MUST write your final output to a JSON file. This is mandatory - do not just return JSON in your response.
OUTPUT FILE: `.design-specs/{project}/design-spec.json`
First, read ALL previous pass outputs:
- `.design-specs/{project}/pass-1-layout.json`
- `.design-specs/{project}/pass-2-colors.json`
- `.design-specs/{project}/pass-3-typography.json`
- `.design-specs/{project}/pass-4-components.json`
- `.design-specs/{project}/pass-5-spacing.json`
- `.design-specs/{project}/pass-6-states.json`
Then use the Write tool to save your consolidated analysis as valid JSON.
## Input
- All previous pass outputs (Passes 1-6) - Read from the JSON files listed above
## Your Task
Create the final, validated design specification:
### 1. Merge Token Groups
Combine all token extractions into unified structure:
- Resolve any duplicate tokens
- Ensure consistent naming
- Verify all references resolve correctly
### 2. Validate Component Tree
- Check all components have required fields
- Verify parent-child relationships
- Ensure style references link to valid tokens
- Check bounding boxes don't overlap incorrectly
### 3. Cross-Reference Validation
- Every color used in components should exist in tokens
- Every font used should be in typography tokens
- Every spacing value should map to spacing scale
### 4. Quality Scoring
Assign confidence scores:
- Overall extraction confidence
- Per-section confidence
- Flag areas of uncertainty
### 5. Generate Recommendations
Based on analysis:
- Accessibility fixes needed
- Token consolidation opportunities
- Component naming suggestions
## Final Output Format
Return complete JSON matching the schema at references/design-tokens-schema.json:
{
"$schema": "https://design-tokens.org/schema.json",
"$version": "1.0.0",
"$source": {
"type": "<figma-export|website-screenshot|mockup>",
"dimensions": { "width": N, "height": N, "aspectRatio": "W:H", "deviceClass": "..." },
"extractedAt": "<ISO timestamp>",
"confidence": 0.0-1.0
},
"tokens": {
"colors": {
"primitive": {...},
"semantic": {...}
},
"typography": {
"fontFamilies": {...},
"fontWeights": {...},
"fontSizes": {...},
"lineHeights": {...},
"letterSpacing": {...},
"textStyles": {...}
},
"spacing": {
"scale": {...},
"semantic": {...}
},
"sizing": {...},
"radii": {...},
"borders": {...},
"shadows": {...},
"transitions": {...}
},
"components": {
"$root": {...},
"catalog": {...}
},
"layout": {
"type": "...",
"regions": [...],
"gridSystem": {...}
},
"accessibility": {
"contrastIssues": [...],
"colorBlindnessIssues": [...],
"semanticHierarchy": {...},
"touchTargets": {...}
},
"semantics": {
"designPatterns": [
{ "pattern": "Hero Section", "confidence": 0.95, "instances": [...] },
{ "pattern": "Card Grid", "confidence": 0.9, "instances": [...] }
],
"contentTypes": ["marketing", "e-commerce"],
"brandPersonality": {
"traits": ["modern", "professional"],
"tone": "friendly"
}
},
"$extensions": {
"com.design-spec.extraction": {
"passesCompleted": 7,
"confidence": {
"overall": 0.85,
"layout": 0.9,
"colors": 0.95,
"typography": 0.8,
"components": 0.85,
"spacing": 0.9,
"accessibility": 0.75
},
"recommendations": [
"Increase contrast on secondary buttons",
"Add aria-labels to icon-only buttons"
]
}
}
}
The final file MUST be valid JSON. Validate all references resolve correctly.
## FINAL STEP - MANDATORY
Use the Write tool to save this JSON to: `.design-specs/{project}/design-spec.json`
This is the FINAL deliverable. Do NOT proceed without writing the file. Confirm the file was written successfully.---
Execution Instructions
IMPORTANT: File-Based Workflow
Before launching any pass:
1. Create the output directory:
mkdir -p .design-specs/{project-name}2. Each pass MUST write to its designated file - Subtask agents will use the Write tool 3. Verify file exists before proceeding to next pass - Read the file to confirm
Using Task Subtask Agents
Execute each pass as a dedicated subtask agent. Replace `{project}` with actual project name in ALL prompts.
// Step 0: Create directory
mkdir -p .design-specs/my-design
// Step 1: Pass 1 - Layout
Task({
prompt: "[Pass 1 prompt - agent MUST write to .design-specs/my-design/pass-1-layout.json]",
model: "sonnet"
});
// VERIFY: Read .design-specs/my-design/pass-1-layout.json exists
// Step 2: Pass 2 - Colors
Task({
prompt: "[Pass 2 prompt - agent reads pass-1, MUST write to pass-2-colors.json]",
model: "sonnet"
});
// VERIFY: Read .design-specs/my-design/pass-2-colors.json exists
// ... Continue for Passes 3-6, verifying each file exists ...
// Step 7: Pass 7 - Final Consolidation
Task({
prompt: "[Pass 7 prompt - agent reads ALL pass files, MUST write to design-spec.json]",
model: "opus" // Use Opus for complex consolidation
});
// VERIFY: Read .design-specs/my-design/design-spec.json existsVerification After Each Pass
After each subtask completes, verify the output file was written:
// After Pass N completes:
Read(".design-specs/{project}/pass-N-{type}.json")
// If file doesn't exist or is invalid JSON, re-run the passModel Recommendations
- Passes 1-6: Use Sonnet for focused visual analysis tasks
- Pass 7 (Consolidation): Use Opus for complex synthesis and validation
Output Delivery
After extraction, provide:
1. Summary: Key statistics and findings 2. Complete JSON: Full spec matching schema 3. Recommendations: Suggested improvements 4. Confidence Report: Areas of uncertainty
Example Summary Output
## Design Spec Extraction Complete
### Statistics
- Colors extracted: 24 (8 primitive, 16 semantic)
- Typography styles: 12
- Components detected: 47 (18 atoms, 15 molecules, 14 organisms)
- Spacing values: 11
- Accessibility issues: 2 (contrast)
### Key Findings
- Layout: 12-column grid with 24px gutters
- Primary font: Inter (sans-serif)
- Design patterns: Hero, Card Grid, Feature List, CTA
- Device class: Desktop (1440px width)
### Accessibility Notes
- 2 contrast failures requiring attention
- Recommend adding icons to status indicators
### Confidence
- Overall: 0.89
- Colors: 0.95
- Typography: 0.88
- Components: 0.85
- Spacing: 0.90
[Full JSON spec attached]---
Best Practices
For Accurate Extraction
1. Use highest resolution source available 2. Prefer Figma exports over screenshots when possible 3. Ensure design shows actual content (not lorem ipsum) 4. Include multiple states if analyzing interactions 5. Provide context about target platform
For AI-Readable Output
1. Use semantic naming (intent over appearance) 2. Include $description explaining when/how to use tokens 3. Document token relationships and pairings 4. Show which tokens apply to which components 5. Include usage examples for complex tokens
For Processing Efficiency
1. Start with layout pass to establish structure 2. Use component IDs consistently across passes 3. Pass only relevant previous results to each subtask 4. Validate incrementally, not just at end
---
Reference Files
references/design-tokens-schema.json- Complete JSON Schema for output validationreferences/extraction-patterns.md- Detailed patterns for visual analysis
Load these references as needed during extraction for detailed guidance on specific analysis tasks.
Schema Compliance
Output follows W3C Design Tokens Community Group format (2025.10):
- All tokens use
$value,$type,$descriptionproperties - Token references use
{group.token}syntax - Extensions use reverse domain notation in
$extensions
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://design-spec-extraction/schema/v1",
"title": "Design Specification Extraction Schema",
"description": "JSON schema for extracted design specifications from screenshots, based on W3C DTCG format with extensions for component extraction",
"type": "object",
"required": ["$schema", "$version", "$source", "tokens", "components"],
"properties": {
"$schema": {
"type": "string",
"description": "Schema identifier"
},
"$version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+$",
"description": "Specification version (semver)"
},
"$source": {
"$ref": "#/definitions/sourceMetadata"
},
"tokens": {
"$ref": "#/definitions/tokenGroups"
},
"components": {
"$ref": "#/definitions/componentTree"
},
"layout": {
"$ref": "#/definitions/layoutStructure"
},
"accessibility": {
"$ref": "#/definitions/accessibilityReport"
},
"semantics": {
"$ref": "#/definitions/semanticsAnalysis"
},
"$extensions": {
"type": "object",
"description": "Vendor-specific extensions using reverse domain notation",
"properties": {
"com.design-spec.extraction": {
"type": "object",
"properties": {
"passesCompleted": { "type": "integer" },
"confidence": {
"type": "object",
"properties": {
"overall": { "type": "number", "minimum": 0, "maximum": 1 },
"layout": { "type": "number", "minimum": 0, "maximum": 1 },
"colors": { "type": "number", "minimum": 0, "maximum": 1 },
"typography": { "type": "number", "minimum": 0, "maximum": 1 },
"components": { "type": "number", "minimum": 0, "maximum": 1 },
"spacing": { "type": "number", "minimum": 0, "maximum": 1 },
"accessibility": { "type": "number", "minimum": 0, "maximum": 1 }
}
},
"recommendations": {
"type": "array",
"items": { "type": "string" }
}
}
}
}
}
},
"definitions": {
"sourceMetadata": {
"type": "object",
"required": ["type", "dimensions", "extractedAt"],
"properties": {
"type": {
"type": "string",
"enum": ["figma-export", "sketch-export", "xd-export", "website-screenshot", "mockup", "wireframe", "unknown"],
"description": "Type of source image"
},
"dimensions": {
"type": "object",
"required": ["width", "height"],
"properties": {
"width": { "type": "integer", "minimum": 1 },
"height": { "type": "integer", "minimum": 1 },
"aspectRatio": { "type": "string" },
"deviceClass": {
"type": "string",
"enum": ["mobile", "tablet", "desktop", "widescreen", "unknown"]
},
"density": { "type": "number" }
}
},
"extractedAt": {
"type": "string",
"format": "date-time"
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"url": {
"type": "string",
"format": "uri"
},
"filename": {
"type": "string"
}
}
},
"tokenGroups": {
"type": "object",
"description": "Design tokens organized by category following DTCG structure",
"properties": {
"colors": { "$ref": "#/definitions/colorTokenGroup" },
"typography": { "$ref": "#/definitions/typographyTokenGroup" },
"spacing": { "$ref": "#/definitions/spacingTokenGroup" },
"sizing": { "$ref": "#/definitions/sizingTokenGroup" },
"radii": { "$ref": "#/definitions/dimensionTokenGroup" },
"borders": { "$ref": "#/definitions/borderTokenGroup" },
"shadows": { "$ref": "#/definitions/shadowTokenGroup" },
"transitions": { "$ref": "#/definitions/transitionTokenGroup" }
}
},
"colorTokenGroup": {
"type": "object",
"properties": {
"$type": { "const": "color" },
"primitive": {
"type": "object",
"description": "Raw color palette values",
"additionalProperties": {
"type": "object",
"additionalProperties": { "$ref": "#/definitions/colorToken" }
}
},
"semantic": {
"type": "object",
"description": "Purpose-driven color tokens",
"properties": {
"background": { "type": "object", "additionalProperties": { "$ref": "#/definitions/colorToken" } },
"foreground": { "type": "object", "additionalProperties": { "$ref": "#/definitions/colorToken" } },
"border": { "type": "object", "additionalProperties": { "$ref": "#/definitions/colorToken" } },
"interactive": { "type": "object", "additionalProperties": { "$ref": "#/definitions/colorToken" } },
"feedback": { "type": "object", "additionalProperties": { "$ref": "#/definitions/colorToken" } }
}
}
}
},
"colorToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"oneOf": [
{ "type": "string" },
{
"type": "object",
"properties": {
"colorSpace": { "type": "string", "enum": ["srgb", "display-p3", "oklch", "oklab", "hsl"] },
"components": { "type": "array", "items": { "type": "number" } },
"alpha": { "type": "number", "minimum": 0, "maximum": 1 }
}
}
]
},
"$type": { "const": "color" },
"$description": { "type": "string" },
"$deprecated": {
"oneOf": [
{ "type": "boolean" },
{ "type": "string" }
]
},
"$extensions": {
"type": "object",
"properties": {
"com.design-spec.extraction": {
"type": "object",
"properties": {
"frequency": { "type": "integer" },
"usageContexts": { "type": "array", "items": { "type": "string" } },
"pairedColors": { "type": "array", "items": { "type": "string" } },
"wcagContrast": { "type": "object" }
}
}
}
}
}
},
"typographyTokenGroup": {
"type": "object",
"properties": {
"$type": { "const": "typography" },
"fontFamilies": {
"type": "object",
"additionalProperties": { "$ref": "#/definitions/fontFamilyToken" }
},
"fontWeights": {
"type": "object",
"additionalProperties": { "$ref": "#/definitions/fontWeightToken" }
},
"fontSizes": {
"type": "object",
"additionalProperties": { "$ref": "#/definitions/dimensionToken" }
},
"lineHeights": {
"type": "object",
"additionalProperties": { "$ref": "#/definitions/numberOrDimensionToken" }
},
"letterSpacing": {
"type": "object",
"additionalProperties": { "$ref": "#/definitions/dimensionToken" }
},
"textStyles": {
"type": "object",
"additionalProperties": { "$ref": "#/definitions/typographyToken" }
}
}
},
"fontFamilyToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"oneOf": [
{ "type": "string" },
{ "type": "array", "items": { "type": "string" } }
]
},
"$type": { "const": "fontFamily" },
"$description": { "type": "string" }
}
},
"fontWeightToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"oneOf": [
{ "type": "integer", "minimum": 1, "maximum": 1000 },
{ "type": "string", "enum": ["thin", "hairline", "extra-light", "ultra-light", "light", "normal", "regular", "book", "medium", "semi-bold", "demi-bold", "bold", "extra-bold", "ultra-bold", "black", "heavy", "extra-black", "ultra-black"] }
]
},
"$type": { "const": "fontWeight" },
"$description": { "type": "string" }
}
},
"typographyToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"type": "object",
"properties": {
"fontFamily": { "type": "string" },
"fontSize": { "type": "string" },
"fontWeight": {
"oneOf": [
{ "type": "integer" },
{ "type": "string" }
]
},
"lineHeight": {
"oneOf": [
{ "type": "number" },
{ "type": "string" }
]
},
"letterSpacing": { "type": "string" },
"textTransform": { "type": "string", "enum": ["none", "uppercase", "lowercase", "capitalize"] },
"textDecoration": { "type": "string" }
}
},
"$type": { "const": "typography" },
"$description": { "type": "string" },
"$extensions": {
"type": "object",
"properties": {
"com.design-spec.extraction": {
"type": "object",
"properties": {
"semanticRole": {
"type": "string",
"enum": ["display", "heading-1", "heading-2", "heading-3", "heading-4", "heading-5", "heading-6", "body", "body-large", "body-small", "caption", "label", "button", "link", "code", "quote"]
},
"sampleText": { "type": "string" }
}
}
}
}
}
},
"spacingTokenGroup": {
"type": "object",
"properties": {
"$type": { "const": "dimension" },
"scale": {
"type": "object",
"additionalProperties": { "$ref": "#/definitions/dimensionToken" }
},
"semantic": {
"type": "object",
"properties": {
"inset": { "type": "object", "additionalProperties": { "$ref": "#/definitions/dimensionToken" } },
"stack": { "type": "object", "additionalProperties": { "$ref": "#/definitions/dimensionToken" } },
"inline": { "type": "object", "additionalProperties": { "$ref": "#/definitions/dimensionToken" } },
"gap": { "type": "object", "additionalProperties": { "$ref": "#/definitions/dimensionToken" } }
}
}
}
},
"sizingTokenGroup": {
"type": "object",
"properties": {
"$type": { "const": "dimension" },
"component": { "type": "object", "additionalProperties": { "$ref": "#/definitions/dimensionToken" } },
"icon": { "type": "object", "additionalProperties": { "$ref": "#/definitions/dimensionToken" } },
"avatar": { "type": "object", "additionalProperties": { "$ref": "#/definitions/dimensionToken" } },
"container": { "type": "object", "additionalProperties": { "$ref": "#/definitions/dimensionToken" } }
}
},
"dimensionTokenGroup": {
"type": "object",
"properties": {
"$type": { "const": "dimension" }
},
"additionalProperties": { "$ref": "#/definitions/dimensionToken" }
},
"dimensionToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"type": "string",
"pattern": "^-?\\d+(\\.\\d+)?(px|rem|em|%|vw|vh|vmin|vmax)?$"
},
"$type": { "const": "dimension" },
"$description": { "type": "string" }
}
},
"numberOrDimensionToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"oneOf": [
{ "type": "number" },
{ "type": "string" }
]
},
"$type": { "type": "string" },
"$description": { "type": "string" }
}
},
"borderTokenGroup": {
"type": "object",
"properties": {
"width": { "type": "object", "additionalProperties": { "$ref": "#/definitions/dimensionToken" } },
"style": { "type": "object", "additionalProperties": { "$ref": "#/definitions/strokeStyleToken" } },
"composite": { "type": "object", "additionalProperties": { "$ref": "#/definitions/borderToken" } }
}
},
"strokeStyleToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"oneOf": [
{ "type": "string", "enum": ["solid", "dashed", "dotted", "double", "groove", "ridge", "outset", "inset", "none"] },
{
"type": "object",
"properties": {
"dashArray": { "type": "array", "items": { "type": "string" } },
"lineCap": { "type": "string", "enum": ["round", "butt", "square"] }
}
}
]
},
"$type": { "const": "strokeStyle" },
"$description": { "type": "string" }
}
},
"borderToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"type": "object",
"properties": {
"color": { "type": "string" },
"width": { "type": "string" },
"style": { "type": "string" }
},
"required": ["color", "width", "style"]
},
"$type": { "const": "border" },
"$description": { "type": "string" }
}
},
"shadowTokenGroup": {
"type": "object",
"properties": {
"$type": { "const": "shadow" },
"elevation": {
"type": "object",
"additionalProperties": { "$ref": "#/definitions/shadowToken" }
}
},
"additionalProperties": { "$ref": "#/definitions/shadowToken" }
},
"shadowToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"oneOf": [
{ "$ref": "#/definitions/shadowValue" },
{ "type": "array", "items": { "$ref": "#/definitions/shadowValue" } }
]
},
"$type": { "const": "shadow" },
"$description": { "type": "string" }
}
},
"shadowValue": {
"type": "object",
"required": ["color", "offsetX", "offsetY", "blur"],
"properties": {
"color": { "type": "string" },
"offsetX": { "type": "string" },
"offsetY": { "type": "string" },
"blur": { "type": "string" },
"spread": { "type": "string" },
"inset": { "type": "boolean" }
}
},
"transitionTokenGroup": {
"type": "object",
"properties": {
"duration": { "type": "object", "additionalProperties": { "$ref": "#/definitions/durationToken" } },
"easing": { "type": "object", "additionalProperties": { "$ref": "#/definitions/cubicBezierToken" } }
},
"additionalProperties": { "$ref": "#/definitions/transitionToken" }
},
"durationToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": { "type": "string", "pattern": "^\\d+(\\.\\d+)?(ms|s)$" },
"$type": { "const": "duration" },
"$description": { "type": "string" }
}
},
"cubicBezierToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"type": "array",
"items": { "type": "number" },
"minItems": 4,
"maxItems": 4
},
"$type": { "const": "cubicBezier" },
"$description": { "type": "string" }
}
},
"transitionToken": {
"type": "object",
"required": ["$value"],
"properties": {
"$value": {
"type": "object",
"properties": {
"duration": { "type": "string" },
"delay": { "type": "string" },
"timingFunction": {
"oneOf": [
{ "type": "array", "items": { "type": "number" }, "minItems": 4, "maxItems": 4 },
{ "type": "string" }
]
}
},
"required": ["duration", "timingFunction"]
},
"$type": { "const": "transition" },
"$description": { "type": "string" }
}
},
"componentTree": {
"type": "object",
"required": ["$root"],
"properties": {
"$root": { "$ref": "#/definitions/componentNode" },
"catalog": {
"type": "object",
"additionalProperties": { "$ref": "#/definitions/componentDefinition" }
}
}
},
"componentNode": {
"type": "object",
"required": ["id", "type", "bounds"],
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"type": {
"type": "string",
"enum": [
"root", "Page", "frame", "container", "section", "Header", "Footer", "sidebar", "main",
"Navigation", "NavItem", "nav-item", "menu", "menu-item", "breadcrumb",
"Card", "list", "list-item", "grid", "grid-item",
"Button", "icon-button", "link", "Link", "tab", "tab-panel",
"Input", "textarea", "select", "Select", "checkbox", "Checkbox", "radio", "Radio", "switch", "Switch", "Toggle", "slider", "date-picker",
"form", "form-field", "FormField", "label", "Label",
"text", "Text", "heading", "Heading", "paragraph", "Paragraph", "caption", "Caption", "badge", "Badge", "tag", "Tag", "chip", "Chip",
"Image", "image", "avatar", "Avatar", "icon", "Icon", "logo", "Logo",
"modal", "Modal", "dialog", "Dialog", "drawer", "Drawer", "popover", "Popover", "tooltip", "Tooltip", "dropdown", "Dropdown",
"table", "Table", "table-header", "table-row", "table-cell",
"divider", "Divider", "spacer", "Spacer",
"progress", "Progress", "spinner", "Spinner", "skeleton", "Skeleton",
"alert", "Alert", "toast", "Toast", "notification", "Notification", "banner", "Banner",
"pagination", "Pagination", "stepper", "Stepper",
"accordion", "Accordion", "accordion-item", "collapse", "Collapse",
"carousel", "Carousel", "slide",
"video", "Video", "audio", "Audio", "embed",
"map", "Map", "chart", "Chart",
"hero", "Hero", "cta", "CTA", "feature", "Feature",
"custom", "unknown"
]
},
"atomicLevel": {
"type": "string",
"enum": ["atom", "molecule", "organism", "template"]
},
"bounds": { "$ref": "#/definitions/boundingBox" },
"styles": { "$ref": "#/definitions/componentStyles" },
"content": { "$ref": "#/definitions/componentContent" },
"states": { "$ref": "#/definitions/componentStates" },
"variants": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"children": {
"type": "array",
"items": { "$ref": "#/definitions/componentNode" }
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
}
},
"boundingBox": {
"type": "object",
"required": ["x", "y", "width", "height"],
"properties": {
"x": { "type": "number" },
"y": { "type": "number" },
"width": { "type": "number", "minimum": 0 },
"height": { "type": "number", "minimum": 0 },
"rotation": { "type": "number" }
}
},
"componentStyles": {
"type": "object",
"properties": {
"layout": {
"type": "object",
"properties": {
"display": { "type": "string" },
"flexDirection": { "type": "string" },
"justifyContent": { "type": "string" },
"alignItems": { "type": "string" },
"gap": { "type": "string" },
"padding": { "type": "string" },
"margin": { "type": "string" }
}
},
"background": {
"type": "object",
"properties": {
"color": { "type": "string" },
"tokenRef": { "type": "string" },
"gradient": { "type": "string" },
"image": { "type": "string" }
}
},
"border": {
"type": "object",
"properties": {
"width": { "type": "string" },
"style": { "type": "string" },
"color": { "type": "string" },
"radius": { "type": "string" },
"tokenRef": { "type": "string" }
}
},
"shadow": {
"type": "object",
"properties": {
"value": { "type": "string" },
"tokenRef": { "type": "string" }
}
},
"typography": {
"type": "object",
"properties": {
"fontFamily": { "type": "string" },
"fontSize": { "type": "string" },
"fontWeight": { "type": "string" },
"lineHeight": { "type": "string" },
"color": { "type": "string" },
"tokenRef": { "type": "string" }
}
}
}
},
"componentContent": {
"type": "object",
"properties": {
"text": { "type": "string" },
"placeholder": { "type": "string" },
"alt": { "type": "string" },
"icon": { "type": "string" },
"src": { "type": "string" },
"href": { "type": "string" }
}
},
"componentStates": {
"type": "object",
"properties": {
"current": {
"type": "string",
"enum": ["default", "hover", "active", "focus", "disabled", "error", "success", "loading", "selected"]
},
"available": {
"type": "array",
"items": { "type": "string" }
}
}
},
"componentDefinition": {
"type": "object",
"required": ["name", "category"],
"properties": {
"name": { "type": "string" },
"category": {
"type": "string",
"enum": ["action", "input", "display", "navigation", "feedback", "layout", "media", "data"]
},
"atomicLevel": {
"type": "string",
"enum": ["atom", "molecule", "organism"]
},
"description": { "type": "string" },
"htmlElement": { "type": "string" },
"ariaRole": { "type": "string" },
"variants": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"values": { "type": "array", "items": { "type": "string" } }
}
}
},
"props": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"type": { "type": "string" },
"required": { "type": "boolean" },
"default": {}
}
}
},
"tokens": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"instances": {
"type": "array",
"items": { "type": "string" }
}
}
},
"layoutStructure": {
"type": "object",
"required": ["type", "regions"],
"properties": {
"type": {
"type": "string",
"enum": ["single-column", "multi-column", "grid", "masonry", "flex", "sidebar", "absolute", "mixed"]
},
"regions": {
"type": "array",
"items": { "$ref": "#/definitions/layoutRegion" }
},
"gridSystem": {
"type": "object",
"properties": {
"columns": { "type": "integer" },
"gutter": { "type": "string" },
"margin": { "type": "string" },
"maxWidth": { "type": "string" },
"breakpoints": { "type": "object" }
}
},
"contentFlow": {
"type": "string",
"enum": ["ltr", "rtl"],
"default": "ltr"
}
}
},
"layoutRegion": {
"type": "object",
"required": ["name", "bounds"],
"properties": {
"name": {
"type": "string",
"enum": ["header", "navigation", "sidebar", "main", "footer", "modal", "drawer", "hero", "content", "aside"]
},
"type": { "type": "string" },
"bounds": { "$ref": "#/definitions/boundingBox" },
"landmark": { "type": "string" },
"sticky": { "type": "boolean" },
"present": { "type": "boolean" },
"zIndex": { "type": "integer" }
}
},
"accessibilityReport": {
"type": "object",
"properties": {
"contrastIssues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"element": { "type": "string" },
"componentRef": { "type": "string" },
"foreground": { "type": "string" },
"background": { "type": "string" },
"ratio": { "type": "number" },
"required": { "type": "number" },
"wcagLevel": { "type": "string", "enum": ["AA", "AAA"] },
"passes": { "type": "boolean" },
"textSize": { "type": "string", "enum": ["normal", "large"] },
"recommendation": { "type": "string" }
}
}
},
"colorBlindnessIssues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["protanopia", "deuteranopia", "tritanopia"] },
"affectedElements": { "type": "array", "items": { "type": "string" } },
"recommendation": { "type": "string" }
}
}
},
"semanticHierarchy": {
"type": "object",
"properties": {
"headings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"level": { "type": "integer", "minimum": 1, "maximum": 6 },
"text": { "type": "string" },
"componentRef": { "type": "string" }
}
}
},
"landmarks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"role": { "type": "string", "enum": ["banner", "navigation", "main", "complementary", "contentinfo", "search", "form", "region"] },
"componentRef": { "type": "string" }
}
}
}
}
},
"touchTargets": {
"type": "object",
"properties": {
"minimumSize": { "type": "string" },
"violations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"componentRef": { "type": "string" },
"actualSize": { "type": "string" },
"recommendation": { "type": "string" }
}
}
}
}
},
"interactiveElements": {
"type": "array",
"items": {
"type": "object",
"properties": {
"componentRef": { "type": "string" },
"type": { "type": "string" },
"hasVisibleLabel": { "type": "boolean" },
"suggestedAriaLabel": { "type": "string" },
"focusVisible": { "type": "boolean" }
}
}
}
}
},
"semanticsAnalysis": {
"type": "object",
"properties": {
"designPatterns": {
"type": "array",
"items": {
"type": "object",
"properties": {
"pattern": { "type": "string" },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
"instances": { "type": "array", "items": { "type": "string" } },
"description": { "type": "string" }
}
}
},
"contentTypes": {
"type": "array",
"items": {
"type": "string",
"enum": ["marketing", "e-commerce", "dashboard", "form", "article", "gallery", "profile", "settings", "navigation", "authentication"]
}
},
"brandPersonality": {
"type": "object",
"properties": {
"traits": { "type": "array", "items": { "type": "string" } },
"tone": { "type": "string" },
"industry": { "type": "string" }
}
}
}
}
}
}
Design Specification Extraction Patterns
This reference provides comprehensive patterns for extracting design specifications from visual sources (screenshots, Figma exports, mockups).
Table of Contents
1. Visual Analysis Fundamentals 2. Layout Detection Patterns 3. Component Detection Patterns 4. Color Extraction Patterns 5. Typography Extraction Patterns 6. Spacing and Dimensions Patterns 7. State Inference Rules 8. Accessibility Analysis Patterns 9. Component Classification Taxonomy 10. Confidence Scoring 11. Output Format Conversions
---
Visual Analysis Fundamentals
Image Preprocessing Considerations
Before extraction, assess the source image:
1. Resolution Assessment
- High resolution (2x/3x): Scale coordinates by density factor
- Low resolution: Note reduced confidence in fine details
- Variable density: Normalize to 1x for consistent measurements
2. Source Type Identification
| Source Type | Characteristics | Confidence Impact |
|---|---|---|
| Figma Export | Clean vectors, precise measurements | High |
| Website Screenshot | May include browser chrome | Medium-High |
| Mockup/Wireframe | Lower fidelity, focus on structure | Medium |
| Mobile Screenshot | Status bar, navigation gestures | Medium |
| Photo of Screen | Perspective issues, artifacts | Low |
3. Content Area Detection
- Identify actual design area vs. surrounding artifacts
- Browser chrome, device frames should be excluded from analysis
- Status bars, navigation bars may or may not be part of design
Hierarchical Decomposition Strategy
Extract structure using depth-first analysis:
1. Identify major regions (header, main, sidebar, footer)
2. Within each region, identify containers/sections
3. Within containers, identify individual components
4. Within components, identify atomic elements
5. Validate parent-child containment relationships---
Layout Detection Patterns
Viewport Classification
| Aspect Ratio | Width Range | Classification |
|---|---|---|
| < 0.6 | < 480px | Mobile Portrait |
| 0.6 - 0.8 | 480-768px | Mobile Landscape / Small Tablet |
| 0.8 - 1.2 | 768-1024px | Tablet |
| > 1.2 | > 1024px | Desktop |
Primary Layout Types
Single Column Layout
Visual Indicators:
- Content centered horizontally
- Elements stacked vertically
- Consistent left/right margins
- Maximum width constraint visible
Multi-Column Grid
Visual Indicators:
- Visible column divisions (2, 3, 4, or 12-column)
- Consistent gutter spacing between columns
- Elements aligned to grid lines
- Responsive breakpoint hints
Sidebar + Main Layout
Visual Indicators:
- Narrow fixed-width column on left or right
- Wider flexible main content area
- Clear visual separation (border, background, or space)
- Navigation elements typically in sidebar
Region Detection Heuristics
Header Detection:
- Located in top 15% of viewport
- Full width or near-full width
- Contains logo (top-left corner image)
- Contains navigation elements
- Typically 60-100px height
Navigation Detection:
- Sidebar: Left or right edge, narrow width (200-300px), full height
- Top nav: Within header region, horizontal list of links
- Contains repeated similar elements (nav items)
Main Content Detection:
- Largest contiguous content area
- Excludes header, footer, sidebar regions
- Contains primary content blocks
Footer Detection:
- Located in bottom 10-15% of viewport
- Full width
- Often darker background than main content
- Contains links, copyright text, social icons
Layout Regions Reference
| Region | Visual Cues | Typical Elements |
|---|---|---|
| Header | Top position, full width, distinct background | Logo, navigation, search, auth buttons |
| Navigation | Horizontal or vertical menu structure | Links, icons, dropdowns |
| Hero | Large top section, prominent heading | Headline, CTA, image/illustration |
| Main | Central content area | Primary page content |
| Sidebar | Narrow column, secondary info | Filters, navigation, widgets |
| Footer | Bottom position, darker background | Links, copyright, social icons |
Grid System Detection
Step 1: Identify Container Width
- Look for consistent outer margins
- Note if content is centered or full-bleed
- Measure visual max-width
Step 2: Count Columns
- Align visible elements to potential column lines
- Look for patterns: 12-col (Bootstrap), 4-col, 6-col
- Check responsive behavior hints
Step 3: Measure Gutters
- Find consistent horizontal gaps between elements
- Common values: 16px, 20px, 24px, 32px
Grid Calculation:
Column Width = (Container Width - (Gaps * (Columns - 1))) / Columns
Gutter Width = Gap between adjacent columnsFlexbox vs Grid Indicators
Flexbox Indicators:
- Items of varying widths in same row
- Items wrapping to next line
- Single-axis alignment dominance
- Unequal distribution of remaining space
Grid Indicators:
- Strict column alignment across rows
- Items spanning multiple columns
- Both row and column tracks visible
- Consistent cell sizing
---
Component Detection Patterns
Component Detection Decision Tree
Is it interactive?
├── Yes → Does it trigger an action?
│ ├── Yes → Button/Link/Icon Button
│ └── No → Does it accept input?
│ ├── Yes → Input/Select/Checkbox/Radio
│ └── No → Toggle/Switch
└── No → Is it a container?
├── Yes → Card/Modal/Drawer/Section
└── No → Is it text?
├── Yes → Heading/Paragraph/Label/Caption
└── No → Is it visual?
├── Yes → Image/Icon/Avatar/Badge
└── No → Divider/SpacerBounding Box Detection Heuristics
Visual Boundary Detection:
- Look for clear edges (borders, shadows, background changes)
- Identify whitespace gaps that separate elements
- Group elements by visual proximity (Gestalt proximity principle)
- Consider alignment lines as grouping indicators
Common Component Signatures
| Component Type | Visual Indicators |
|---|---|
| Button | Rounded rectangle, consistent height, centered text, possible icon |
| Card | Shadow, border-radius, contained content group, consistent padding |
| Input | Bordered rectangle, placeholder text, label above/beside |
| Navigation | Horizontal or vertical list, evenly spaced items, highlight state |
| Avatar | Circular or rounded-square image, typically 24-64px |
| Badge | Small pill shape, high-contrast colors, near other elements |
| Modal | Centered overlay, shadow, close button, dimmed background |
| Dropdown | Text + chevron icon, bounded width |
| Table | Grid of cells, header row, alternating row colors |
Button Detection
Visual Characteristics:
- Distinct background color (different from surroundings)
- Rounded corners (border-radius > 0)
- Centered text
- Horizontal padding visible
- Consistent height (32-48px typical)
- Often contains icon + text or text only
Button Variants:
| Variant | Background | Border | Text |
|---|---|---|---|
| Primary | Solid brand color | None | White/inverse |
| Secondary | Transparent/light | 1-2px solid | Brand color |
| Tertiary | Transparent | None | Brand color |
| Ghost | Transparent | None | Muted color |
| Destructive | Red/danger color | None | White |
Input Field Detection
Visual Characteristics:
- Rectangular shape
- Border visible (light gray typical)
- Background (white or very light)
- Placeholder text (muted color)
- Height: 36-44px typical
- Often has label above
Input Variants:
- Text input: Single line, cursor position
- Textarea: Multi-line, taller
- Select: Dropdown arrow icon on right
- Checkbox: Square, small (16-20px)
- Radio: Circle, small (16-20px)
- Toggle/Switch: Pill shape, binary state indicator
Card Detection
Visual Characteristics:
- Distinct container boundary
- Background different from page
- Shadow or border creating separation
- Contains multiple child elements
- Consistent padding around content
- Often in repeating grid patterns
Card Anatomy: 1. Image area (top, optional) 2. Header/title 3. Body content 4. Footer/actions (optional)
Container Recognition Patterns
Flex Container Detection:
- Children aligned in single direction (row or column)
- Consistent gap between children
- Children may have different sizes
- Look for: justify-content and align-items behavior
Grid Container Detection:
- Elements aligned in both rows and columns
- Consistent column widths or repeated patterns
- Gaps between grid cells
- Often used for: card grids, image galleries, data tables
---
Color Extraction Patterns
Systematic Color Sampling
Background Colors (Priority Order)
1. Page background (outermost) 2. Section backgrounds (cards, modals) 3. Component backgrounds (buttons, inputs) 4. Hover/active state backgrounds
Foreground Colors (Priority Order)
1. Primary text (headings, body) 2. Secondary text (captions, metadata) 3. Muted/disabled text 4. Link colors (default, hover, visited) 5. Error/success/warning text
Border and Divider Colors
- Card borders
- Input field borders (default, focus, error)
- Divider lines
- Table borders
Color Categorization System
Primary Palette:
- Primary: Main brand color, CTAs
- Secondary: Supporting brand color
- Accent: Highlight, emphasis
Neutral Palette:
- Background colors (lightest to darkest)
- Text colors (body, muted, heading)
- Border colors
- Divider colors
Semantic Colors:
- Success: Typically green spectrum (hue 100-140)
- Warning: Typically yellow/orange spectrum (hue 30-50)
- Error/Danger: Typically red spectrum (hue 0-10, 350-360)
- Info: Typically blue spectrum (hue 200-220)
Color Semantic Mapping Table
| Visual Context | Semantic Token Name | Usage Description |
|---|---|---|
| Page background | color.background.default | Main page backdrop |
| Card surface | color.background.elevated | Raised containers |
| Primary button | color.interactive.primary | Main CTAs |
| Button hover | color.interactive.primary-hover | Primary button hover state |
| Body text | color.foreground.default | Standard text content |
| Muted text | color.foreground.muted | Secondary information |
| Error indicator | color.feedback.error | Error states and messages |
| Success indicator | color.feedback.success | Success confirmations |
| Warning indicator | color.feedback.warning | Warning notices |
| Input border | color.border.input | Form field boundaries |
| Focus ring | color.border.focus | Keyboard focus indicators |
Color Extraction Algorithm
1. Sample colors from each detected component
2. Cluster similar colors (within delta-E threshold of ~3)
3. Identify dominant colors by frequency
4. Assign semantic meaning based on usage context:
- Large area backgrounds -> background tokens
- Text on backgrounds -> foreground tokens
- Small interactive elements -> interactive tokens
- Borders and lines -> border tokensColor Palette Extraction Steps
1. Extract all unique colors 2. Group similar colors (within deltaE 2.0) 3. Sort each group by lightness 4. Create scale (50, 100, 200, ... 900) 5. Identify semantic roles
---
Typography Extraction Patterns
Font Family Detection
Visual Analysis:
- Serif vs Sans-serif (look for feet/stems)
- Monospace (equal character width)
- Display/decorative fonts (headings only)
Common Font Signatures:
| Font | Visual Identifier |
|---|---|
| Inter | Clean sans-serif, slight humanist curves |
| Roboto | Geometric with open counters |
| SF Pro | Apple system font, compact |
| Helvetica | Classic, uniform stroke width |
| Georgia | Serif with modern proportions |
| Source Code Pro | Monospace, distinct 0 and O |
Common Font Stacks:
- System: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto
- Sans-serif: Inter, Helvetica Neue, Arial
- Serif: Georgia, "Times New Roman", serif
- Mono: "SF Mono", Monaco, Consolas, monospace
Type Scale Detection
Common Scale Ratios:
| Ratio | Name | Example Scale |
|---|---|---|
| 1.067 | Minor Second | 16, 17, 18, 19, 21 |
| 1.125 | Major Second | 16, 18, 20, 23, 26 |
| 1.200 | Minor Third | 16, 19, 23, 28, 33 |
| 1.250 | Major Third | 16, 20, 25, 31, 39 |
| 1.333 | Perfect Fourth | 16, 21, 28, 38, 50 |
| 1.414 | Augmented Fourth | 16, 23, 32, 45, 64 |
| 1.500 | Perfect Fifth | 16, 24, 36, 54, 81 |
Detection Algorithm: 1. Collect all font sizes 2. Sort ascending 3. Calculate ratios between consecutive sizes 4. Find most common ratio 5. Match to standard scale
Text Style Hierarchy
Typical Hierarchy:
| Level | Usage | Size Range | Weight |
|---|---|---|---|
| Display | Hero headlines | 48-72px | Bold/Black |
| H1 | Page titles | 32-48px | Bold |
| H2 | Section headers | 24-32px | Semibold |
| H3 | Subsection headers | 20-24px | Semibold |
| H4 | Card titles | 18-20px | Medium |
| Body Large | Lead paragraphs | 18-20px | Regular |
| Body | Standard text | 14-16px | Regular |
| Body Small | Captions | 12-14px | Regular |
| Caption | Metadata | 10-12px | Regular |
| Label | Form labels | 12-14px | Medium |
| Button | Button text | 14-16px | Medium/Semibold |
Line Height Patterns
| Use Case | Line Height |
|---|---|
| Headings | 1.1 - 1.3 |
| Body text | 1.4 - 1.6 |
| UI elements | 1.0 - 1.2 |
| Long-form reading | 1.6 - 1.8 |
Font Weight Detection
- Thin/Light: 100-300 (barely visible stroke)
- Normal/Regular: 400 (standard body text)
- Medium: 500 (slightly emphasized)
- Semibold: 600 (subheadings)
- Bold: 700 (headings, emphasis)
- Black: 800-900 (display text)
---
Spacing and Dimensions Patterns
Base Unit Detection Algorithm
1. Measure all gaps between elements 2. Find Greatest Common Divisor (GCD) 3. Validate GCD is reasonable (4px or 8px typical) 4. Build scale from base unit
Common Base Units:
- 4px system: 4, 8, 12, 16, 20, 24, 32, 40, 48, 64
- 8px system: 8, 16, 24, 32, 40, 48, 64, 80, 96
Spacing Scale Reference
4px Base Scale (Tailwind-style):
0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80, 968px Base Scale:
0, 8, 16, 24, 32, 48, 64, 96, 128Padding vs Margin Detection
Padding (Internal Spacing):
- Distance from container edge to content
- Consistent within component types
- Often symmetric (same top/bottom, left/right)
Margin (External Spacing):
- Distance between components
- May vary by context
- Often uses larger values than padding
Component Spacing Patterns
| Component | Padding X | Padding Y | Gap |
|---|---|---|---|
| Button SM | 12px | 6px | 8px |
| Button MD | 16px | 8px | 8px |
| Button LG | 24px | 12px | 12px |
| Card | 24px | 24px | 16px |
| Input | 12px | 8px | - |
| Modal | 32px | 24px | 24px |
Spacing Relationship Map
Component Internal Padding: spacing-sm to spacing-md (8-16px)
Component Gap (siblings): spacing-md to spacing-lg (16-24px)
Section Gap: spacing-xl to spacing-2xl (32-64px)
Page Margins: spacing-lg to spacing-xl (24-48px)Dimension Tokens
Container Widths:
- Full width: 100% of viewport
- Constrained: Common max-widths (1024px, 1200px, 1440px)
- Content width: Typical 600-800px for readability
Component Sizing:
| Component | SM | MD | LG |
|---|---|---|---|
| Button Height | 32px | 40px | 48px |
| Input Height | 32px | 40px | 48px |
| Icon Size | 16px | 20px | 24px |
| Avatar | 32px | 40px | 48px |
---
State Inference Rules
Interactive States
| State | Visual Indicators |
|---|---|
| Default | Base appearance |
| Hover | Slight color change, cursor pointer |
| Active/Pressed | Darker shade, slight scale reduction |
| Focus | Visible ring/outline, increased contrast |
| Disabled | Muted colors, reduced opacity |
| Loading | Spinner, skeleton, pulsing |
| Error | Red borders/text, error icon |
| Success | Green indicators, checkmark |
Button States Inference
From Static Screenshot:
- Default: Base styling visible
- Hover: Infer +10% darker background, elevated shadow
- Active: Infer +20% darker, no shadow, slight scale down
- Focus: Infer focus ring (2px outline, offset 2px)
- Disabled: Infer reduced opacity (0.5-0.6), muted colors
When Multiple States Visible:
- Different buttons may show different states
- Look for visual variations in similar components
- Catalog each variation as a state
Input States Inference
- Default: Standard border color
- Hover: Slightly darker border
- Focus: Primary color border, focus ring
- Filled: Content present, potentially different label position
- Error: Red/danger border, error message below
- Disabled: Gray background, muted text
Interactive Feedback Patterns
| State | Background | Border | Shadow | Transform |
|---|---|---|---|---|
| Default | Base | Base | Level 1 | none |
| Hover | Darken 5% | Darken 10% | Level 2 | none |
| Active | Darken 10% | Darken 15% | none | scale(0.98) |
| Focus | Base | Primary | Base | none |
| Disabled | Gray 200 | Gray 300 | none | none |
---
Accessibility Analysis Patterns
Contrast Ratio Requirements
WCAG 2.1 Requirements:
| Level | Normal Text | Large Text | UI Components |
|---|---|---|---|
| AA | 4.5:1 | 3:1 | 3:1 |
| AAA | 7:1 | 4.5:1 | 4.5:1 |
Large text defined as: >= 18pt (24px) or >= 14pt bold (19px)
Contrast Calculation Formula:
L = 0.2126 * R + 0.7152 * G + 0.0722 * B (relative luminance)
Contrast Ratio = (L1 + 0.05) / (L2 + 0.05)
where L1 > L2Touch Target Analysis
Minimum Size Requirements:
| Standard | Size |
|---|---|
| WCAG 2.5.5 (AAA) | 44x44 CSS pixels |
| WCAG 2.5.8 (AA) | 24x24 CSS pixels with spacing |
| iOS HIG | 44x44 points |
| Material Design | 48x48dp (with 8dp spacing minimum) |
Detection Approach: 1. Identify interactive elements (buttons, links, inputs) 2. Measure bounding box dimensions 3. Check spacing between adjacent touch targets 4. Flag elements below minimum thresholds
Semantic Structure Analysis
Expected Semantic Roles:
| Element | Role | Usage |
|---|---|---|
| Navigation | nav, role="navigation" | Main navigation |
| Main Content | main, role="main" | Primary content |
| Header | header, role="banner" | Page header |
| Footer | footer, role="contentinfo" | Page footer |
| Sidebar | aside, role="complementary" | Secondary content |
| Search | role="search" | Search functionality |
| Form | form, role="form" | Form container |
| Button | button, role="button" | Interactive action |
| Link | a, role="link" | Navigation link |
Color Blindness Considerations
Types and Prevalence:
- Protanopia (red-blind): 1% of males
- Deuteranopia (green-blind): 1% of males
- Tritanopia (blue-blind): <0.01%
Critical Rule: Color must not be the only visual means of conveying information (WCAG 1.4.1)
Check For:
- Information conveyed only by color
- Error states without icon/text
- Status without additional indicators
- Charts/graphs without patterns
---
Component Classification Taxonomy
Atomic Components (Atoms)
Text Elements:
heading: h1-h6 equivalentparagraph: Body text blockscaption: Small descriptive textlabel: Form labels, UI labelsbadge: Small status indicatorstag: Categorization chips
Interactive Elements:
button: Primary action triggericon-button: Icon-only buttonlink: Navigation linkcheckbox: Binary selectionradio: Single selection from groupswitch: Toggle controlinput: Text input fieldtextarea: Multi-line inputselect: Dropdown selectionslider: Range selection
Media Elements:
image: Static imagesavatar: User/entity imagesicon: Symbolic graphicslogo: Brand marksvideo: Video players
Feedback Elements:
spinner: Loading indicatorprogress: Progress barskeleton: Loading placeholderalert: Inline feedbacktoast: Temporary notification
Molecular Components (Molecules)
form-field: Label + input + helpersearch-bar: Input + icon + buttonnav-item: Icon + text + indicatorbreadcrumb: Path navigationmenu-item: Icon + text + shortcutlist-item: Content + actions
Organism Components (Organisms)
Layout Components:
header: Page headernavigation: Nav containersidebar: Side navigationfooter: Page footercard: Bounded content groupmodal: Dialog overlaydrawer: Slide-in panel
Content Components:
hero: Hero sectionfeature-section: Feature listtestimonial: User testimonialpricing-table: Pricing comparisondata-table: Tabular dataform: Form container
Component Naming Conventions
Hierarchical Naming:
{category}-{type}-{variant}
Examples:
- button-primary
- button-secondary
- button-ghost
- input-text
- input-password
- card-product
- card-user
- nav-horizontal
- nav-verticalState-Aware Naming:
{component}-{state}
Examples:
- button-hover
- button-active
- button-disabled
- input-focus
- input-error
- card-selected---
Confidence Scoring
Per-Category Confidence Levels
High Confidence (0.8-1.0):
- Clear, high-resolution input
- Standard design patterns
- Consistent styling throughout
- Multiple examples of each element type
Medium Confidence (0.5-0.79):
- Some ambiguity in element boundaries
- Mix of standard and custom patterns
- Minor inconsistencies
- Limited examples of some elements
Low Confidence (0.0-0.49):
- Low resolution or artifacts
- Highly custom/unusual design
- Significant inconsistencies
- Minimal examples to pattern match
Confidence Factors (Weighted)
| Factor | Weight | Description |
|---|---|---|
| Resolution | 0.20 | Image quality and clarity |
| Consistency | 0.25 | Design system coherence |
| Coverage | 0.20 | % of elements successfully identified |
| Pattern Match | 0.20 | Alignment with known patterns |
| Completeness | 0.15 | All token categories populated |
Confidence Reporting Format
{
"$extensions": {
"com.design-spec.confidence": {
"overall": 0.85,
"byCategory": {
"layout": 0.9,
"components": 0.8,
"colors": 0.95,
"typography": 0.75,
"spacing": 0.85,
"states": 0.7
},
"notes": [
"Typography font family inferred from visual characteristics",
"Button hover states not visible, using standard inference"
]
}
}
}---
Output Format Conversions
CSS Custom Properties
:root {
/* Colors */
--color-primary: #3B82F6;
--color-secondary: #6366F1;
--color-text-primary: #1F2937;
/* Typography */
--font-family-primary: 'Inter', system-ui, sans-serif;
--font-size-base: 16px;
--font-weight-medium: 500;
--line-height-normal: 1.5;
/* Spacing */
--spacing-1: 4px;
--spacing-2: 8px;
--spacing-4: 16px;
/* Border Radius */
--radius-md: 8px;
/* Shadows */
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
}SCSS Variables
// Colors
$color-primary: #3B82F6;
$color-secondary: #6366F1;
// Typography
$font-family-primary: 'Inter', system-ui, sans-serif;
$font-sizes: (
'xs': 12px,
'sm': 14px,
'base': 16px,
'lg': 18px
);
// Spacing
$spacing-scale: (
1: 4px,
2: 8px,
3: 12px,
4: 16px
);Tailwind Config
module.exports = {
theme: {
colors: {
primary: {
DEFAULT: '#3B82F6',
dark: '#2563EB',
light: '#60A5FA'
}
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif']
},
fontSize: {
'xs': '12px',
'sm': '14px',
'base': '16px'
},
spacing: {
'1': '4px',
'2': '8px',
'4': '16px'
},
borderRadius: {
'sm': '4px',
'md': '8px',
'lg': '12px'
}
}
}Style Dictionary Format
{
"color": {
"primary": { "value": "#3B82F6" },
"secondary": { "value": "#6366F1" }
},
"font": {
"family": {
"primary": { "value": "Inter, system-ui, sans-serif" }
},
"size": {
"base": { "value": "16px" }
}
}
}Figma Variables JSON
{
"colors/primary": {
"type": "COLOR",
"value": "#3B82F6",
"scopes": ["ALL_SCOPES"]
},
"spacing/md": {
"type": "FLOAT",
"value": 16,
"scopes": ["GAP", "WIDTH_HEIGHT"]
}
}---
Validation Checklist
Token Extraction
- [ ] All colors captured with hex/RGB values
- [ ] Font families identified accurately
- [ ] Font sizes mapped to scale
- [ ] Spacing values follow consistent scale
- [ ] Border radii captured
- [ ] Shadow values captured (offset, blur, spread, color)
Component Tree
- [ ] All visible components identified
- [ ] Correct parent-child relationships
- [ ] Appropriate atomic level assigned
- [ ] Bounding boxes accurate
- [ ] States and variants noted
Accessibility
- [ ] Contrast ratios checked
- [ ] Heading hierarchy validated
- [ ] Interactive elements identified
- [ ] Focus indicators noted
- [ ] Semantic landmarks mapped
Layout
- [ ] Grid system detected
- [ ] Major regions identified
- [ ] Spacing patterns recognized
- [ ] Responsive hints captured
---
Best Practices Summary
For Accurate Extraction
1. Start with layout - Understand the structure before details 2. Use reference points - Identify repeating patterns as calibration 3. Cross-validate - Compare findings across passes 4. Document uncertainty - Mark low-confidence areas 5. Preserve relationships - Maintain token references, don't flatten
For AI-Readable Output
1. Semantic naming - Use intent-based names (color.interactive.primary) 2. Rich descriptions - Add $description explaining when/how to use 3. Explicit relationships - Document token pairings and dependencies 4. Component mapping - Show which tokens apply to which components 5. Usage examples - Include context for complex tokens
For Developer Handoff
1. Complete tokens - Include all variations needed for implementation 2. Clear hierarchy - Organize logically (primitive -> semantic -> component) 3. State coverage - Document all interactive states 4. Responsive values - Note breakpoint variations if detected 5. Accessibility notes - Include WCAG compliance information