Install
$ agentstack add skill-sso-ss-vibe-ship-it-generate-design-md ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Generate DESIGN.md
Takes a website URL and produces a complete DESIGN.md file -- a plain-text design system document that any AI coding agent can read to build UI that matches that site's look and feel.
How It Works
- Designer gives a URL
- Fetch the page HTML and all linked CSS
- Extract every visual token: colors, fonts, spacing, shadows, radii, component patterns
- Analyze the visual atmosphere and design philosophy
- Detect the page structure (sections, grids, layout patterns)
- Generate three files:
DESIGN.md-- the complete design system (9 sections)- Tailwind config extension -- tokens mapped to utility classes
- CSS variables -- tokens as custom properties in globals.css
- Drop them in the project
One command. No questions. The designer just sees the result.
When To Use
- "I like how linear.app looks -- capture that"
- "Generate a design md from stripe.com"
- "Make my app look like this site"
- "Use vercel.com as a design reference"
- "Grab the design from notion.so"
- "Copy the style of airbnb.com"
Extraction Process
Step 1: Fetch (multi-pass)
Do multiple fetches to maximize what you capture:
Pass 1: HTML Fetch the target URL. From the HTML, extract:
- All `` URLs
- All `
blocks (including` for CSS-in-JS SSR output) - All
style="..."inline attributes on elements - `` for brand color
- Google Fonts / Typekit `` URLs (reveals exact font families and weights)
- `
and` (brand color clues)
Pass 2: CSS files Fetch each discovered stylesheet URL. If a URL returns 403/404:
- Try removing query strings
- Try the base domain +
/styles.css,/main.css,/globals.css - Try common CDN patterns:
cdn.example.com/css/... - Move on if blocked -- note which sources were inaccessible
Pass 3: Critical CSS extraction Many modern sites inline critical CSS in ` tags in the `. This often contains:
- CSS custom properties (
:root { --color-primary: ... }) - Font-face declarations
- Key component styles
- Media queries with breakpoints
This is often the richest source -- don't skip it.
Step 2: Extract Raw Tokens
Pull these from ALL collected sources (external CSS + inline styles + style blocks):
| What | Where to look | |---|---| | Colors | CSS custom properties, color, background-color, border-color, fill, box-shadow color values, style="color:..." inline, meta[theme-color] | | Fonts | font-family, @font-face, Google Fonts URL params (?family=Inter:wght@300;400;700), Typekit kit IDs | | Type scale | font-size, font-weight, line-height, letter-spacing -- collect ALL unique values and sort | | Spacing | padding, margin, gap -- collect unique values, find the base unit (most common divisor) | | Radii | border-radius -- collect per-component (see Radius Precision below) | | Shadows | box-shadow -- capture full declarations including multi-layer stacks | | Borders | border shorthand and individual properties | | Transitions | transition, animation, @keyframes declarations | | Breakpoints | @media queries -- extract all width breakpoints |
Radius Precision
Border-radius is the token most often wrong because CSS text alone is ambiguous: variable references (var(--radius)), utility classes (rounded-xl), and shorthand (8px 8px 0 0) all hide the actual computed value. Use these techniques in order of reliability:
1. Resolve CSS variables. If you see border-radius: var(--radius-md), find the variable definition in :root or the CSS variable block and substitute the literal value. Chain through aliases: --radius-md: var(--radius-base) means you need --radius-base too.
2. Map utility classes. If the HTML uses Tailwind or a utility-first framework, map class names to known values: | Class | Value | |-------|-------| | rounded-none | 0px | | rounded-sm | 2px (0.125rem) | | rounded | 4px (0.25rem) | | rounded-md | 6px (0.375rem) | | rounded-lg | 8px (0.5rem) | | rounded-xl | 12px (0.75rem) | | rounded-2xl | 16px (1rem) | | rounded-3xl | 24px (1.5rem) | | rounded-full | 9999px |
If the site uses a custom Tailwind config the values may differ. Check CSS custom properties for overrides like --radius: 0.625rem (Shadcn/ui pattern).
3. Group by component. Different components use different radii. Always record WHICH component a radius belongs to:
- Buttons: typically
radius-smorradius-md - Cards / panels: typically
radius-mdorradius-lg - Inputs: typically matches button radius
- Modals / sheets: typically
radius-lgorradius-xl - Badges / pills: often
radius-full(9999px) - Avatars:
radius-fullfor circles,radius-mdfor rounded squares - Dropdowns / menus: typically
radius-md - Tooltips: typically
radius-sm
When two components use the same numeric value, that's an intentional design system choice. Note it. When they differ by component, that IS the radius scale.
4. DevTools precision pass (optional). If the fetched CSS is heavily variable-based, JS-rendered, or the radius values look ambiguous, ask the designer to run the DevTools extractor script in their browser:
- Open the target site in Chrome/Safari/Firefox
- Open DevTools console (right-click > Inspect > Console)
- Paste the extractor script (available at the project's
public/extract.js) - The script reads
getComputedStyle()on every visible element and groups radii by component type (button, card, input, modal, badge, etc.) - Result is copied to clipboard as JSON
The radiusByComponent object in the script output gives the exact computed radius for each component type, with occurrence counts. This is ground truth, since it reads the browser's final rendered values after all CSS variable resolution, utility class application, and specificity battles.
When the designer pastes this JSON, use radiusByComponent as the authoritative source for the Border Radius table in DESIGN.md. It overrides any values inferred from CSS text.
Step 3: Verify, don't guess
Extracted = you found the exact value in HTML, CSS, or inline styles. Mark these with confidence.
Inferred = you deduced the value from patterns (e.g., "body text is probably 16px based on the type scale"). Note these in the output with (inferred) so the designer knows.
Known = you recognize the site and fill from general knowledge. This is valid but must be flagged: add a note at the top of the DESIGN.md if significant portions came from recognition rather than extraction. Known values come from training data that may be months or years old. If a site has redesigned since then, known values will be confidently wrong. If more than 30% of tokens are "known" with zero extracted confirmation, add a warning that values may reflect an older version of the site.
Source priority when values conflict: External stylesheet > inline ` blocks > style="" attributes > known. This inverts normal CSS specificity on purpose: inline style` attributes are often one-off overrides, not canonical design tokens. The stylesheet is where the real system lives. When two sources disagree on the same property, use the higher-priority source and drop the other silently.
If the output is mostly inferred/known (CSS was blocked, JS-rendered, etc.), add this note at the top:
> Note: CSS files were not fully accessible. Some values are based on
> visual analysis of the site's publicly visible HTML and known design patterns.
> Verify accent colors and exact spacing values against the live site.
Step 4: Analyze Patterns
From the raw tokens, identify:
- Color roles: Which color is background? Primary text? Accent? Secondary text? Border?
- Type hierarchy: What's the display size? Heading? Body? Caption? What weights are used?
- Spacing rhythm: Is it 4px-based? 8px-based? What's the scale?
- Component signatures: How do buttons look? Cards? Inputs? Navigation?
- Shadow philosophy: Flat? Subtle elevation? Heavy depth? Shadow-as-border?
- Shape language: Map each component type to its specific radius. Are buttons and inputs the same? Are cards larger? Any use of asymmetric radii (e.g.
8px 8px 0 0)? Does the radius scale follow a pattern (e.g. 4/8/12/16)?
Font Classification
Separate extracted fonts into three buckets:
- Body font: the font used on most text. Look for names containing "Text", "Body", or "Sans" (without "Display").
- Heading font: used for titles. Look for names containing "Display", "Headline", "Title".
- Mono font: for code/data. Names containing "Mono", "Code", "Consol", "Courier".
Filter out icon fonts before assigning roles. Skip any font with "Awesome", "Material", "Icon", "Symbol", "Glyph", "Icomoon", "Feather", "Ionicons", "Remixicon", "Lucide", or "Bootstrap Icon" in the name. These are icon fonts, not text fonts.
If the site uses only one text font for everything, note it as both body and heading. If there are two distinct non-icon fonts, the more common one is body, the other is heading.
Accent Color Detection
The accent color must be intentional, not a stray focus ring or outline:
- Saturation > 40% required. Low-saturation colors are grays, not brand colors.
- Source must be text or background, not border. Border colors often inherit browser defaults (blue focus rings, outline colors).
- Monochrome sites (Uber, Nike) have no accent. The primary button is dark/black, not colored. Don't force an accent when there isn't one.
- Check CSS variables:
--accent,--brand,--color-primary,--color-button-primaryoften hold the brand color.
Button Detection
Sites use different button styles. Detect in this priority:
- Chromatic buttons: colored background (saturation > 40%). This is the accent/CTA.
- Dark/black buttons: common on monochrome sites (Nike, Puma, Uber, Vercel). Brightness
or`. - Hidden panels: most dropdowns are
display:noneuntil hover. Their styles are still readable viagetComputedStyle(). - Page-wide fallback: search the whole page for the same selectors.
Dropdown radius cap: max 24px. Dropdowns are tight UI, never pill-shaped.
Pill Detection
Only values >= 999px count as pills, NOT percentage values like 50% or 100%. The value 50% creates circles (avatars, icons), not pills. The value border-radius: 9999px or border-radius: 1600px creates pills.
When a site uses pills AND no explicit button radius is detected, assume buttons are pills too.
Bot Protection
If the headless browser lands on a challenge page instead of the real site, detect it by checking the page title or first heading for phrases like: "just a moment", "checking your browser", "security check", "access denied", "attention required", "what happened", "please verify", "captcha". Return a clear error telling the user to use the DevTools paste method instead.
Step 5: Interpret the Atmosphere
Read the design decisions as a whole. What does this site feel like?
- Dense or spacious?
- Technical or friendly?
- Dark or light?
- Minimal or rich?
- Corporate or playful?
Write this as a short, opinionated paragraph -- not a list of CSS values.
Output Format
The DESIGN.md follows a 9-section structure optimized for AI agents. Every section earns its place -- no redundancy, no prose padding.
# DESIGN.md -- [Site Name]
[If staleness-risk is medium or high, add a blockquote warning here.]
## 1. Identity
**In one line:** [Single sentence capturing the visual personality -- what a designer would say after 5 seconds on the site.]
**Signature Techniques:**
- [3-5 bullets. Only the things that make THIS site look different from others. Not generic traits like "uses whitespace." Specific moves: "shadow-as-border via `box-shadow: 0 0 0 1px`", "negative letter-spacing at display sizes (-2.4px)", "gradient mesh hero backgrounds".]
## 2. Color
### Palette
| Token | Value | Role | Confidence |
|-------|-------|------|------------|
| `background` | `#hex` | Page canvas | [extracted/inferred/known] |
| `surface` | `#hex` | Cards, panels, elevated containers | |
| `text-primary` | `#hex` | Headings, body text | |
| `text-secondary` | `#hex` | Descriptions, muted copy | |
| `text-tertiary` | `#hex` | Placeholder, disabled, metadata | |
| `accent` | `#hex` | Primary brand action, links | |
| `accent-hover` | `#hex` | Accent hover state | |
| `border` | `#hex` or `rgba()` | Dividers, card edges, input borders | |
| `border-subtle` | `#hex` or `rgba()` | Lighter separator lines | |
| `success` | `#hex` | Confirmation, positive states | |
| `warning` | `#hex` | Caution states | |
| `danger` | `#hex` | Error, destructive actions | |
[Add any brand-specific named colors: "Ship Red", "Console Blue", etc.]
### Dark Mode (if present)
| Token | Light | Dark |
|-------|-------|------|
[Same token names, mapped values for both themes. If no dark mode detected, omit this subsection.]
## 3. Typography
### Fonts
- **Primary:** [font name] -- [fallback stack]
- **Mono:** [font name] -- [fallback stack] (omit if site doesn't use mono)
### Scale
| Role | Size | Weight | Line Height | Letter Spacing | Confidence |
|------|------|--------|-------------|----------------|------------|
| Display | [px/rem] | [number] | [value] | [value] | |
| H1 | [px/rem] | [number] | [value] | [value] | |
| H2 | [px/rem] | [number] | [value] | [value] | |
| H3 | [px/rem] | [number] | [value] | [value] | |
| Body | [px/rem] | [number] | [value] | [value] | |
| Body Small | [px/rem] | [number] | [value] | [value] | |
| Caption | [px/rem] | [number] | [value] | [value] | |
| Code | [px/rem] | [number] | [value] | [value] | |
[Add rows as needed -- these are minimums, not limits.]
### Weight Strategy
[1-2 lines. How many weights are used and what each one means. e.g. "Three weights only: 400 (read), 500 (interact), 600 (announce). No bold."]
## 4. Spacing & Layout
### Base Unit
[e.g. "8px grid. Scale: 4, 8, 12, 16, 24, 32, 48, 64, 96."]
### Container
- Max width: [value]
- Page padding: [value]
- Section gap: [value]
### Border Radius
| Token | Value | Used on | Source |
|-------|-------|---------|--------|
| `radius-sm` | [px] | [inputs, inline code, tooltips] | [extracted/variable-resolved/class-mapped/devtools] |
| `radius-md` | [px] | [buttons, cards, dropdowns] | |
| `radius-lg` | [px] | [modals, hero cards, large panels] | |
| `radius-full` | [px/9999px] | [badges, pills, avatars] | |
[Map every component to its radius token. If buttons use `radius-md` and cards also use `radius-md`, say so. If they differ, that IS the scale]
## 5. Depth & Motion
### Elevation
| Level | Shadow Value | Use |
|-------|-------------|-----|
| Flat | none | Page background |
| Low | `[full CSS]` | Cards, containers |
| Mid | `[full CSS]` | Dropdowns, popovers |
| High | `[full CSS]` | Modals, dialogs |
[Add rows for distinctive techniques: backdrop-blur, glassmorphism, glow, inner shadow, shadow-as-border. Keep them in the table, not as prose.]
### Motion
| Property | Value | Use |
|----------|-------|-----|
| `duration-fast` | [ms] | Hover, toggle, micro-interactions |
| `duration-base` | [ms] | Page transitions, panel open/close |
| `duration-slow` | [ms] | Entrance animations, loading transitions |
| `easing` | [curve] | Default easing function |
[Note any distinctive motion patterns: staggered entrance, parallax, spring physics, scroll-triggered]
## 6. Page Structure
### Header
[ element placement diagram ] height: [value] | position: [sticky/fixed/absolute/static] | bg: [value] | [backdrop-blur if present]
### Page Flow
The page has [N] sections in this order:
**1. [Section Name]** [note if section has a tinted/dark background]
- Heading: [word count, size from type scale, alignment]
- Subheading/label: [position relative to heading (above/below), style (uppercase, small, etc.)]
- Body: [sentence count, approximate word count, alignment]
- CTA: [button count, button labels pa
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [sso-ss](https://github.com/sso-ss)
- **Source:** [sso-ss/vibe-ship-it](https://github.com/sso-ss/vibe-ship-it)
- **License:** MIT
- **Homepage:** https://vibe-ship-it.vercel.app/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.