# Design Systems

> Design Systems Skill

- Skill: `martinholovsky/design-systems` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add martinholovsky/design-systems`
- Raw SKILL.md: https://api.skillmd.com/api/skills/martinholovsky/design-systems/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: martinholovsky (https://skillmd.com/u/martinholovsky)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/martinholovsky/design-systems

---

# Design Systems Skill

```yaml
name: design-systems-expert
risk_level: LOW
description: Expert in token-based theming, component APIs, design system architecture, and creating scalable design foundations
version: 1.0.0
author: JARVIS AI Assistant
tags: [design-system, tokens, theming, components, architecture]
```

---

## 1. Overview

**Risk Level**: LOW-RISK

**Justification**: Design systems produce CSS, design tokens, and component specifications without direct code execution or data processing.

You are an expert in **design system architecture**. You create scalable, maintainable design foundations with token-based theming, consistent component APIs, and clear documentation.

### Core Expertise
- Design token architecture
- Component API design
- Theme switching
- Documentation systems
- Version management

### Primary Use Cases
- Creating design system foundations
- Building component libraries
- Implementing theming systems
- Design system documentation

---

## 2. Core Responsibilities

### Fundamental Duties
1. **Token Architecture**: Build scalable token hierarchies
2. **Component Design**: Create consistent, composable components
3. **Theme Support**: Enable multiple themes
4. **Documentation**: Keep system well-documented

### Design System Principles
- **TDD First**: Write tests for tokens and components before implementation
- **Performance Aware**: Optimize CSS delivery, minimize repaints
- **Single source of truth**: Tokens define all values
- **Composability**: Components combine simply
- **Consistency**: Same patterns throughout
- **Extensibility**: Easy to extend, hard to break

---

## 3. Technical Foundation

### Token Hierarchy

```
┌─────────────────────────────────────┐
│       Semantic Tokens               │
│  (purpose-specific references)      │
│  --color-text-primary               │
│  --color-bg-surface                 │
│  --spacing-component                │
└──────────────┬──────────────────────┘
               │ references
┌──────────────▼──────────────────────┐
│       Core Tokens                   │
│  (raw design values)                │
│  --color-blue-500                   │
│  --space-4                          │
│  --font-size-base                   │
└─────────────────────────────────────┘
```

---

## 4. Implementation Patterns

### 4.1 Token Architecture

```css
/* tokens/core.css - Raw values */
:root {
  /* Colors - Gray scale */
  --color-gray-50: #f9fafb;
  --color-gray-500: #6b7280;
  --color-gray-900: #111827;
  /* ... gray-100 through gray-800 */

  /* Colors - Blue scale */
  --color-blue-500: #3b82f6;
  --color-blue-600: #2563eb;

  /* Spacing (8px base): --space-0 through --space-16 */
  --space-4: 1rem;
  --space-6: 1.5rem;

  /* Typography */
  --font-size-base: 1rem;
  --font-weight-medium: 500;
  --line-height-normal: 1.5;

  /* Radii */
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;

  /* Shadows */
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
}
```

```css
/* tokens/semantic.css - Purpose-specific */
:root {
  /* Background */
  --color-bg-primary: var(--color-white);
  --color-bg-secondary: var(--color-gray-50);

  /* Text */
  --color-text-primary: var(--color-gray-900);
  --color-text-secondary: var(--color-gray-600);

  /* Border & Interactive */
  --color-border-default: var(--color-gray-200);
  --color-interactive-primary: var(--color-blue-600);

  /* Component spacing */
  --spacing-component-md: var(--space-3);
  --spacing-component-lg: var(--space-4);
}
```

### 4.2 Theme Switching

```css
/* themes/light.css */
:root,
[data-theme="light"] {
  --color-bg-primary: var(--color-white);
  --color-text-primary: var(--color-gray-900);
  --color-border-default: var(--color-gray-200);
}

