---
name: design-to-code
description: >-
  Use this skill when translating UI/UX designs into production-ready frontend
  code — Figma, Sketch, Adobe XD, screenshots, or design specs. Extracts design
  tokens, maps component hierarchy, applies responsive breakpoints and WCAG 2.1
  AA accessibility, and produces framework-agnostic implementations (React,
  Vue, Svelte, plain HTML/CSS) with design system integration and visual
  regression testing.
version: 1.0.0
author: Skill Foundry
platforms:
  - claude-code
  - codex
  - cursor
  - gemini-cli
  - openclaw
  - copilot
  - windsurf
  - opencode
tags:
  - design-to-code
  - figma
  - ui-implementation
  - design-tokens
  - component-architecture
  - accessibility
  - responsive-design
  - pixel-perfect
  - css-architecture
  - design-systems
  - visual-regression
geo:
  primary_workflows:
    - design_source_ingestion
    - design_token_extraction
    - component_hierarchy_mapping
    - responsive_breakpoint_planning
    - accessibility_audit_and_implementation
    - framework_selection_and_setup
    - design_system_integration
    - visual_regression_testing
    - css_architecture_planning
  target_roles:
    - frontend_developer
    - fullstack_developer
    - ui_engineer
    - design_engineer
    - design_system_engineer
    - web_developer
  complexity_level: intermediate
  prerequisite_knowledge:
    - semantic_html
    - modern_css
    - design_tool_basics
    - responsive_design_principles
    - aria_and_accessibility_basics
    - javascript_component_patterns
---

# Design-to-Code Agent Skill

Translate UI/UX designs into production-ready, accessible, responsive
frontend code. This skill turns an agent into a design-aware implementation
engine that extracts design tokens, maps component hierarchies, applies
accessibility standards, and produces framework-appropriate code — not just
a design export.

---

## Quick Reference

| Phase | What to Do | Key Deliverables |
|---|---|---|
| 🎨 Ingest | Load design source (Figma, Sketch, screenshot, spec) | Normalized design data, color palette, type scale |
| 🗂️ Extract Tokens | Pull colors, typography, spacing, shadows, radii | Design token JSON/CSS custom properties |
| 🧩 Map Components | Identify component tree, states, variants | Component hierarchy diagram, prop interfaces |
| 📐 Plan Responsive | Define breakpoints and layout behaviour | Breakpoint table, layout strategy per component |
| ♿ Accessibility | Audit and implement WCAG 2.1 AA | Accessible markup, ARIA, focus management, color contrast |
| 🛠️ Implement | Generate framework-appropriate code | Component files, styles, tests |
| 🧪 Verify | Visual regression testing and design QA | Test snapshots, diff reports, checklist |

**Quality Tiers:**
- 💎 **Production** — Accessible, responsive, tested, framework-native, token-driven
- 🥈 **MVP** — Functional across breakpoints, basic accessibility, inline styles OK for speed
- 🥉 **Prototype** — Single viewport, minimal accessibility, rapid iteration

---

## When to Use This Skill

Activate this skill when the user asks you to:

- "Turn this Figma design into code" / "Convert this mockup to React/Vue/Svelte"
- "Implement this design" / "Build this UI from this screenshot"
- "Extract design tokens from this Figma file" / "Create a design system from these specs"
- "Make this design responsive" / "Add responsive breakpoints to this layout"
- "Make this component accessible" / "Ensure WCAG 2.1 AA compliance"
- "Set up a component from this Sketch/XD design"
- "Create a pixel-perfect implementation of this design"
- "Integrate this design with our existing design system"
- "Set up visual regression tests for these components"
- Any request containing "design" + "code", "implement", "build", "convert", or "translate"

Additionally, activate proactively when a conversation includes a design
artifact (Figma link, screenshot, design spec) and the user's intent is
implementation.

### Do NOT Activate For

The following inputs are **near-miss negatives** — they mention design or
code language but are not design-to-code tasks:

