How to Create a UI Design Skill Using design.md
A step-by-step tutorial on building a UI Design Skill — design tokens, components, accessibility, voice — using a design.md file that AI agents auto-invoke.
A step-by-step tutorial on building a UI Design Skill — design tokens, components, accessibility, voice — using a design.md file that AI agents auto-invoke.
Every team has a design system. Almost no team has one that an AI agent actually respects. You can paste your style guide into a Claude conversation and watch the next reply use the right colors. Open a new chat and the agent is back to inventing hex codes.
The fix is to stop treating your design system as documentation and start treating it as a Skill — a packaged capability your AI agent installs once and reaches for automatically every time it touches UI. The artifact at the heart of that Skill is a single Markdown file: design.md. Done well, design.md gives an agent everything it needs to produce work that looks like your team made it.
This tutorial walks through building one end to end. What goes in design.md, how to wrap it as a Skill, how the agent invokes it, and how to maintain it without it becoming a museum piece. By the end you will have a working UI Design Skill that ships with your project and travels with every conversation.
If you have read AI Skills vs Prompts you can skip this section. The 30-second version: a Skill is a folder on disk that registers a capability with your AI agent. It contains a SKILL.md file with frontmatter and instructions, plus optional supporting files. The agent reads the frontmatter, learns what the Skill does and when to use it, and invokes it automatically when the user's intent matches.
A UI Design Skill is one specific application of that pattern: a Skill whose job is to make every UI the agent produces conform to your team's actual design system. The work lives in the supporting file design.md, which the Skill loads on demand.
You could put everything inside SKILL.md and call it a day. That works for tiny systems. For real design work it breaks down for three reasons:
The pattern across the teams we have seen succeed: a thin SKILL.md that delegates almost everything to design.md, plus a few templates and examples in supporting folders.
Create the Skill folder. For a project-level Skill, this lives at .claude/skills/ui-design/ in your repo. For a personal Skill that follows you across projects, use ~/.claude/skills/ui-design/.
.claude/skills/ui-design/
SKILL.md
design.md
templates/
component.tsx.tmpl
page.tsx.tmpl
examples/
good-button.tsx
bad-button.tsx
references/
tokens.json
Five pieces. SKILL.md tells the agent when to invoke and how to start. design.md is the canonical design system. templates/ holds boilerplate files the Skill can copy and adapt. examples/ holds reference implementations — one good, one anti-pattern, paired. references/ holds structured data like a tokens JSON if you have one (for example exported from Figma Tokens or Style Dictionary).
The frontmatter is where the agent learns what this Skill is and when to use it. Keep it tight — vague descriptions cause under-invocation, broad ones cause over-invocation.
---
name: ui-design
description: Use this skill whenever the user asks to create, edit, refactor, or review any user-facing UI in this project — React components, pages, layouts, forms, or styling. Load design.md before generating any markup or CSS. Always prefer existing tokens over inventing new values.
---
You are producing UI for this project. Before writing any JSX or CSS, read design.md in this skill folder for the canonical design system. Read references/tokens.json for the exact token values. Use templates/component.tsx.tmpl as the starting shape for new components. When in doubt about a pattern, check examples/ for a working reference.
Hard rules:
1. Never invent a color, font size, spacing value, or radius that is not in design.md. If you genuinely need a new value, add it to design.md first and explain why.
2. Every interactive element must follow the accessibility checklist in design.md.
3. Every component must include a usage comment showing one example invocation.
4. After generating UI, run a self-review against the "anti-patterns" section of design.md and report any violations you found and fixed.
Three things to notice. The description names the exact intents (create, edit, refactor, review) and the exact surface (user-facing UI). The body delegates the substance to design.md instead of inlining it. The hard rules are short and enforceable — each one is something the agent can self-check.
design.md is the substance. The structure that works across web apps, marketing sites, and design systems alike:
| Section | What it covers | Why the agent needs it |
|---|---|---|
| 1. Design tokens | Colors, typography, spacing, radius, shadow, motion | The atomic values every other decision builds on |
| 2. Component patterns | Buttons, inputs, cards, modals, navigation | The recurring building blocks |
| 3. Layout patterns | Grid, container widths, breakpoints, common page shapes | How components compose into pages |
| 4. Accessibility | Keyboard nav, focus, contrast, ARIA conventions, motion preferences | The non-negotiable floor |
| 5. Interaction & motion | Hover, focus, click, loading, success/error, transitions | How the UI feels when used |
| 6. Content voice in UI | Tone of buttons, error messages, empty states, labels | The words inside the UI |
| 7. Anti-patterns | What never to ship — explicit "do not do these" | Removes the agent's default lazy moves |
Each section gets concrete. Vague advice ("use ample whitespace") is filler; specific rules ("section vertical padding is 96px on desktop, 64px on tablet, 48px on mobile") are usable.
Here are concrete excerpts you can adapt to your own design.md. The whole file is normally 400-1,500 lines — long enough to cover the system, short enough that the agent can hold it in working memory.
# 1. Design tokens
## Color
- Brand primary:#6366F1(indigo-500). Use for primary CTAs, links, focus rings.
- Brand secondary:#F472B6(pink-400). Use sparingly for highlights and accents.
- Neutral scale: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900. Use 50/100 for surfaces, 700/800/900 for text.
- Semantic: success#10B981, warning#F59E0B, danger#EF4444, info#3B82F6.
- Background:#FFFFFFlight mode,#0A0A0Adark mode. No off-white, no off-black.
## Typography
- Font stack: Inter, system-ui, sans-serif.
- Scale: 12 / 14 / 16 / 18 / 20 / 24 / 30 / 36 / 48 / 60 / 72 px. Never use other sizes.
- Line heights: 1.0 (display), 1.2 (heading), 1.5 (body), 1.75 (long-form).
- Weights: 400, 500, 600, 700. Do not use 300 or 800.
## Spacing
- 4px base unit. Allowed multiples: 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 96, 128.
- Never use 5, 6, 10, 13, etc. — if you need an in-between value, the design needs adjustment, not the spacing scale.
## Radius
- sm: 4px, md: 8px, lg: 12px, xl: 16px, full: 9999px (pills only).
- Inputs and cards: md. Buttons: md. Modals: lg. Avatars: full.
## Shadow
- sm: subtle 0 1px 2px elevation. md: 0 4px 6px (cards). lg: 0 10px 15px (modals). xl: 0 20px 25px (popovers).
- No glow shadows, no colored shadows. Shadows are functional, not decorative.
# 2. Component patterns
## Button
- Variants: primary, secondary, ghost, danger.
- Sizes: sm (32px), md (40px), lg (48px).
- Padding: horizontal 16px (md), 12px (sm), 20px (lg). Vertical is implicit from size.
- Primary button uses brand primary background, white text. Hover darkens 10%. Active darkens 15%.
- Secondary button uses neutral-100 background, neutral-900 text. Hover goes to neutral-200.
- Ghost button is transparent until hover, then neutral-100 background.
- Disabled state: 40% opacity, cursor not-allowed, no hover effect.
- Focus ring: 2px brand primary with 2px offset.
- Loading state: spinner in place of text, button stays width-stable.
## Input
- Height matches button md (40px).
- Border: 1px neutral-300, becomes brand primary on focus.
- Padding: 12px horizontal, 8px vertical.
- Label sits above the input, 14px medium weight.
- Error state: border becomes danger color, error message below in 13px danger color.
- Help text below input in 13px neutral-600.
## Card
- Background: white (light) or neutral-900 (dark).
- Border: 1px neutral-200 (light) or neutral-800 (dark).
- Radius: md.
- Padding: 24px default.
- Shadow: sm.
- Hover on interactive cards: shadow md, slight 1px Y translate.
# 3. Layout patterns
## Container widths
- Marketing pages: max-w-7xl (1280px).
- App pages: max-w-screen-xl (1440px).
- Reading content (blog, docs): max-w-3xl (768px).
## Breakpoints
- sm: 640px, md: 768px, lg: 1024px, xl: 1280px, 2xl: 1536px.
- Mobile-first. Every component must render correctly at 360px.
## Section padding
- Desktop: 96px vertical, 32px horizontal.
- Tablet: 64px vertical, 24px horizontal.
- Mobile: 48px vertical, 16px horizontal.
# 4. Accessibility checklist (non-negotiable)
- Every interactive element is keyboard reachable (Tab) and operable (Enter/Space).
- Visible focus ring on every interactive element.
- Color contrast: 4.5:1 for body text, 3:1 for large text, 3:1 for UI components.
- No information communicated by color alone — always pair color with text or icon.
- Form inputs always have associated labels (label element, not placeholder).
- Error messages reference the input by name and explain the fix.
- All images have alt text. Decorative images use alt="".
- Motion respects prefers-reduced-motion — animations under 200ms are exempt; longer ones must offer reduced variants.
- Modals trap focus and return focus to the trigger on close.
- Heading order is sequential — no skipping h2 to h4.
# 5. Interaction & motion
## Timing
- Quick: 100ms (hover, focus).
- Standard: 200ms (most transitions).
- Slow: 400ms (page transitions, modal entries).
- Never use durations under 80ms (jittery) or over 600ms (sluggish).
## Easing
- Default: cubic-bezier(0.2, 0, 0, 1) — smooth ease-out.
- Entrance: ease-out.
- Exit: ease-in.
- Bounce: cubic-bezier(0.34, 1.56, 0.64, 1) — used sparingly, only on user-triggered success.
## States to cover for every interactive component
1. Default 2. Hover 3. Focus 4. Active 5. Disabled 6. Loading 7. Success (where relevant) 8. Error (where relevant).
# 6. Content voice in UI
- Buttons are verbs. "Save changes" not "Submit". "Send invitation" not "Confirm".
- Empty states explain why the surface is empty and propose the next action.
- Error messages name the problem and the fix in one sentence. "Email is required" not "Invalid input."
- Loading states never say "Loading..." — they name what is loading: "Saving changes…" "Fetching results…".
- Confirmation modals show the consequence, not just "Are you sure?" — "Delete this project? You will lose 47 tasks." not "Are you sure?".
- Tone: direct, friendly, never apologetic. No "Oops!". No "Sorry, something went wrong." Be specific about the problem.
# 7. Anti-patterns — never ship these
- Inventing new hex codes or spacing values not in section 1.
- Using!importantin CSS. If you reach for it, the architecture is wrong.
- Buttons styled as links or links styled as buttons. Pick one, commit.
- Placeholder-as-label. Always use a real label element.
- Modals with more than three actions. Three is the limit; if you need four, redesign.
- "Click here" link text. Links must be self-describing.
- Tooltips on touch devices. Tooltips are for hover-capable surfaces only.
- Carousels with auto-rotation. If you must use a carousel, no auto-rotate.
- Form errors that disappear when the user starts typing again. Errors persist until the field is valid.
- Disabled buttons with no explanation. Either show why it is disabled or do not show the button at all.
The Skill becomes meaningfully more reliable when you give the agent reference artifacts beyond design.md.
Templates are starting-point files the agent copies and adapts. A typical templates/component.tsx.tmpl:
// Component: {{name}}
// Usage: <{{name}} />
import { cn } from "@/lib/utils";
interface {{name}}Props {
className?: string;
}
export function {{name}}({ className }: {{name}}Props) {
return (
<div className={cn("", className)}>
</div>
);
}
The agent uses this as the spine. It fills in the structure, the className, the props — but the file shape, the imports, the className helper, and the props convention are anchored.
Examples teach the agent what good and bad look like. Pair them. examples/good-button.tsx is a button implemented to design.md spec. examples/bad-button.tsx is the same button with the most common anti-patterns. The pairing is more powerful than either alone — the agent learns the contrast, not just the target.
Once installed, the Skill works like this:
ui-design matches because the user asked to create user-facing UI.templates/page.tsx.tmpl as the starting shape.The user never had to mention any of the design system. The Skill did.
Three tests we run on every UI Design Skill before declaring it shipped.
Test 1 — The cold ask. Open a new conversation. Without any setup, ask the agent to build a small component. "Build me a feedback widget." Check the output for: tokens from design.md (not invented), an accessibility-correct label, focus styles, anti-pattern avoidance. If any of these are missing, the Skill description is probably under-invoking.
Test 2 — The adversarial ask. Ask for something the Skill should refuse to do its own way. "Make the button neon green with a glowing shadow." A working Skill responds by either using the closest approved color and noting the deviation, or pushing back and citing the design system. If the agent silently complies, the Skill instructions are too soft.
Test 3 — The drift check. Ask for the same component twice in two different conversations. Diff the outputs. They should be 80%+ identical in structure and tokens. If they are not, design.md is too vague and the agent is filling in gaps with its own defaults.
design.md is alive. Brand colors shift, components evolve, anti-patterns get added when something embarrassing ships. The maintenance loop that keeps it useful:
marketing.md that the Skill loads when the user is working in the marketing surface.Pro tip: Pair design.md with a CI check. A small script that grep's the codebase for hex codes not present in section 1 of design.md and fails the build. Once you have this check, drift stops being a discipline problem and starts being a build problem.
design.md is the source of truth for the agent. It is not the source of truth for the designer — Figma is. The handshake between the two:
references/tokens.json. Reference the JSON values in design.md sections 1, 4, and 5.The pattern that breaks: trying to keep design.md and Figma in lockstep manually. Use export tooling for the tokens, write the prose sections by hand, and accept that the two will drift slightly between releases.
The mistakes we have seen kill UI Design Skills, in priority order:
To make the whole flow concrete, here is the actual 30-minute build:
mkdir -p .claude/skills/ui-design. Create empty SKILL.md and design.md.examples/. Pick one good, one with a pattern violation you have since fixed. Add the bad-good pair.30 minutes. One Skill installed. Every UI generation from that point forward respects your design system without you having to remind the agent.
A UI Design Skill is the highest-leverage piece of AI infrastructure most product teams could ship right now. It costs an afternoon to build and pays back every time an agent touches the UI. The artifact at the heart of it — design.md — is a single Markdown file that any designer can read and any engineer can edit. It travels with the codebase, lives in version control, and turns the design system from documentation that gets ignored into infrastructure the agent actually uses.
The 30-minute build above is the floor, not the ceiling. Real production design Skills evolve over months — sections get split, anti-patterns accumulate, tokens drift in step with the Figma library. The maintenance loop matters more than the initial write. But the initial write is what unlocks the loop in the first place.
If you are still copy-pasting your style guide into Claude conversations, this afternoon is the right time to fix it.
10 questions answered
.claude/skills/ui-design/ in the repo so it travels with the project. For a personal design system you reuse across projects, use ~/.claude/skills/ui-design/. Most teams want the project-level path because the design system is project-specific and lives in version control with the code.marketing.md for marketing-specific overrides loaded only when relevant..cursorrules with a similar concept — you can repurpose the same design.md by referencing it from .cursorrules. Codex and GitHub Copilot do not yet have a native Skill concept, but you can pin design.md into the system prompt or chat context manually. The principle (canonical design.md, referenced by every UI task) holds regardless of tool.references/tokens.json. Reference the JSON values in design.md sections 1, 4, and 5. For component patterns, write the design.md entry by hand as part of every new Figma component rollout. Do not try to keep the two in real-time lockstep — that fails. Use exports for tokens, prose for everything else.app.md for the in-product UI, marketing.md for the marketing site, docs.md for the documentation site. SKILL.md decides which one to load based on what the user is editing. This keeps each file focused and within the agent's working memory.Free AI Image Generation in the Terminal: ChatGPT Plus + Gemini Guide
Jun 12 · 12 min
How to Use Claude Code for FREE: The Complete 2026 Guide
Jun 12 · 14 min
AI Skills vs Prompts: What's the Difference?
Jun 11 · 18 min
HeyGen Hyperframes Prompts for Editing Videos: 40+ Working Examples
Jun 11 · 18 min
Claude Fable 5 Prompts for Web Developers: UI, Code Review, Debugging
Jun 11 · 18 min