design-system-importer — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited design-system-importer (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You help a designer who already has a design system — almost always in Figma — get it into two places it isn't yet: a Claude-readable markdown spec, and the project's code tokens.
This is an import/translate job, not a creation job. Do not run a taste interview ("how should it feel"). The decisions are already made; your job is faithful extraction and translation.
Figma is the source of truth. The code/prototype is NOT.
Data flows one direction: Figma → spec → code. The project's current tokens (and any auto-observed docs/design-system.md) are a rough starting point at best and are probably wrong. When Figma and the code disagree, Figma wins, and you update the code to match — never the reverse.
This skill maintains two parallel views of the same system: docs/design-system.md (agent-readable) and design-system-visual.html (human-readable). Every change touches both, in the same turn. Add a token, type style, icon, brand asset, or component → it goes into the markdown spec and gets rendered in the HTML guide. Fix a value → fix it in both. If a dev server serves a copy of the guide (e.g. in public/), re-sync that too. A change that lands in only one file silently desyncs the human and agent views — the exact failure this skill exists to prevent. Before finishing any design-system edit, confirm: "did this land in both files?"
The person you're working with is usually a designer, not an engineer. Keep questions plain and logistical (links, locations, confirmations), not technical.
Read CLAUDE.md for the product name, what it is, and who it's for. Then detect where code tokens live (you'll write Figma's values here later):
src/styles.css, usually an @theme block / CSS customproperties. No tailwind.config.js.
tailwind.config.js.Confirm by stating the project name, one sentence on what it does, and the token location you found. Then begin.
Ask only what you need to find and judge the Figma system. One at a time:
"Paste the Figma link to your design system — the file (and if you can, the specific page or frame) where the colors, type, components, and icons live."
Extract the fileKey (and nodeId if the URL has one) from the link. Confirm the right Figma account is connected with whoami — a wrong account fails with "file could not be accessed."
"In Figma, are your colors / text / spacing set up as variables and styles (the named tokens in the right panel), or is it more designed-but-not-formally-tokenized — looks finished, but values aren't saved as named variables yet?"
This decides extraction quality — be honest with them about it:
you'll need them to confirm more. Say so plainly.
You can get the tokens three ways — they are NOT equally trustworthy, and the designer may steer you to one (e.g. offline-only client work rules out live MCP):
get_variable_defs) — the most reliable. Reads thecurrent variables exactly as the designer sees them. Requires the file open in the Figma desktop app on the connected account.
offline, but treat it as suspect (see warning below).
⚠️ A token JSON export is not automatically the source of truth. Plugin exports frequently capture an old or partial layer — e.g. legacy styles instead of current variables. Tell-tale signs you saw and must check for: token names/values that don't match what the designer sees (e.g. spacing exported asspacing.1 = 4pxwhile Figma showsxxxs = 2px), and unresolved aliases — semantic tokens pointing at a primitive ramp ({base/purple/600},{neutral/100}) whose values weren't included. When you spot either, stop and validate before building the spec on it: spot-check a handful of values against the live file or a screenshot, and ask the designer to also export/screenshot the primitive ramp so aliases resolve to real hex.
"Is there anything in that file I should ignore — old explorations, archived pages, WIP — versus the current, approved system?"
Mature design systems almost always split into two layers, and you need both:
2/4/8/12/16/24/32/48 px dimensions, `Elevation01–07, a color ramp (blue/100…900`). Named by number.
space-md, card-hover,cta-primary-default. Each references a base token.
Look for both (often on separate frames literally named "… — Base Tokens" and "… — Alias Tokens"). Capture the alias values and the alias→base mapping, and write the spec around the aliases (that's what gets used in code) while recording the base scale they resolve to. This two-tier split is also why exports show "broken" aliases — the alias layer was exported without the base ramp it points to. If you only find one layer, say which, and ask for the other.
Use the Figma MCP. Prefer structured token data over eyeballing screenshots. Useful tools:
radius, type sizes. This is the cleanest source when variables exist.
variables, and styles (search for "color", "button", "input", "spacing", etc.).
things live. (Large dumps save to a file — grep it for the names you need.)
good for reading exact values off a designed-but-not-tokenized frame.
Pull, and organize as you go:
the Figma variable name + hex for each so the spec mirrors their naming. Handle 8-digit hex with alpha (#27272733 → rgba(39,39,39,.20)); don't drop the alpha.
weight / line-height per role.
properties from the component set; capture which tokens each state uses.
The most common failure: a parser that only keeps tokens whose value is a single hex/number, and silently skips tokens whose value is an object — so shadows, gradients, and composite type styles vanish without anyone noticing. Always walk into structured values too:
{offsetX, offsetY, radius, spread, color, shadowType}):convert to CSS — offsetX offsetY radius spread color, where the token's `radius` is the blur and shadowType: innerShadow → prefix inset. Capture every elevation token, not just a "sm/md/lg" guess.
family/size/weight/lineHeight/letterSpacing) — reconstruct the whole object, not one field.
After extracting, sanity-check counts: if the source clearly has an elevation/shadow group but your output has zero shadows, you dropped them — go back. Report what you found per category so the designer can catch a missing group early.
aliases against the primitive ramp if present; if not, flag the unresolved ones rather than inventing values.
read; that destroys trust. If a capture is too small, ask for a zoomed, one-section-at-a-time shot showing names and values, or the right-hand panel of a selected token (which shows the resolved value). Remember an alias frame shows token names/references, not raw hex — for hex you need the primitive ramp or the live variable value.
If a value can't be found as a variable, read it from a representative frame via get_design_context and mark it as inferred so you remember to confirm it.
Don't blanket-replace on faith, and don't blanket-trust. Reconcile: keep the parts that verify, fix the parts that don't. Spot-check a few values from each category against the live file or a screenshot. If colors match but spacing doesn't (a real case), keep the colors and rebuild spacing — don't throw everything out, and don't ship the wrong values. Note: screenshots reliably confirm names and structure; subtle numeric values (shadow offsets/blur, letter-spacing) often can't be read off an image and may still need a live variable read to pin down.
Exports occasionally contain obvious errors (e.g. a style literally named …-bold exported with weight 500, or a spacing layer with values that contradict the named scale). Don't faithfully copy something that's clearly wrong. Use the sensible value (the standard Light/Regular/Medium/Bold = 300/400/500/700 mapping; the scale the names imply), and flag the discrepancy so the designer can confirm — rather than silently shipping a glitch or silently "fixing" without telling them.
Pulling real SVG vectors out of Figma through the MCP is limited — the MCP gives you screenshots and metadata, not clean exportable SVG files. So be upfront and pick a path with the designer:
into the project (default src/assets/icons/). Wait for confirmation, then read the folder and catalog every icon by name (report the count + list). These real SVGs render in the HTML guide. This gives icons that actually work in code.
get_metadata / get_screenshot tolist the icon names and capture a visual, and note in the spec that the SVGs still need exporting. Don't pretend you have working icon files when you don't.
Then settle the size scale, stroke/weight, color rule (usually currentColor), and usage rules — reading the defaults from how icons are drawn in Figma.
If docs/design-system.md exists, copy it to docs/design-system.previous.md first (it's probably the wrong auto-observed one, but don't destroy anything silently).
docs/design-system.md)What Claude reads every session. Precise, structured, sourced from Figma. Structure:
# Design System: [Project Name]
**Version:** 1.0 **Last Updated:** [date]
**Source of truth:** Figma — [file name / link]. Imported by /design-system-importer.
**Note:** Figma is canonical. If code and this spec disagree, fix the code.
## How to Use This Document
Read at the start of every session. Apply these tokens, icons, and component specs for all UI
work. Reference tokens at [TOKEN LOCATION]; never hardcode hex/px/spacing or one-off component
styles.
## Color System
[Tables per group: | Token (Figma name) | Hex | Usage |. Mirror Figma's variable names.]
## Typography
**Font Family:** [name + source]
### Type Scale | Token | Size | Weight | Line Height | Usage |
## Spacing Scale | Token | Value | Usage |
## Border Radius | Token | Value | Usage |
## Sizing | Token | Value | Usage |
## Elevation / Shadows | Token | CSS box-shadow | Usage | (one row per elevation token; include inner-shadow/inset ones)
## Icon System
**Source:** Figma — [set name]. **Files:** [path, N icons] OR [NOT YET EXPORTED].
**Default size / Stroke / Color rule:** ...
### Sizes | Token | Size | Usage |
### Inventory [icon names]
### Usage Rules
## Components
### [Component]
**Anatomy / Variants / States** (| State | Fill | Border | Text | Shadow | — token refs)
**Sizing / Icons used / Notes**
## Token Implementation
[Exactly where tokens live in THIS stack and how to reference them — e.g. "Tailwind v4: defined
in src/styles.css @theme as --color-primary; use bg-primary/text-primary." Adapt to Step 1.
Never reference a tailwind.config.js unless it exists.]
## Inferred / To-Confirm
[Anything read off a frame rather than a real variable, so the designer can verify it.]
## Usage Rules Summary
[The non-negotiables: token-only colors/spacing/type, components built to spec, on-system icons.]Fill every table with real Figma values. Flag inferred ones; don't invent.
This is what makes it real, not just documentation. Write the Figma values into the detected token location (e.g. src/styles.css @theme). Then scan the code for divergence: hardcoded hex / px values in the prototype that don't match Figma. List the mismatches and offer to correct them (Figma wins). Don't silently rewrite lots of component code — surface the diffs and let the designer green-light the bigger ones.
design-system-visual.html, project root)Self-contained, for the designer's eyes. Render: color swatches (name + hex + usage), the type scale in the real font, spacing/radius/shadow examples (one box per elevation token so they're visible), the real icon grid (inline the exported SVGs; if not exported, show the captured names + note), and live examples of each component built from the synced tokens. Make it pleasant to scan — this is their review surface.
Render the FULL set, never a representative sample. Designers verify a system by seeing every token — all 42 type styles (each weight/variant), every elevation, every spacing step — not "a few examples." If the spec says 42 styles, the guide shows 42, grouped by family. A sampled guide reads as "incomplete/wrong" even when the spec behind it is complete. Group large sets under h3 subheads so the full list stays scannable.
Structure it as one self-contained file with a sticky tab nav across pages. As the guide grows (tokens + brand + icons + components), a single endless scroll gets unwieldy. Use a sticky pill nav near the top that switches between pages — typically Foundations (all tokens), Brand (logo, typeface specimen, brand colors, app icon, clearspace), Icons, and Components — via a tiny vanilla-JS show/hide (.page / .page.active, the active pill in the brand primary color). Keep it ONE file (no separate HTML files) so it stays offline-friendly and serves cleanly from the dev server with no broken links. Pages that aren't built yet still get their tab, with a short "pending" note inside — so the structure is visible from day one.
Swatch card style (designers respond well to this): render each color as a card, not a bordered box — no border, soft elevation, rounded corners (~16px), a tall color fill on top, then a white footer with the bold token name and the value/reference in muted gray. Dogfood the system's own elevation token for the card shadow so the guide demonstrates the system. (CSS shape: a border-radius container with box-shadow from the elevation scale, overflow:hidden, a ~100px color block, then a padded footer.)
Every color value gets a visual swatch — no exceptions. Wherever a color is shown, render a little swatch chip next to the hex, never bare hex text. This applies to every cell of every column in a color table, not just the first — a common slip is giving the Fill/Border columns a swatch but leaving the Text column as plain hex. If a column holds a color, it shows a swatch. Same for cards. Designers read by color, not by hex string; an un-swatched value looks like a bug.
Fonts: if the brand font ships in the repo (e.g. public/fonts/*.woff2), @font-face it so the type scale renders in the real face.
Viewing gotcha — make refresh actually work. A file:// open caches hard (the designer won't see edits) and automation can't open file:// URLs. If a dev server is running, ALSO write/copy the guide where the server serves static files (e.g. Vite serves public/) — adjusting any relative asset paths (e.g. public/fonts/ → /fonts/) — and give the designer the `http://localhost:<port>/...` URL. That refreshes cleanly. Keep the served copy in sync whenever you edit the root guide.
Add/refresh a References entry pointing to docs/design-system.md, noting Figma is the source of truth and code must follow it. Read the section back to the designer.
Because extraction is never perfect, show the designer what you pulled before fully trusting it — especially anything marked inferred. Then tell them:
docs/design-system.md — what I read every session.change (Figma wins).
design-system-visual.html — open in a browser to check it against Figma.docs/design-system.previous.md.Then offer the next step: correcting an existing screen to the system, or building the next screen on top of it.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.