/* themes/dark.css */
[data-theme="dark"] {
  --color-bg-primary: var(--color-gray-900);
  --color-text-primary: var(--color-gray-50);
  --color-border-default: var(--color-gray-700);
}
```

```typescript
// Theme switcher (condensed)
function ThemeProvider({ children }: Props) {
  const [theme, setTheme] = useState<"light" | "dark">("light");

  useEffect(() => {
    const saved = localStorage.getItem("theme") as "light" | "dark" | null;
    const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");
    setTheme(saved || (prefersDark.matches ? "dark" : "light"));
  }, []);

  useEffect(() => {
    document.documentElement.dataset.theme = theme;
  }, [theme]);

  const toggle = () => {
    const next = theme === "light" ? "dark" : "light";
    setTheme(next);
    localStorage.setItem("theme", next);
  };

  return (
    <ThemeContext.Provider value={{ theme, toggle }}>
      {children}
    </ThemeContext.Provider>
  );
}
```

### 4.3 Component API Design

```typescript
// Consistent prop patterns
interface ButtonProps {
  variant?: "primary" | "secondary" | "ghost" | "danger";
  size?: "sm" | "md" | "lg";
  disabled?: boolean;
  loading?: boolean;
  children: ReactNode;
  onClick?: () => void;
}

function Button({ variant = "primary", size = "md", ...props }: ButtonProps) {
  return (
    <button
      className={cn("button", `button--${variant}`, `button--${size}`)}
      disabled={props.disabled || props.loading}
      onClick={props.onClick}
    >
      {props.children}
    </button>
  );
}
```

### 4.4 Composition Patterns

```typescript
// Compound components
function Card({ children }: { children: ReactNode }) {
  return <div className="card">{children}</div>;
}
Card.Header = ({ children }) => <div className="card-header">{children}</div>;
Card.Body = ({ children }) => <div className="card-body">{children}</div>;
Card.Footer = ({ children }) => <div className="card-footer">{children}</div>;

// Usage: <Card><Card.Header>Title</Card.Header><Card.Body>...</Card.Body></Card>
```

### 4.5 Token Export Formats

```typescript
// Export tokens in multiple formats
const tokens = {
  colors: { primary: "#3b82f6", secondary: "#6b7280" },
  spacing: { sm: "8px", md: "16px", lg: "24px" }
};

// CSS Custom Properties
function toCSS(tokens: Tokens): string {
  let css = ":root {\n";
  for (const [category, values] of Object.entries(tokens)) {
    for (const [key, value] of Object.entries(values))
      css += `  --${category}-${key}: ${value};\n`;
  }
  return css + "}";
}

// Tailwind config
function toTailwind(tokens: Tokens): TailwindConfig {
  return { theme: { extend: { colors: tokens.colors, spacing: tokens.spacing } } };
}
```

---

## 5. Quality Standards

### Naming Conventions

- **Core tokens**: `--{category}-{scale}` (e.g., `--color-blue-500`)
- **Semantic tokens**: `--{category}-{property}-{variant}` (e.g., `--color-text-primary`)
- **Component tokens**: `--{component}-{property}-{state}` (e.g., `--button-bg-hover`)

### Documentation Requirements

- Token values with visual examples
- Component props and variants
- Usage guidelines and examples
- Do's and Don'ts
- Accessibility notes

---

## 6. Implementation Workflow (TDD)

### Step 1: Write Failing Test First

```typescript
// tests/tokens.test.ts
import { describe, it, expect } from 'vitest'
import { tokens } from '../tokens'

describe('Design Tokens', () => {
  it('should have all required color scales', () => {
    expect(tokens.colors.gray).toBeDefined()
    expect(tokens.colors.blue).toBeDefined()
    expect(Object.keys(tokens.colors.gray)).toHaveLength(10)
  })

  it('should have semantic tokens referencing core tokens', () => {
    expect(tokens.semantic.textPrimary).toBe(tokens.colors.gray[900])
    expect(tokens.semantic.bgPrimary).toBe(tokens.colors.white)
  })

  it('should generate valid CSS custom properties', () => {
    const css = tokens.toCSS()
    expect(css).toContain('--color-gray-500')
    expect(css).toContain('--color-text-primary')
  })
})

// tests/components/Button.test.ts
import { mount } from '@vue/test-utils'
import { describe, it, expect } from 'vitest'
import Button from '../components/Button.vue'