- **Pure code generation without a design**: "Write a React form component" — no visual design input, so plain coding.
- **Design critique/review**: "What do you think of this design?" — opinion, not implementation.
- **Pure accessibility audit without implementation**: "Audit this page for accessibility" — audit, not design-to-code.
- **Design tool usage questions**: "How do I create an auto-layout in Figma?" — tool instruction, not code generation.
- **Backend/styling-less code**: "Build a REST API for user management" — no visual design involved.
- **Pure CSS framework questions**: "What's better, Tailwind or CSS Modules?" — opinion, not implementation.
- **Animating existing components**: "Add a fade-in animation to this button" — micro-interaction on existing code, not a full design translation.
- **Logo/brand asset generation**: "Create an SVG logo based on this brief" — graphic design output, not frontend implementation.
- **Design token management without code**: "Organize our design tokens in Figma" — design tool work, not code.

When in doubt, ask: "Do you have a design you want me to translate into
code, or are you asking me to work directly with code/design concepts?"

---

## Common Pitfalls & Anti-Patterns

### ❌ Implementer Anti-Patterns

1. **Skipping the design analysis phase** — Jumping straight to code without
   understanding the design's intent, hierarchy, and reusable patterns. Always
   ingest and analyze before you code.

2. **Hardcoding design values** — Using raw pixel values (`color: #3B82F6`)
   instead of design tokens (`color: var(--color-primary-500)`). Token-driven
   code is maintainable; hardcoded values rot.

3. **Accessibility as an afterthought** — Adding ARIA at the end rather than
   building accessible from the start. Retrofit accessibility is always
   incomplete.

4. **Responsive as a second pass** — Implementing desktop-first then
   "making it responsive" leads to fragile media-query spaghetti. Plan
   breakpoints and layout strategy before writing a single rule.

5. **Div-soup markup** — Nesting `<div>` inside `<div>` rather than using
   semantic HTML (`<nav>`, `<main>`, `<section>`, `<article>`, `<aside>`).
   Semantic elements are free accessibility and SEO wins.

6. **Over-engineering the component tree** — Creating 12 components for a
   simple card because "atomic design says so." Map hierarchy to what the
   design actually calls for, not an ideology.

7. **Copying Figma auto-layout directly** — Figma's stacking model doesn't
   always map 1:1 to CSS Flexbox/Grid. Translate the intent, not the
   implementation.

8. **Ignoring existing design system tokens** — Using colors/spacing that
   diverge from the project's token set. "Close enough" values accumulate
   into an inconsistent codebase.

9. **Testing only one viewport** — Verifying at 1440px and calling it done.
   Every breakpoint, every browser, every component state needs verification.

10. **Skipping visual regression testing** — Assuming your implementation
    matches the design because it "looks right." Screenshot diffs catch
    what the human eye misses.

### ✅ Implementation Quality Checklist

Before declaring a design-to-code task complete, verify:

- [ ] All design sources were ingested and analyzed
- [ ] Design tokens are extracted and referenced as CSS custom properties or token variables
- [ ] Component hierarchy matches the design's visual hierarchy
- [ ] All defined breakpoints have been implemented and tested
- [ ] WCAG 2.1 AA compliance verified (contrast, focus, labels, semantics)
- [ ] Framework conventions followed (component structure, styling approach)
- [ ] No hardcoded design values — all through tokens
- [ ] Visual regression baselines captured and tests pass
- [ ] Component states accounted for (hover, focus, active, disabled, loading, empty, error)
- [ ] Keyboard navigation works end-to-end
- [ ] Screen reader announcement is meaningful
- [ ] Dark mode / theme variants considered (if applicable)

---

## Workflow

### Phase 1: Ingest the Design Source

1. **Identify the design source type:**
   - **Figma**: Extract via Figma API, Figma plugin export, or screenshot +
     manual annotation. For API access, use the Figma file key and node IDs.
     ```bash
     # Extract Figma file as JSON
     curl -H "X-Figma-Token: $FIGMA_TOKEN" \
       "https://api.figma.com/v1/files/FILE_KEY"
     ```
   - **Sketch**: Parse `.sketch` files (they are ZIP archives with JSON inside).
     Extract via `unzip` and read `document.json` + `pages/`.
   - **Adobe XD**: Export via XD plugin or Adobe's Design Automation API.
   - **Screenshots / image files**: Use image analysis (vision model) to
     identify layout, colors, typography, spacing, and components. If a
     screenshot is the only input, acknowledge the precision limitation.
   - **Design specs / redlines**: Parse spec documents for explicit
     measurements, colors, and type scales.

