| name | distill-design |
| description | Distill a DESIGN.md from a website โ crawl and analyze a site's rendered design (colors, typography, spacing, components, signature motifs) and produce a brand-accurate DESIGN.md design-system spec. On request, also generate a token-preview page (preview.html) or a realistic website demo (demo.html). Use when the user gives a URL and asks to "make/generate a DESIGN.md", "extract this site's design system", "capture a brand's visual language", or "turn this website into design tokens". |
| user-invocable | true |
| allowed-tools | ["Read","Write","Edit","WebFetch","Bash"] |
/distill-design โ Distill a DESIGN.md from a website
Turn a live website into a DESIGN.md: a plain-text design-system spec (YAML
token frontmatter + 11 prose sections) that any AI agent can read to generate
on-brand UI. Concept and format follow
VoltAgent/awesome-design-md.
Argument: a website URL ($ARGUMENTS). If none was given, ask for one.
What gets produced: by default, only DESIGN.md. The visual preview.html
and the realistic demo.html are opt-in โ generate them only when the user
asks (see the two "on request" sections below).
Read these first
reference/format-spec.md โ the exact frontmatter schema and 11-section body.
reference/extraction-guide.md โ how to measure tokens off a live site.
reference/template.md โ the DESIGN.md skeleton you fill in.
reference/preview-template.html โ the canonical, data-driven preview.html.
Copy it verbatim and inject only the token JSON (see "Generate the token preview").
reference/demo-guide.md โ how to build the realistic demo (only when asked).
(These ship next to this SKILL.md, so read them as siblings.)
The preview.html shell is the same for every brand โ use the template above, never
hand-write it. For a bespoke demo.html, the sample folders examples/stripe,
examples/linear, examples/spotify in the source repo
(ake77-code/distill-design) are references.
Where to write output
By default, write into the current project (not this skill's own folder):
- A single spec โ
./DESIGN.md (project root). An optional preview.html /
demo.html go alongside it only when requested.
- Several specs โ use a
distill-design/<brand>/ folder per brand.
- Always honor an explicit path the user gives.
Workflow
1. Scope the target
Confirm the URL. Identify a few page types worth inspecting beyond the homepage:
marketing, pricing, docs, and the app/dashboard if reachable. Brands often flip
polarity (light marketing โ dark app) โ plan to capture both.
2. Inspect & measure
Prefer measured values over guesses. Drive a real headless browser and read
getComputedStyle โ try these in strict order, stop at the first that works
(full snippets in extraction-guide.md):
- Playwright (preferred) โ script Chromium via Bash; install with
npx -y playwright install chromium (or bunx playwright install chromium) if
missing, then page.$eval(sel, โฆ) to read exact hex, font stacks, radii, padding,
shadows. Screenshot too. (npx and bunx are interchangeable throughout.)
- Puppeteer (fallback) โ same approach via
require("puppeteer") if Playwright
is unavailable; install with npx -y puppeteer browsers install chrome (or the
bunx equivalent).
- Browser MCP (Chrome / Preview) โ only if one is already connected.
WebFetch / fetch (LAST RESORT) โ text only, no pixel values. Use ONLY when no
browser can run; combine with brand knowledge and label the output an inspired
interpretation in the Colors note and ## Known Gaps.
Sweep heros, body text, buttons, cards, nav, inputs, and footer. Pull colors โ roles,
the type scale, radius scale, spacing base unit, elevation, per-component specs and
states, and the 2โ3 signature motifs.
3. Map to tokens โ go DEEP
The most common failure is a too-thin file. Real brands have many tokens; match that
depth (see format-spec.md for the targets):
- Colors ~18โ30+, named by role, kept FLAT. Carry polarity inside
colors:
with *-on-dark text variants and surface-dark-* tiles; tier muted inks by
approximate opacity in the name (ink-muted-64). Only dedupe same-role hexes within ~2%.
- Typography ~12โ20 SEMANTIC roles (
hero-display, lead, tagline,
body-strong, dense-link, caption-strong, button-large, fine-print,
micro-legal, nav-link), each with weight, line-height, letterSpacing in px,
and fontFeature only when real. Capture rare weights (300 / 600-vs-700).
rounded with none:0 + full; spacing with measured oddities (17px) and
a section step. Use measured values, not idealized 4/8/12.
- Components ~15โ30+, each a
{group.token} composition (literal padding/height/
size allowed). Variants are SEPARATE keys (-active, -focus, -selected, -2).
Never document hover.
- Choose an open-source substitute for any proprietary font.
4. Write DESIGN.md
Fill reference/template.md into the output path (default ./DESIGN.md โ see
"Where to write output"). Follow the 11-section structure and the prose tone of the
bundled samples. name: is <Brand>-design-analysis. The frontmatter description is
the most important field โ one dense paragraph on a single line (plain scalar, not a
> block) vivid enough to picture the site with eyes closed.
5. Self-check the DESIGN.md
- Frontmatter is valid YAML; run a quick parse if unsure (see verification below).
- Every
{group.token} in the body resolves to a defined frontmatter key.
- All 11 sections present and non-empty (Overview โ Known Gaps), including the
required
## Known Gaps.
- Depth targets met (~18+ colors, ~12+ type roles, ~15+ components).
description is
inline. No -hover component keys (brief prose hover is fine). letterSpacing in px.
- Colors are role-named and deduped; proprietary fonts have a substitute.
6. Offer the visualizations (always end with this)
The DESIGN.md is the deliverable. Do not auto-generate preview.html or
demo.html. End your reply by reminding the user they can opt into either, e.g.:
ๅทฒ็ๆ DESIGN.mdใ้่ฆ็่ฏๆ่ฟ่ฝๅบไบๅฎ็ๆ:
โ preview.html โโ ่ฎพ่ฎก็ณป็ปๅฏ่งๅ(่ฒๆฟ / ๅญ้ถ / ็ปไปถ,ๅธฆ้กถ้จๅฏผ่ชไธๆๆๅๆข);
โก demo.html โโ ๅ็ๅฎ็ฝ็ซ็ Web ่ฝๅฐ้กตๆ็งปๅจ็ซฏ็้ขใ
ไธค่
้ฝๆ้็ๆ,่ฆๅชไธชๅ่ฏๆใ
(Match the user's language.) Generate preview.html only if asked โ follow
"Generate the token preview" below. Generate demo.html only if asked โ follow
"Generate a realistic demo" below.
Generate the token preview preview.html (on request)
Do NOT hand-write per-brand HTML/CSS. The preview shell is identical for every
website โ only the injected data changes. The skill ships one canonical, data-driven
template: reference/preview-template.html โ a polished design-system showcase page:
a sticky nav (the brand wordmark + a distill-design GitHub chip that links to
github.com/ake77-code/distill-design + section anchors + light/dark toggle + a CTA),
a two-column hero (Design System Analysis of <displayName> + the description + a
device-mock card), then numbered sections
("01 โ Color Palette", "02 โ Typography Scale", "03 โ Components", "04 โ Spacing &
Radius", "05 โ Elevation & Depth", "06 โ Responsive Behavior") rendering grouped swatch
cards, a type ladder, a component gallery, spacing/radius blocks, and a breakpoints
table. No footer. Zero dependencies (system fonts, no CDN).
To generate a brand's preview.html:
- Copy
reference/preview-template.html verbatim to <output>/preview.html.
- Replace ONLY the JSON inside
<script type="application/json" id="design-data">
with the brand's tokens, derived from the DESIGN.md. Change nothing else โ the shell,
CSS, and renderer stay byte-identical across brands.
The injected JSON schema (see the comment above that block in the template):
meta: { name, displayName, description, source, nativeTheme: "light"|"dark", navCta, heroCtas, sections? }. name is the real brand; the hero reads "Design
System Analysis of displayName" โ set displayName to the real brand name
(e.g. "Apple", "Stripe", "Figma"). Do NOT invent fictional product names โ use the
actual brand the URL belongs to. description is the
frontmatter description verbatim; source is the live URL; nativeTheme is the
brand's polarity (dark for Linear etc.). Optional navCta (nav button label, e.g.
"Buy" / "Get started") and heroCtas ["Learn more","Buy"] set the brand's CTA
wording. Optional heroArt picks the hero visual to match the signature motif:
device (default product mock), mesh (gradient-mesh fill โ Stripe-like brands), or
glow (dark glow โ Linear-like brands). Optional sections = { colors:{heading,intro}, typography:{...}, components:{...} } gives each section a brand-voiced heading/intro (e.g. "One blue.
Three near-blacks.") pulled from the matching DESIGN.md body sections; omit for defaults.
colors: the flat palette as roleโhex (rgba strings ok). Every role renders as a
swatch, auto-grouped (Brand & Accent / Surface / Text / Hairlines & Borders / Semantic).
colorRoles (optional, recommended): { role: "one-line description" } โ the
per-color usage note from the DESIGN.md Colors section; shows as the swatch's 3rd line
so cards match the reference depth. colorNames (optional): { role: "Friendly Name" }
โ renders as "role (Friendly Name)".
colorsDark: optional opposite-polarity overrides (else dark is synthesized).
typography: roleโ{ fontFamily, fontSize, fontWeight, lineHeight, letterSpacing }.
rounded, spacing: tokenโvalue maps.
components: roleโ{ backgroundColor, textColor, typography, rounded, padding, border, height, size }; values may use {group.token} refs (resolved by the renderer) so each
gallery sample renders in the real component style.
responsive (optional): { breakpoints:[{name,width,changes}], touchTargets, collapsing, imageBehavior } from the DESIGN.md Responsive Behavior section โ drives
"06 โ Responsive Behavior". Omit the whole key to hide the section.
The template already provides the nav, hero, numbered sections, swatch grouping,
type ladder, component gallery, spacing/radius/elevation blocks, a responsive
breakpoints table, and the
light/dark toggle (localStorage). The nav wordmark shows the brand name
(not a third-party brand); the GitHub chip reads distill-design and points at
github.com/ake77-code/distill-design.
After injecting the data, verify it opens standalone (file://) and visually reads as
a polished design-system analysis page in the brand's colors. For pixel-level reference,
the awesome-design-md project renders each brand at getdesign.md/design-md/<brand>/preview.html.
Generate a realistic demo demo.html (on request)
Goal: a single .html file with zero external dependencies (all CSS/JS inline,
no CDN, no network requests โ system/-apple-system font stacks only) that reads
like a real product, not a token catalog. It is distinct from preview.html:
preview.html documents the system; the demo uses it to ship a believable page.
Read reference/demo-guide.md for the full recipe. In short:
- Ask form factor if unclear: Web (responsive landing page) or Mobile
(a phone-framed app screen). Default to Web.
- Build a real page from the tokens โ pull every color, font, radius, spacing,
shadow and component straight from the
DESIGN.md:
- Web: sticky nav โ hero (headline + sub + primary/secondary CTA) โ social-proof
logos โ 3-up feature cards โ pricing tiers โ testimonial โ CTA band โ footer.
- Mobile: a phone frame (status bar, notch) wrapping a real app screen โ top bar,
content list/feed/cards, and a bottom tab bar or now-playing/sticky CTA.
- Make it feel real โ plausible copy and product name, the brand's signature
motif (e.g. gradient mesh, glow hairlines, green play button), realistic imagery
via inline SVG/CSS gradients (never hot-link external images), and tasteful
hover/scroll micro-interactions in a tiny inline
<script>.
- Save next to the spec as
demo.html (or demo-mobile.html).
- Verify it opens standalone (double-click /
file://) with no console errors and
visibly resembles a real site in the brand's language.
Verify
python3 - "$f" <<'PY'
import sys, yaml
t = open(sys.argv[1]).read().split('---', 2)
yaml.safe_load(t[1]); print("frontmatter OK")
PY
Then grep the spec for the two most common slips โ both must return nothing:
grep -nE '^\s+[a-z0-9-]*-hover:' "$f"
grep -c '^## ' "$f"
If you generated a preview.html or demo.html, open it in a browser โ or
screenshot it with a browser MCP โ and confirm it renders in the brand's language.
Notes
- Keep folder names lowercase, URL-safe (
stripe, together.ai).
name: is <Brand>-design-analysis. When values are interpreted (WebFetch-only,
no measured CSS) rather than officially sanctioned, say so in the Colors source-pages
note and the ## Known Gaps section โ don't fabricate precision.
- One brand per folder; document state variants as separate component keys; never hover.