skills/figma/SKILL.md
--- name: figma version: 1.6.0 description: Use when user says "figma", "figma it", "sync figma", "figma mockup", "create figma file", "design to figma", "figma from PRD", "figma from journey", "build in figma", or "figma design system" — anything that creates, syncs, or updates Figma design systems, components, variables, mockups, or front-end-ready screens. Always enumerates the linked Figma library FIRST (library-driven discovery, not per-need search), produces a block→DS mapping table for us
npx skillsauth add ash4180/vorbit skills/figmaInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create Figma design-system assets and front-end-ready mockups that engineers can implement without guessing.
MCP namespace: This skill uses
mcp__figma__*(primary writer isuse_figma) and optionallymcp__mobbin__search_screensfor competitor research. See_shared/mcp-tool-routing.mdfor the Plugin Tool Index and the announce-the-plugin rule.
Locate
_shared/: This skill ships as a plugin, so_shared/files live in the plugin cache, not your project. Before reading any_shared/...path below, runls -d ~/.claude/plugins/cache/local/vorbit/*/skills/_shared 2>/dev/null | head -1and use the output as the absolute base for every_shared/...reference.
UX patterns reference: Senior UX product designer knowledge lives in
_shared/ux-knowledge/. When designing UI states in Phase 2 (Page Inventory), consultux-philosophy.mdfor empty/loading/error state design principles. When checking accessibility, edge cases, or input validation patterns in Phase 4B (Mockup Creation), consultedge-case-catalog.md. When defining microcopy for buttons/errors/empty states, consultux-philosophy.md → Error Statesand the verbatim-words rule. Read directly — no need to invoke/vorbit:design:ux.
Read and follow _shared/mcp-tool-routing.md.
ToolSearch for "figma" to check if Figma MCP tools are available./mcp to connect, then retry." → STOP/mcp to reconnect, then retry." → STOPToolSearch for "mobbin". If available, it's required in Phase 1 step 7. Inspect the exposed Mobbin tool names/schema before assuming first-class flow support. Record one of:
native flow search — a dedicated flow search tool or flow IDs/metadata are exposed.screen search grouped into flow candidates — only screen search is exposed; infer flows by grouping screens by app, feature area, and recurring UI structure.Mobbin unavailable — no Mobbin tool is connected; record the gap and continue.Before calling use_figma, load the figma-use guidance via ReadMcpResourceTool (server: figma, uri: skill://figma/figma-use/SKILL.md). Do not use the Skill tool for figma-use — the MCP resource path is the supported route.
Goal: Understand the product flow, implementation surface, and existing design system before creating anything.
Create todo list with all phases.
Gather source context. In mockup mode (Phase 4B path) the skill consumes structured fields from the upstream design chain — do NOT re-ask what's already captured:
/vorbit:design:prd — acceptance_criteria[] (AC-*), flow_steps[] (with F*-S* IDs + screen refs + AC tags in Notion-doc format), state_list[], component_mapping_intent[] (block + intent description, no concrete DS name — that's this skill's Phase 3 job). PRD is authoritative for rules; Figma is authoritative for visual./vorbit:design:explore — blocks_mined[] (grain-tagged: section / pattern / component / page-archetype / flow, with embedded reference screenshots), references[]. These ground Phase 3's DS resolution in evidence, not the agent's training-data defaults.If journey context exists, use it only to understand flow and page needs.
Inspect the codebase:
Inspect Figma:
get_metadata)get_variable_defs)get_design_context reports "nothing selected"), the file has not been seeded yet. Do NOT keep fetching — switch to code→design push mode and use generate_figma_design (or equivalent write tool) to push the current UI/intent into Figma first, then continue from a populated frame.
generate_figma_design, load its companion guidance: ReadMcpResourceTool with server: figma, uri: skill://figma/figma-generate-design/SKILL.md.Discover linked libraries — library-driven, not need-driven. The agent must see what exists before deciding what to use; per-need searches alone find confirmation of what the agent already imagined and miss the compositions/blocks it didn't think to search for. This is the single biggest lever for stopping the "agent ignores the linked DS" failure mode.
Call mcp__figma__get_libraries to list every library connected to the target file. Record library names, IDs, and whether each is enabled.
IF the result is empty: the file has no linked library. STOP here and ask the user (link a library, point to a different file, or explicitly approve custom primitives). Do not skip ahead to drawing.
Full library enumeration pass (NEW — required before per-need searches). For each enabled library, surface its page/folder structure (via mcp__figma__search_design_system with broad queries or library metadata). Then call mcp__figma__search_design_system with a wildcard / broad query (e.g. empty string, "*", or one query per library page) to capture every available component key. Build a structured inventory the agent can refer back to during Phase 3 mapping:
library_inventory = [
{ name: "Button / Primary", key: "comp:abc123", category: "atom", variants: ["sm", "md", "lg"] },
{ name: "SearchInput", key: "comp:def456", category: "atom", variants: ["with-icon", "with-clear"] },
{ name: "EmptyState", key: "comp:ghi789", category: "block", variants: ["illustration", "icon", "text"] },
…
]
This inventory is what Phase 3 maps /prd's component_mapping_intent against. Without it, Phase 3 is guesswork dressed as a table.
Discover compositions by library structure, not by name. Naming conventions vary by team (slashes, spaces, prefixes, none). Libraries are organized by page or folder much more reliably — atoms on one page, composed templates on another. After the inventory pass, report the page list to the user, and use AskUserQuestion: "These are the pages in your library: [list]. Which contain composed/template components I should prefer over atoms — or does your library not use compositions?" Search the user-named composition pages first for each Phase 2 need. A composition supersedes the atoms it would replace — record only the composition key, not its child atoms. If the user says no compositions exist, skip composition search and proceed straight to atomic search.
For each remaining need not satisfied by a composition, refine the inventory match with mcp__figma__search_design_system and a concrete query (e.g. "button primary", "card surface"). Record the returned component key, node ID, and library source.
Call mcp__figma__get_variable_defs to capture token IDs for colors, spacing, radii, and typography. These IDs — not hex codes — are what use_figma / generate_figma_design need to bind tokens.
If neither the full inventory nor a refined search returns a match for a need, mark it as a gap for Phase 3 to resolve with the user. Never silently substitute a custom primitive.
Mobbin reference research — flow-pattern first, then per-screen (MANDATORY when Mobbin connected). See _shared/mobbin-research.md for the full per-screen synthesis format (bullets, app attribution, URL coverage rules). The figma-specific steps below cover the flow-pattern discovery layer that sits on top of that shared workflow.
a. Flow-pattern discovery (run FIRST when the request spans multiple screens). Use the Mobbin capability mode recorded in Phase 0:
mcp__mobbin__search_screens({ query: "<full flow description, e.g. 'billing and subscription management flow'>", platform: "<ios|web>", limit: 8, mode: "deep" })
Then group results by app, feature area, and recurring UI structure. These are flow-pattern candidates, not guaranteed Mobbin flow objects.Report the top 3 candidates to chat before asking. Use one block per candidate:
**Flow Candidate <N> — <App / pattern name>**
- Fit: <why this matches the requested flow>
- Screens observed: <screen names or inferred stages>
- Strong patterns: <2-3 concrete patterns>
- Copy tone: <brief tone read>
- Evidence: <native flow metadata, or "inferred from screen results">
- Caveat: <missing screen, weak match, or none>
Then use AskUserQuestion: "Which flow pattern should anchor the screen-level searches?" The user's pick anchors all per-screen searches in step b — bias screen queries toward that app's conventions and copy tone.
Skip this sub-step ONLY when the request is a single isolated screen.
b. Per-screen search. For each anticipated screen:
mcp__mobbin__search_screens({ query: "<screen purpose>", platform: "<ios|web>", limit: 5, mode: "deep" })
If a flow-pattern candidate was chosen in step a, prefer results from that app/pattern when interpreting which patterns to highlight. Still mention stronger outside matches when they solve a screen better.
c. Report per-screen findings following the synthesis format in _shared/mobbin-research.md (4–7 bullets per screen, [App](URL) in every bullet, distinguish universal vs app-specific). If a screen returns no usable references, write No Mobbin matches for <screen> — proceeding from library only.
d. Evidence rules. Every Mobbin-derived recommendation must include:
observed directly or inferred.universal, app-specific, or a combination of multiple apps.e. Ask direction. After all per-screen reports are posted, use AskUserQuestion to pick the direction. Prefer one consolidated question over interrupting after every screen unless the flow is genuinely ambiguous. Reference report items by number:
Which direction should I use for Phase 2?
1. Follow Flow Candidate <N> closely for structure and tone.
2. Combine patterns from Screens <A/B/C>.
3. Use Mobbin only as reference and prioritize our design system.
4. Specify another direction.
Task list requirements:
Mobbin flow-pattern discovery → Report Mobbin flow-pattern findings → for each screen: Mobbin screen search: <X> → Report Mobbin findings: <X>Mobbin search: <screen> → Report Mobbin findings: <screen>The only legitimate skip is "Mobbin not connected" (record as gap). No "direct re-skin" escape.
Present consolidated findings — library names, component keys, variable IDs, Mobbin capability mode, selected flow-pattern candidate, Mobbin picks per screen, gaps — and use AskUserQuestion to confirm before Phase 2.
Goal: Convert complex flow into implementation-sized screens.
Before drawing, produce a page inventory:
| Field | Meaning | |-------|---------| | Page name | Human-readable screen name | | Route | Expected frontend route or screen ID | | User goal | Why this page exists | | Entry point | How user gets here | | Exit point | Where user goes next | | Primary actions | Buttons/actions that must be implemented | | Data needed | API/model data shown on the page | | States | Default, loading, empty, error, disabled, permission denied, success |
Use shadcn-friendly implementation boundaries where applicable: Button, Input, Form, Card, Dialog, Sheet, Tabs, Table, Dropdown, Badge, Toast, Accordion, Checkbox, RadioGroup, Select, Switch, Tooltip.
Present the inventory and use AskUserQuestion to confirm before mapping design-system assets.
Goal: Decide exactly what linked Figma assets will be used.
For each page/component, map. The "Figma key/ID" column must contain a real key returned by search_design_system or get_variable_defs — not a name, not a placeholder. If a row has no real key, it's a gap, not a match.
| Code / Need | Figma asset | Figma key/ID | Source | Action |
|-------------|-------------|--------------|--------|--------|
| Button primary | Button / Primary | comp:abc123 (from search_design_system) | Linked library "DS Core" | Reuse as instance |
| Color / background | --surface-bg | var:xyz789 (from get_variable_defs) | Linked library "DS Tokens" | Bind variable |
| Form field | Input | comp:def456 | Local component | Reuse as instance |
| Empty state illustration | None | — | Gap | Ask before creating |
Rules:
[Reference / Gap] frame next to the mockup so the user can see the gap and decide._shared/design-knowledge/references/aesthetic-direction.md [Skill ref] so the question is grounded in concrete aesthetic vocabulary (committed direction, restraint, clarity).Present the mapping and use AskUserQuestion to confirm before writing anything.
Use this path when the user asks to create, sync, or reconcile Figma design-system assets from code.
Before starting Phase 4A, also load figma-generate-library via ReadMcpResourceTool (server: figma, uri: skill://figma/figma-generate-library/SKILL.md). It covers what to build and in what order — variables, text styles, effect styles, components, variants — so the design system comes out professional-grade.
Use this path when the user asks for Figma mockups, screens, pages, or journey-informed designs.
Pre-flight (gate the phase):
figma-use guidance loaded. Writer = use_figma (default); generate_figma_design only as web-app screenshot reference.use_figma must call await figma.importComponentByKeyAsync("<key>") before any .createInstance(). Bind variables via figma.variables.getVariableByIdAsync("<var-id>") — no inline hex. See figma-use guidance (Phase 0.5) for the full Plugin API skeleton.If any pre-flight item is incomplete, return to that earlier phase.
Present the mockup plan: frame names, routes, sections, reused assets listed with actual keys/IDs from Phase 3, Flow Page contents (ordered journey steps from /prd's flow_steps[], each line tagged with [AC-X]), Dev Mode annotation plan (which interactive elements get implements: AC-X annotations referencing which AC), required states as text references to /prd's state_list[] (not as separate mockup frames — see step 7).
Use AskUserQuestion to confirm.
Build with use_figma. Pass Phase 3 keys to code; JS calls figma.importComponentByKeyAsync(key) then .createInstance(). For web-app pixel-perfect copies, run generate_figma_design in parallel as a screenshot reference, refine use_figma to match, then delete the screenshot output. For PRD/intent/iOS/Android, skip generate_figma_design.
generate_figma_design, load its companion guidance first: ReadMcpResourceTool with server: figma, uri: skill://figma/figma-generate-design/SKILL.md.Mobbin reference rule — borrow concept, use library:
getVariableByIdAsync.[Reference / Gap] <element name>, showing what's needed. This makes the gap visible without polluting the mockup with custom primitives. User decides next steps.Generate the Flow Page first (before any per-screen frames). One dedicated frame at the file root named Flow (or Flow Page per the Notion convention) listing /prd's flow_steps[] as ordered text — no UI chrome, just steps with screen refs and [AC-X] tags in the exact format:
Step 1: Empty Dashboard → +Add tap → Add Service modal [AC-1, AC-2]
Step 2: Service modal → Submit → Success toast [AC-3]
Step 3: Submit failure → Inline validation message [AC-4, AC-5]
This frame is the canonical journey for downstream /vorbit:implement:epic and /vorbit:implement:implement. Don't add visuals; the screens themselves carry the visual.
Add Dev Mode annotations on every interactive element (buttons, inputs, links, toggles, dropdowns, checkboxes, radios) as you build each screen. Use data-development-annotations containing implements: AC-X referencing the PRD acceptance criterion that governs the element. Pin-style canvas annotations have NOT been validated as agent-readable downstream — only Dev Mode annotations work. Per [[reference_figma_metadata_authoritative_fields]], get_metadata will surface these in the annotations field, which is what /vorbit:implement:implement and /vorbit:implement:verify consume.
Bind variables by ID (figma.variables.getVariableByIdAsync + setBoundVariable); no inline hex.
Happy path only — no state-variant frames. Mock the success/default state of each screen. Do NOT create separate frames for empty/loading/error/permission-denied — those live as AC text in /prd's state_list[] and are realized only in code per AC. Multi-state mockups duplicate spec and drift; keep Figma to the canonical happy path so the visual contract stays single-source-of-truth.
Name frames by page, route, section. Use auto-layout and stable hierarchy.
Validate with get_metadata and get_screenshot. Post-write checks (mandatory, blocking) — get_metadata is the source of truth, not the JS you wrote:
<frame> not <instance>. <text> nodes with emoji where icon components should be.mainComponent.name (full path including variant) matches the exact Phase 3 row. Button / Primary ≠ Button / Secondary — right component, wrong variant still fails.boundVariables set in metadata. A SOLID fill with a raw {r,g,b} color where a variable was declared = silent override.overrides; flag any that change fills, strokes, corner radius, or padding to non-Phase-3 values.Flow (or Flow Page) exists, containing ordered steps with [AC-X] tags matching /prd's flow_steps[]. Missing or empty Flow Page = fail; regenerate.INSTANCE node whose component category is interactive (button / input / link / toggle / dropdown / checkbox / radio) has a Dev Mode annotation containing implements: AC-X referencing a valid PRD acceptance-criterion ID. Missing annotation = fail; attach via use_figma corrective JS.use_figma with corrective JS — re-import via importComponentByKeyAsync, re-bind via getVariableByIdAsync + setBoundVariable, strip overrides, or attach annotations.Use AskUserQuestion after each page before continuing.
Final report must include:
/vorbit:implement:epic reads this for the canonical journeyimplements: AC-X, and any unannotated elements flagged/prd's state_list[], not as separate frames)use_figma succeeding is the floor. Without inventory, mapping, Mobbin, and confirmations, the output is shapes-with-keys, not design.generate_figma_design as the main writer — it's reserved for web-app screenshot reference. use_figma is the default writer.use_figma without loading figma-use first — covers Plugin API gotchas that cause silent JavaScript failures.importComponentByKeyAsync calls — the keys must appear in actual importComponentByKeyAsync(...) calls in the JS body, not just in comments or the description parameter. Otherwise the library components aren't imported and the result is orphan frames named like the components but unlinked.generate_figma_design) seeds it first.development
Sync design tokens and components from a codebase to a Pencil canvas (`.pen` files), or set up a Pencil canvas from a style guide when no codebase exists. Use when the user says "sync pencil", "setup pencil", "configure pencil", "pencil sync", "sync tokens to pencil", "build pencil component library", or names Pencil/`.pen` files explicitly. Also triggers when mockups generated by Pencil don't match project conventions.
development
Use when the user wants to build Webflow pages, templates, or components, with or without Figma designs as reference.
testing
Use when the user wants to verify an implementation, validate acceptance criteria, or run a Vorbit-style post-change check using shared project rules.
testing
Use when any skill needs to clarify user experience requirements through exhaustive questioning. Transforms vague requirements into precise acceptance criteria.