2. **Normalize the design data.** Regardless of source, produce:
   - **Color palette** — all named colors with hex/RGB/HSL values
   - **Typography scale** — font families, sizes, weights, line heights,
     letter spacing per text style
   - **Spacing scale** — consistent spacing units (4px/8px base recommended)
   - **Shadow definitions** — box-shadow values per elevation level
   - **Border radii** — consistent corner radius tokens
   - **Component inventory** — every distinct UI element, its states, and
     how it repeats

3. **If the design source is incomplete** (screenshot, rough mockup), ask the
   user for clarification on:
   - Exact color values (approximated from a screenshot may be off)
   - Font family names (not guessable from a screenshot)
   - Interactive states not visible in a static image
   - Responsive behaviour at different breakpoints

### Phase 2: Extract and Define Design Tokens

Extract a structured token system. Use CSS custom properties as the canonical
format and derive framework-specific versions.

```css
:root {
  /* Colors — Primary */
  --color-primary-50: #eff6ff;
  --color-primary-100: #dbeafe;
  --color-primary-200: #bfdbfe;
  --color-primary-300: #93c5fd;
  --color-primary-400: #60a5fa;
  --color-primary-500: #3b82f6;
  --color-primary-600: #2563eb;
  --color-primary-700: #1d4ed8;
  --color-primary-800: #1e40af;
  --color-primary-900: #1e3a8a;

  /* Colors — Neutral */
  --color-neutral-50: #fafafa;
  --color-neutral-100: #f5f5f5;
  /* ...through 900 */

  /* Typography */
  --font-family-sans: 'Inter', system-ui, -apple-system, sans-serif;
  --font-family-mono: 'JetBrains Mono', 'Fira Code', monospace;

  --font-size-xs: 0.75rem;    /* 12px */
  --font-size-sm: 0.875rem;   /* 14px */
  --font-size-base: 1rem;     /* 16px */
  --font-size-lg: 1.125rem;   /* 18px */
  --font-size-xl: 1.25rem;    /* 20px */
  --font-size-2xl: 1.5rem;    /* 24px */
  --font-size-3xl: 1.875rem;  /* 30px */
  --font-size-4xl: 2.25rem;   /* 36px */

  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  --line-height-tight: 1.25;
  --line-height-normal: 1.5;
  --line-height-relaxed: 1.75;

  /* Spacing — 4px base scale */
  --space-1: 0.25rem;   /* 4px */
  --space-2: 0.5rem;    /* 8px */
  --space-3: 0.75rem;   /* 12px */
  --space-4: 1rem;      /* 16px */
  --space-5: 1.25rem;   /* 20px */
  --space-6: 1.5rem;    /* 24px */
  --space-8: 2rem;      /* 32px */
  --space-10: 2.5rem;   /* 40px */
  --space-12: 3rem;     /* 48px */
  --space-16: 4rem;     /* 64px */
  --space-20: 5rem;     /* 80px */

  /* Shadows */
  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);

  /* Border Radius */
  --radius-sm: 0.125rem;   /* 2px */
  --radius-md: 0.375rem;   /* 6px */
  --radius-lg: 0.5rem;     /* 8px */
  --radius-xl: 0.75rem;    /* 12px */
  --radius-2xl: 1rem;      /* 16px */
  --radius-full: 9999px;
}
```