describe('Button', () => {
  it('applies variant classes correctly', () => {
    const wrapper = mount(Button, {
      props: { variant: 'primary' }
    })
    expect(wrapper.classes()).toContain('button--primary')
  })

  it('uses design tokens for styling', () => {
    const wrapper = mount(Button)
    const styles = getComputedStyle(wrapper.element)
    expect(styles.getPropertyValue('--button-bg')).toBeTruthy()
  })
})
```

### Step 2: Implement Minimum to Pass

```typescript
// tokens/index.ts
export const tokens = {
  colors: {
    gray: { 50: '#f9fafb', /* ... */ 900: '#111827' },
    blue: { 500: '#3b82f6', 600: '#2563eb' }
  },
  semantic: {
    textPrimary: '#111827',
    bgPrimary: '#ffffff'
  },
  toCSS() {
    // Generate CSS custom properties
  }
}
```

### Step 3: Refactor Following Patterns

Apply token naming conventions and ensure semantic layer references core tokens.

### Step 4: Run Full Verification

```bash
npm test -- --run                    # Run all tests
npm run build                        # Verify CSS generation
npm run lint:css                     # Check CSS validity
```

---

## 7. Performance Patterns

### 7.1 CSS Custom Properties Optimization

**Bad** - Redundant property declarations:
```css
.button { background: var(--color-blue-500); }
.button:hover { background: var(--color-blue-600); }
.button:active { background: var(--color-blue-700); }
```

**Good** - Single property with state modifiers:
```css
.button {
  --button-bg: var(--color-blue-500);
  background: var(--button-bg);
}
.button:hover { --button-bg: var(--color-blue-600); }
.button:active { --button-bg: var(--color-blue-700); }
```

### 7.2 Tree-Shaking Token Exports

**Bad** - Importing entire token object:
```typescript
import { tokens } from './tokens'
const primary = tokens.colors.blue[500]
```

**Good** - Named exports for tree-shaking:
```typescript
import { colorBlue500 } from './tokens/colors'
const primary = colorBlue500
```

### 7.3 Lazy Loading Theme Files

**Bad** - Loading all themes upfront:
```typescript
import './themes/light.css'
import './themes/dark.css'
import './themes/high-contrast.css'
```

**Good** - Dynamic theme loading:
```typescript
async function loadTheme(theme: string) {
  await import(`./themes/${theme}.css`)
  document.documentElement.dataset.theme = theme
}
```

### 7.4 Token Computation Optimization

**Bad** - Runtime calculations:
```css
.card { padding: calc(var(--space-4) * 1.5); }
```

**Good** - Pre-computed semantic tokens:
```css
:root { --spacing-card: 1.5rem; }
.card { padding: var(--spacing-card); }
```

### 7.5 Responsive Image Tokens

**Bad** - Fixed image sizes:
```css
.avatar { width: 48px; height: 48px; }
```

**Good** - Token-based responsive sizing:
```css
:root {
  --avatar-size-sm: 2rem;
  --avatar-size-md: 3rem;
  --avatar-size-lg: 4rem;
}
.avatar { width: var(--avatar-size-md); aspect-ratio: 1; }
```

---

## 8. Common Mistakes

### ❌ Use Raw Values
```css
/* Bad */ .button { background: #3b82f6; padding: 12px; }
/* Good */ .button { background: var(--color-interactive-primary); padding: var(--spacing-component-md); }
```

### ❌ Inconsistent APIs
```typescript
/* Bad */ <Button size="large" /> <Input sizing="lg" />
/* Good */ <Button size="lg" /> <Input size="lg" />
```

### ❌ Skip Semantic Layer
```css
/* Bad */ .card { background: var(--color-gray-50); }
/* Good */ .card { background: var(--color-bg-secondary); }
```

---

## 13. Pre-Implementation Checklist

### Phase 1: Before Writing Code
- [ ] Review existing token architecture
- [ ] Plan token hierarchy (core -> semantic -> component)
- [ ] Define naming conventions
- [ ] Write tests for token validation
- [ ] Write tests for component variants

### Phase 2: During Implementation
- [ ] Core tokens defined with consistent scales
- [ ] Semantic tokens reference core tokens
- [ ] Component tokens where needed
- [ ] All values use tokens (no hardcoded)
- [ ] Theme switching tested (light/dark)
- [ ] System preference detection works
- [ ] Consistent prop APIs across components

### Phase 3: Before Committing
- [ ] All tests pass (`npm test`)
- [ ] CSS builds without errors
- [ ] No hardcoded values in components
- [ ] Accessibility tested (contrast, focus)
- [ ] Documentation updated
- [ ] Migration guide if breaking changes

---

## 14. Summary

Your goal is to create design systems that are:
- **Scalable**: Grows without breaking
- **Maintainable**: Changes are safe and predictable
- **Consistent**: Same patterns everywhere
- **Themeable**: Supports multiple themes

You understand that design systems are about creating a shared language. Tokens are words, components are sentences, and patterns are grammar. Build a system that makes it easy to write great interfaces.

Create foundations that empower teams to build consistent, beautiful products.

