Design Context Extract
Extract the "Design DNA" from existing applications — colors, typography, spacing, and component patterns — and output as structured tokens.
/ork:design-context-extract /tmp/screenshot.png
/ork:design-context-extract /tmp/recording.mp4
/ork:design-context-extract https://example.com
/ork:design-context-extract current project
Pipeline
Input (screenshot/URL/project)
│
▼
┌──────────────────────────────┐
│ Capture │ Screenshot or fetch HTML/CSS
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ Extract │ Stitch extract_design_context
│ │ OR multimodal analysis (fallback)
│ → Colors (hex + oklch) │
│ → Typography (families, scale)│
│ → Spacing (padding, gaps) │
│ → Components (structure) │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ Output │ Choose format:
│ → design-tokens.json (W3C) │
│ → @theme (Tailwind v4) │
│ → tokens.css (CSS variables) │
│ → Markdown spec │
└──────────────────────────────┘
Step 0: Detect Input and Context
INPUT = ""
TaskCreate(subject="Extract design context: {INPUT}", description="Extract design DNA", activeForm="Extracting design from {INPUT}")
TaskCreate(subject="Detect input type and context", activeForm="Detecting input type")
TaskCreate(subject="Capture source material", activeForm="Capturing source")
TaskCreate(subject="Extract design tokens", activeForm="Extracting tokens")
TaskCreate(subject="Choose output format and generate", activeForm="Generating output")
TaskCreate(subject="Recommend shadcn/ui style", activeForm="Recommending style")
TaskUpdate(taskId="3", addBlockedBy=["2"])
TaskUpdate(taskId="4", addBlockedBy=["3"])
TaskUpdate(taskId="5", addBlockedBy=["4"])
TaskUpdate(taskId="6", addBlockedBy=["5"])
TaskUpdate(taskId="2", status="in_progress")
TaskUpdate(taskId="2", status="completed")
Step 1: Capture Source
For screenshots: Read the image directly (Claude is multimodal). Pasted/attached images are compressed to the same token budget as Read tool images (CC 2.1.97), so both workflows are equally efficient.
Resolution budget (Opus 5 / CC 2.1.111+): Max input is 2,576 px on the long edge (~3.75 MP) — roughly 3× the Opus 4.6 ceiling. Dense dashboards, dark-mode UIs, and technical diagrams benefit the most from the higher ceiling; extraction reads tiny labels, spacing ticks, and component boundaries that were previously blurred. Below 1,024 px, don't upscale — the source bitmap is the ceiling. Resize only when input exceeds 2,576 px.
For URLs:
For current project:
Grep("@theme", glob="**/*.css")
Glob("**/tailwind.config.*")
Glob("**/tokens.css")
Glob("**/*.css")
Glob("**/theme.*")
For screen recordings (video): the only input mode that carries motion — easing, scroll
choreography, transitions. Requires ffmpeg/ffprobe (skip with an install hint if missing).
ffprobe -v error -show_entries format=duration,size:stream=width,height,r_frame_rate -of json "$VIDEO"
mkdir -p "$SCRATCHPAD/video-frames"
ffmpeg -y -i "$VIDEO" -vf fps=1 "$SCRATCHPAD/video-frames/frame-%03d.jpg"
Then Read the extracted frames (multimodal) and analyze in layers:
| Layer | What to capture |
|---|
| Layout | viewport framing, grids, sticky zones, section order |
| Motion | reveal timing, easing curves, parallax, pinned/scrubbed sections, hover states, loops |
| Visual | same token extraction as screenshots (colors, type, spacing) |
| Rebuild | name the mechanism: CSS transition, IntersectionObserver, GSAP ScrollTrigger, video.currentTime scrub, WebGL |
Video inputs additionally emit a motion-spec.md alongside the token output: per-interaction
durations (ms), easing, trigger (scroll/hover/load), and a reduced-motion fallback for each entry.
Never describe motion as "smooth" or "nice" — convert taste into mechanism + numbers.
Step 2: Extract Design Context
If stitch MCP is available:
If stitch MCP is NOT available (fallback):
Extracted data structure:
{
"colors": {
"primary": { "hex": "#3B82F6", "oklch": "oklch(0.62 0.21 255)" },
"secondary": { "hex": "#10B981", "oklch": "oklch(0.69 0.17 163)" },
"background": { "hex": "#FFFFFF" },
"text": { "hex": "#1F2937" },
"muted": { "hex": "#9CA3AF" }
},
"typography": {
"heading": {
Step 3: Choose Output Format
AskUserQuestion(questions=[{
"question": "Output format for extracted tokens?",
"header": "Format",
"options": [
{"label": "Tailwind @theme (Recommended)", "description": "@theme block in the CSS entry (app.css) with extracted theme values"},
{"label": "W3C Design Tokens", "description": "design-tokens.json following W3C DTCG spec"},
{"label": "CSS Variables", "description": "tokens.css with CSS custom properties"},
{"label": "Markdown spec", "description": "Human-readable design specification document"}
],
"multiSelect": false
}])
Tailwind v4 is CSS-first: theme values go in an @theme block, and tailwind.config.js
is ignored entirely (see ui-components/rules/tailwind-v4-patterns.md).
@import "tailwindcss";
@theme {
--color-primary: oklch(0.62 0.21 255);
--font-sans: "Inter", system-ui, sans-serif;
--spacing: 0.25rem;
}
Legacy (Tailwind v3 only): if the project pins v3, emit tailwind.config.ts with the
same values under theme.extend. Offer this only after confirming the v3 pin in
package.json. It is never the default.
Step 4: Generate Output
Write the extracted tokens in the chosen format. If the project already has tokens, show a diff of what's new vs existing.
Step 5: Recommend Best-Fit shadcn/ui Style
After extracting design DNA, map the extracted characteristics to the best-fit shadcn/ui v4 style:
radius = extracted["radius"]
density = extracted["spacing"]
elevation = extracted["shadows"]
STYLE_MAP = {
("pill/large", "generous", "layered"): "Luma — polished, macOS-like",
("medium", "balanced", "subtle"): "Vega — general purpose",
("medium", "compact", "subtle"): "Nova — dense dashboards",
("large", "generous", "subtle"): "Maia — soft, consumer-facing",
("none/sharp", "balanced", "none"): "Lyra — editorial, dev tools",
("small", "dense", "none"): "Mira — ultra-dense data",
}
Skip condition: If the user only needs raw tokens (not a shadcn project), skip this step.
Anti-Patterns
- NEVER guess colors without analyzing the actual source — use precise extraction
- NEVER skip the oklch conversion — all colors must have oklch equivalents
- NEVER output flat token structures — use three-tier hierarchy (global/alias/component)
Quality Bar
Done means all of these hold:
- Every color was sampled from the actual source, has an oklch equivalent, and carries a role name
- Typography includes family, weight, and the observed size scale — not "modern sans-serif"
- Output file written in the chosen format and verified to parse (JSON/TS/CSS)
- Video inputs: motion-spec.md names mechanism + duration + easing + reduced-motion fallback per interaction
- If the project already had tokens, the diff of new-vs-existing was shown
Related Skills
ork:design-to-code — Full pipeline that uses this as Stage 1
ork:design-system-tokens — Token architecture and W3C spec compliance
ork:component-search — Find components that match extracted patterns