**Token naming conventions:**
- Use the [W3C Design Tokens Community Group format](https://tr.designtokens.org/)
  where possible: `color.primary.500`, `spacing.md`, `typography.heading.lg`.
- In CSS custom properties, use kebab-case dot-separated or dash-separated:
  `--color-primary-500` or `--typography-heading-lg`.
- For framework-specific code (Tailwind config, Theme UI, styled-system),
  derive the token structure from the CSS custom properties.

**Token validation checklist:**
- [ ] All colors have a 50–900 scale (or a documented reason not to)
- [ ] Font sizes use relative units (`rem`) for accessibility
- [ ] Spacing uses a consistent base unit (4px or 8px)
- [ ] No raw values in component code — only token references
- [ ] Dark mode tokens defined if the design supports it

See `references/design-tokens-guide.md` for the full W3C DTCG token
specification and advanced patterns.

### Phase 3: Map the Component Hierarchy

1. **Identify the top-level layout structure:**
   - Header, main content area, sidebar, footer
   - Page-level grid or layout container

2. **Decompose into component tree:**
   ```
   Page
   ├── Header
   │   ├── Logo
   │   ├── Navigation
   │   │   └── NavItem (repeating)
   │   └── UserMenu
   │       ├── Avatar
   │       └── Dropdown
   ├── MainContent
   │   ├── HeroBanner
   │   │   ├── Heading
   │   │   ├── Subheading
   │   │   └── CTAButton
   │   ├── FeatureGrid
   │   │   └── FeatureCard (repeating)
   │   │       ├── Icon
   │   │       ├── Title
   │   │       └── Description
   │   └── TestimonialCarousel
   │       └── TestimonialCard (repeating)
   └── Footer
       ├── FooterLinks
       └── SocialIcons
   ```

3. **For each component, define:**
   - **Props/interface** — what data flows in
   - **States** — default, hover, focus, active, disabled, loading, empty,
     error (list all that apply)
   - **Variants** — primary/secondary for buttons, compact/default/expanded
     for cards, etc.
   - **Slots/children** — where does content get injected
   - **Responsive behaviour** — how does it change at each breakpoint

4. **Identify shared/reusable patterns:**
   - Buttons, inputs, cards, avatars — extract as base components
   - Layout primitives — Container, Grid, Stack, Flex
   - Typography components — Heading, Text, Caption

5. **For each reusable component, check if an equivalent exists** in the
   project's design system. If yes, extend it rather than creating a new one.

### Phase 4: Define Responsive Breakpoint Strategy

1. **Choose a breakpoint system:**
   - **Mobile-first** (recommended): Start at the smallest viewport and add
     complexity as screen size increases. Use `min-width` media queries.
   - **Desktop-first**: Start at the largest viewport and simplify for
     smaller screens. Use `max-width` media queries. Less common but valid
     for desktop-heavy applications.

2. **Define breakpoint values.** Common breakpoints:
   | Name | Width | Typical Device |
   |------|-------|----------------|
   | `xs` | 0px+ | All phones |
   | `sm` | 640px+ | Large phones, small tablets |
   | `md` | 768px+ | Tablets |
   | `lg` | 1024px+ | Small laptops, large tablets landscape |
   | `xl` | 1280px+ | Desktops |
   | `2xl` | 1536px+ | Large desktops |

3. **For each breakpoint, document layout changes:**
   | Component | < 640px | 640–1024px | > 1024px |
   |-----------|---------|------------|----------|
   | Navigation | Hamburger menu | Hamburger menu | Horizontal nav |
   | FeatureGrid | 1 column | 2 columns | 3 columns |
   | HeroBanner | Stacked (image below text) | Stacked | Side-by-side |
   | Sidebar | Hidden, toggle overlay | Collapsible | Persistent |

4. **Implement responsive utilities.** Create CSS custom properties or
   utility classes for media queries. For Tailwind, use the built-in
   breakpoint prefixes (`sm:`, `md:`, `lg:`, `xl:`).

5. **Test at every breakpoint.** Do not trust that a component will work at
   intermediate sizes. 720px can expose layout bugs that 640px and 768px
   hide.

### Phase 5: Accessibility-First Implementation

**Minimum standard: WCAG 2.1 Level AA.** If the user's project requires AAA,
escalate accordingly.

#### 5.1 Semantic HTML

Use the correct HTML element for every piece of content. This is the
single highest-impact accessibility decision.

| Content | Correct Element | Avoid |
|---------|----------------|-------|
| Page header | `<header>` | `<div class="header">` |
| Primary navigation | `<nav aria-label="Main">` | `<div class="nav">` |
| Main content | `<main>` | `<div class="content">` |
| Standalone sections | `<section>` (with heading) | `<div>` |
| Articles / blog posts | `<article>` | `<div>` |
| Sidebar / complementary | `<aside>` | `<div>` |
| Page footer | `<footer>` | `<div class="footer">` |
| Data tables | `<table>`, `<thead>`, `<tbody>`, `<th scope="">` | `<div>` grid |
| Lists of items | `<ul>`, `<ol>`, `<li>` | `<div>` repeated |
| Buttons that perform actions | `<button>` | `<div onclick="">` |
| Links that navigate | `<a href="">` | `<button onclick="navigate()">` |
| Images with meaning | `<img alt="description">` | `<img>` (missing alt) |
| Decorative images | `<img alt="">` | `<img alt="icon">` |
| Form inputs | `<label>` + `<input>` paired with `for`/`id` | Placeholder-only inputs |
| Headings | `<h1>`–`<h6>` in logical order (no skips) | `<div class="heading">` |
| Figures with captions | `<figure>` + `<figcaption>` | `<div>` + `<p>` |

#### 5.2 ARIA — Use Only When HTML Isn't Enough

**First rule of ARIA: don't use ARIA if native HTML can do it.** ARIA adds
complexity and is easy to get wrong.

When ARIA is necessary:

| Pattern | ARIA Usage |
|---------|-----------|
| Tabs | `role="tablist"`, `role="tab"`, `role="tabpanel"`, `aria-selected`, `aria-controls` |
| Modal dialogs | `role="dialog"`, `aria-modal="true"`, `aria-labelledby`, focus trap |
| Accordions | `aria-expanded` on trigger, `aria-controls` linking to panel |
| Live regions | `aria-live="polite"` for dynamic content updates |
| Custom dropdowns | `role="listbox"`, `role="option"`, `aria-activedescendant` |
| Alerts/toasts | `role="alert"` or `aria-live="assertive"` |
| Progress bars | `role="progressbar"`, `aria-valuenow`, `aria-valuemin`, `aria-valuemax` |
| Disclosure widgets | `aria-expanded`, `aria-controls` |

#### 5.3 Color and Contrast

- **Text contrast ratio**: 4.5:1 minimum for normal text, 3:1 for large text
  (18px+ bold or 24px+ regular). WCAG AA requirement.
- **Non-text contrast**: 3:1 minimum for UI components and graphical objects
  (button borders, input borders, icons).
- **Never use color alone** to convey information. Error states need both
  red color AND an icon/text indicator. Links need underlines (not just
  color change).
- **Focus indicators**: Every interactive element must have a visible focus
  style. Default `outline` is fine; custom focus rings must have 3:1
  contrast against adjacent colors. `:focus-visible` is preferred over
  `:focus` for mouse users.

```css
/* Good focus indicator */
:focus-visible {
  outline: 3px solid var(--color-primary-500);
  outline-offset: 2px;
}

/* Avoid — removes focus entirely */
*:focus { outline: none; }
```

#### 5.4 Keyboard Navigation

- **Tab order** must follow visual order. Avoid positive `tabindex` values;
  use `tabindex="0"` to add to the natural order or `tabindex="-1"` for
  programmatic focus only.
- **Interactive elements** must be reachable and operable via keyboard:
  buttons, links, form controls, custom widgets.
- **Skip links**: Provide a "Skip to main content" link as the first
  focusable element.
- **Modals**: Trap focus inside the modal while open. Restore focus to the
  trigger element on close.
- **Dropdown/Menus**: Arrow keys navigate items. Escape closes. Enter/Space
  selects.

#### 5.5 Screen Reader Considerations

- **Descriptive link text**: "Learn more about pricing" not "Click here".
- **Image alt text**: Describe what the image communicates, not what it is.
  "Golden retriever fetching a ball in a park" not "Photo of dog".
- **Form labels**: Every input must have an associated `<label>`. Use
  `aria-label` or `aria-labelledby` only when a visible label is not
  possible.
- **Dynamic content**: Use `aria-live` regions for content that updates
  without page reload (search results, chat messages, notifications).
- **Heading hierarchy**: One `<h1>` per page. Headings should form a logical
  outline without skipping levels (no `<h1>` to `<h3>` without `<h2>`).

#### 5.6 Accessibility Audit Checklist

Before shipping, verify:
- [ ] Page has a unique, descriptive `<title>`
- [ ] `<html>` has a `lang` attribute
- [ ] All images have appropriate `alt` text
- [ ] Color contrast meets WCAG AA minimums (use a checker tool)
- [ ] Focus order is logical and visible
- [ ] Skip link is present and functional
- [ ] Forms have associated labels and error messages
- [ ] Page is navigable by keyboard alone (try tabbing through)
- [ ] ARIA roles, states, and properties are valid (use axe DevTools or
  Lighthouse)
- [ ] Dynamic content updates are announced to screen readers

### Phase 6: Framework-Agnostic Implementation Patterns

Produce code appropriate to the project's framework. This skill does not
favor one framework — adapt to what the project uses.

#### 6.1 React (with TypeScript)

```tsx
// Button component — React + CSS Modules
import styles from './Button.module.css';
import { type ComponentPropsWithoutRef, forwardRef } from 'react';

type ButtonVariant = 'primary' | 'secondary' | 'ghost';
type ButtonSize = 'sm' | 'md' | 'lg';

interface ButtonProps extends ComponentPropsWithoutRef<'button'> {
  variant?: ButtonVariant;
  size?: ButtonSize;
  isLoading?: boolean;
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ variant = 'primary', size = 'md', isLoading, children, disabled, className, ...props }, ref) => {
    const classes = [
      styles.button,
      styles[variant],
      styles[size],
      isLoading && styles.loading,
      className,
    ].filter(Boolean).join(' ');

    return (
      <button
        ref={ref}
        className={classes}
        disabled={disabled || isLoading}
        aria-busy={isLoading}
        {...props}
      >
        {isLoading ? <Spinner size={size} /> : children}
      </button>
    );
  }
);

Button.displayName = 'Button';
```

#### 6.2 Vue 3 (Composition API)

```vue
<script setup lang="ts">
import { computed } from 'vue';

type ButtonVariant = 'primary' | 'secondary' | 'ghost';
type ButtonSize = 'sm' | 'md' | 'lg';

const props = withDefaults(defineProps<{
  variant?: ButtonVariant;
  size?: ButtonSize;
  loading?: boolean;
  disabled?: boolean;
}>(), {
  variant: 'primary',
  size: 'md',
  loading: false,
  disabled: false,
});

const classes = computed(() => [
  `btn btn--${props.variant}`,
  `btn--${props.size}`,
  { 'btn--loading': props.loading },
]);
</script>

<template>
  <button
    :class="classes"
    :disabled="disabled || loading"
    :aria-busy="loading"
  >
    <Spinner v-if="loading" :size="size" />
    <slot v-else />
  </button>
</template>
```

#### 6.3 Svelte

```svelte
<script lang="ts">
  export let variant: 'primary' | 'secondary' | 'ghost' = 'primary';
  export let size: 'sm' | 'md' | 'lg' = 'md';
  export let loading = false;
  export let disabled = false;
</script>

<button
  class="btn btn--{variant} btn--{size}"
  class:btn--loading={loading}
  {disabled}
  aria-busy={loading}
  on:click
  {...$$restProps}
>
  {#if loading}
    <Spinner {size} />
  {:else}
    <slot />
  {/if}
</button>
```

#### 6.4 Plain HTML/CSS (Web Components)

```html
<!-- Usage -->
<ds-button variant="primary" size="md">Click me</ds-button>

<script>
class DsButton extends HTMLElement {
  static observedAttributes = ['variant', 'size', 'loading', 'disabled'];

  connectedCallback() {
    this.render();
  }

  attributeChangedCallback() {
    this.render();
  }

  render() {
    const variant = this.getAttribute('variant') || 'primary';
    const size = this.getAttribute('size') || 'md';
    const loading = this.hasAttribute('loading');
    const disabled = this.hasAttribute('disabled');

    this.setAttribute('role', 'button');
    this.setAttribute('tabindex', disabled ? '-1' : '0');
    this.setAttribute('aria-busy', String(loading));
    this.className = `ds-button ds-button--${variant} ds-button--${size} ${loading ? 'ds-button--loading' : ''}`;

    if (loading) {
      const spinner = document.createElement('ds-spinner');
      spinner.setAttribute('size', size);
      this.replaceChildren(spinner);
    } else {
      this.replaceChildren(document.createElement('slot'));
    }
  }
}

customElements.define('ds-button', DsButton);
</script>
```

### Phase 7: CSS Architecture Selection

Choose and apply the appropriate CSS strategy based on the project context.

| Approach | Best For | Trade-offs |
|----------|----------|------------|
| **CSS Modules** | Component-heavy apps with scoping needs. Pairs well with React, Vue, Svelte. | No global utilities. Need separate global stylesheet for resets/base. |
| **Tailwind CSS** | Rapid prototyping, utility-first teams, consistent design tokens. | HTML verbosity. Learning curve. Heavier HTML markup. |
| **styled-components** | CSS-in-JS with dynamic theming. React-centric. | Runtime overhead. Bundle size. Harder to extract critical CSS. |
| **Vanilla CSS Custom Properties** | Framework-agnostic, design systems, web components. | No scoping built-in. Requires naming conventions (BEM). |
| **Sass/SCSS** | Teams with SCSS legacy, complex mixin/functions needs. | Compilation step. Can produce bloated output without discipline. |
| **CSS-in-JS (zero-runtime)** | Static extraction (Vanilla Extract, Panda CSS, Linaria). | Build-time dependency. Smaller ecosystem than runtime CSS-in-JS. |

**Decision matrix:**
1. **If the project already uses a CSS approach**, match it. Consistency > personal preference.
2. **If starting fresh and speed matters**, Tailwind CSS or plain CSS custom properties.
3. **If building a design system**, CSS custom properties + CSS Modules for components.
4. **If heavy runtime theming is needed**, styled-components or Theme UI.

### Phase 8: Visual Regression Testing Strategy

1. **Set up a visual testing tool** — Chromatic (Storybook), Percy, Playwright
   screenshot comparison, or BackstopJS.

2. **Define test scenarios:**
   - Every component in every meaningful state (default, hover, focus, etc.)
   - Every breakpoint
   - Every theme variant (light/dark)
   - Edge cases: very long text, missing images, empty states, error states

3. **Capture baselines** from the initial implementation and compare against
   design references (Figma exports, design screenshots).

4. **Establish a regression workflow:**
   ```
   Implement → Capture baseline → Compare to design → Fix diffs → Re-capture
   ```

5. **Example Playwright visual test:**
   ```typescript
   import { test, expect } from '@playwright/test';

   test('Button component matches design', async ({ page }) => {
     await page.goto('/components/button');
     await expect(page.locator('[data-testid="button-primary"]')).toHaveScreenshot(
       'button-primary.png',
       { maxDiffPixelRatio: 0.01 }
     );
   });
   ```

6. **Acceptable diff thresholds:**
   - **Pixel-perfect**: 0% diff (brand pages, landing pages, core UI)
   - **Near-perfect**: <0.5% diff (internal tools, dashboards)
   - **Tolerance**: <2% diff (rapid prototyping, early-stage products)

### Phase 9: Design System Integration

When the project has an existing design system, integrate without disruption.

1. **Audit the existing system** — what tokens, components, and patterns
   already exist?

2. **Map new design elements to existing tokens:**
   - If the design uses a color that matches `--color-primary-500`, use it.
   - If the design introduces a new color not in the system, flag it:
     "This design specifies `#7C3AED` which is not in our design system.
     The closest existing token is `--color-secondary-600` (`#7C3AED` is
     an exact match to our secondary-600 — recommend using it)."

3. **Extend components rather than creating duplicates.** If a `Card`
   component exists but the design needs a slightly different variant,
   add a prop rather than creating `SpecialCard`.

4. **If the design contradicts the design system**, flag the discrepancy
   and ask whether the design should change or the design system should
   be updated.

5. **Token synchronization** — If the project has a token pipeline (e.g.,
   Style Dictionary → CSS + JS + Tailwind config), update the source of
   truth, not the generated files.

---

## Safety Rules

**ABSOLUTE RULES — never violate these:**

1. **Respect intellectual property.** Never reproduce copyrighted designs,
   illustrations, logos, or brand assets without explicit permission or
   license. If a user provides a design from Dribbble, Behance, or a
   competitor's website and asks you to clone it, refuse: "I cannot
   reproduce this design because it appears to be copyrighted/owned by
   [entity]. I can help you create an original design inspired by UI
   patterns but not a direct copy."

2. **Never ship hardcoded secrets.** If a design includes API keys,
   tokens, or credentials in code examples, flag them and strip them.
   Use environment variables.

3. **Always use HTTPS** for external assets (fonts, images, CDN resources).
   Mixed content is a security risk.

4. **Respect user privacy.** Don't add third-party trackers, analytics,
   or telemetry to generated code without the user's explicit request.
   Screen readers and accessibility tools must not be blocked.

5. **Be honest about fidelity.** When working from a screenshot (not a
   design file), preface output with: "I'm working from a screenshot,
   so colors and exact measurements are approximate. Please verify
   the following values against your design spec."

6. **Don't silently replace the design intent.** If the design has a
   complex interaction that would be expensive to implement, don't
   simplify it without asking. Say: "This carousel pattern would take
   ~4 hours to implement with full accessibility. A simpler tabbed
   layout would take ~1 hour. Which do you prefer?"

7. **Accessibility is non-negotiable.** Every implementation must meet
   WCAG 2.1 AA at minimum. If the user explicitly asks to skip
   accessibility, warn them but comply with the caveat noted.

8. **Don't generate inaccessibly.** Never produce code with `outline: none`
   without a replacement focus indicator. Never use `tabindex` values
   greater than 0. Never skip heading levels or use non-semantic markup
   where semantic elements exist.

---

## Platform Compatibility Notes

This skill is designed to work across AI coding platforms with minor
adaptations:

| Platform | Notes |
|----------|-------|
| **Claude Code** | Figma API integration works well. Can parse design JSON. Good for token extraction pipelines. |
| **Codex (OpenAI)** | Strong at component generation. Paste design specs or describe the design verbally. Screenshot analysis works well. |
| **Cursor** | Can read existing codebase for design system context. File system access helps with token integration. |
| **Gemini CLI** | Large context window useful for ingesting full design specs. Use `web_fetch` for Figma API. |
| **OpenClaw** | Exec for Figma CLI/API calls. GitHub skill for PR-based design review. Image analysis for screenshots. |
| **GitHub Copilot** | Works within IDE context. Best for incremental component implementation with existing design system access. |
| **Windsurf** | Can access workspace files and design assets. Execute design-to-code in context of existing project. |
| **OpenCode** | Terminal-based. Best with explicit design specs pasted or described textually. Can run token extraction scripts. |

### Platform-Specific Adjustments

- **If Figma API token is unavailable**: ask the user to export the design as
  SVG/PNG or paste a design spec document. Screenshot analysis is the fallback.
- **If image/vision analysis is not available**: ask the user to describe the
  design in text (layout, colors, typography, spacing). Work from description.
- **If a specific framework is not specified**: default to the framework the
  project already uses. If no project exists, ask the user.
- **For Discord/Slack delivery**: use bullet lists, not markdown tables. Split
  large code blocks across multiple messages. Wrap links in `<>`.
- **For platforms without file system access**: inline tokens and styles
  directly in generated output rather than referencing external files.

---

## References

- `references/design-tokens-guide.md` — W3C Design Tokens Community Group
  specification and implementation guide
- [WCAG 2.1 Quick Reference](https://www.w3.org/WAI/WCAG21/quickref/) —
  Official WCAG 2.1 guidelines
- [WAI-ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/patterns/) —
  ARIA design patterns and widget examples
- [Figma API Documentation](https://www.figma.com/developers/api) —
  Figma REST API reference
- [Style Dictionary](https://amzn.github.io/style-dictionary/) —
  Design token transformation tool
- [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/) —
  Color contrast verification
- [axe DevTools](https://www.deque.com/axe/) — Automated accessibility testing
- [Chromatic](https://www.chromatic.com/) — Visual regression testing for
  Storybook
