design-system-patterns
Install this skill
npx skills add wshobson/agentsWorks across Claude Code, Cursor, Codex, Copilot & Antigravity
The design-system-patterns skill provides a structured framework for managing UI consistency across complex codebases. It focuses on the architectural decoupling of style values through a tiered token methodology, allowing developers to manage primitives, semantic aliases, and component-specific variables independently. This skill covers the implementation of multi-platform token pipelines, automated synchronization between design software like Figma and project code, and the logic for state-based theming. By adopting these patterns, teams minimize hard-coded style values, simplify dark mode integration, and ensure that visual changes cascade predictably throughout an application. The skill emphasizes standardized naming conventions and programmatic style injection, moving beyond simple CSS variables toward a scalable infrastructure that bridges the gap between design intent and frontend execution.
When to Use This Skill
- •Transitioning a monolithic CSS codebase to a tokenized system
- •Building a multi-brand application requiring dynamic theme injection
- •Integrating Figma design tokens into a React component library
- •Implementing dark mode support with persistent user preferences
How to Invoke This Skill
Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:
- “how do I organize my CSS custom properties into tokens
- “create a token hierarchy for my component library
- “implement theme switching with semantic variables in react
- “set up a design token pipeline from figma to code
- “refactor my app for better theme management and scalability
Pro Tips
- 💡Prioritize a clear token naming convention (e.g., `color-surface-primary`, `font-size-body-md`) to ensure maintainability and discoverability across large teams.
- 💡When building theming, always consider accessibility from the outset, including high-contrast modes and reduced motion preferences, rather than as an afterthought.
- 💡Integrate automation for token generation and component documentation. Tools like Style Dictionary or Storybook can drastically improve consistency and developer experience.
What this skill does
- •Implementation of a three-tier token hierarchy (primitive, semantic, component)
- •Automation of cross-platform token distribution via Style Dictionary
- •Dynamic theme management and system-level color mode detection
- •Creation of composable component architectures using headless patterns
- •Standardized naming conventions for CSS custom properties
When not to use it
- ✕Small prototypes or one-off landing pages where overhead outweighs maintenance benefits
- ✕Projects with strictly fixed branding that will never undergo design updates or theming
Example workflow
- Define raw color and spacing values as primitive JSON tokens
- Create semantic mappings that reference primitives for specific UI contexts
- Generate CSS custom properties using a transformation tool like Style Dictionary
- Build a ThemeProvider context to toggle between semantic theme objects
- Update component styles to consume the relevant semantic tokens
Prerequisites
- –Basic proficiency in CSS Custom Properties
- –Working knowledge of React state management or equivalent
- –Experience with CI/CD build scripts
Pitfalls & limitations
- !Creating excessive nesting in tokens that makes debugging difficult
- !Over-engineering the token pipeline for projects that do not require multi-brand capabilities
- !Inconsistent naming conventions across team members
FAQ
How it compares
Unlike manual CSS variable management, this skill forces a strict hierarchical structure that separates design intent from implementation, ensuring changes propagate systematically rather than through risky global find-and-replace actions.
📄 Full skill instructions — original source: wshobson/agents
Master design system architecture to create consistent, maintainable, and scalable UI foundations across web and mobile applications.
## When to Use This Skill
- Creating design tokens for colors, typography, spacing, and shadows
- Implementing light/dark theme switching with CSS custom properties
- Building multi-brand theming systems
- Architecting component libraries with consistent APIs
- Establishing design-to-code workflows with Figma tokens
- Creating semantic token hierarchies (primitive, semantic, component)
- Setting up design system documentation and guidelines
## Core Capabilities
### 1. Design Tokens
- Primitive tokens (raw values: colors, sizes, fonts)
- Semantic tokens (contextual meaning: text-primary, surface-elevated)
- Component tokens (specific usage: button-bg, card-border)
- Token naming conventions and organization
- Multi-platform token generation (CSS, iOS, Android)
### 2. Theming Infrastructure
- CSS custom properties architecture
- Theme context providers in React
- Dynamic theme switching
- System preference detection (prefers-color-scheme)
- Persistent theme storage
- Reduced motion and high contrast modes
### 3. Component Architecture
- Compound component patterns
- Polymorphic components (as prop)
- Variant and size systems
- Slot-based composition
- Headless UI patterns
- Style props and responsive variants
### 4. Token Pipeline
- Figma to code synchronization
- Style Dictionary configuration
- Token transformation and formatting
- CI/CD integration for token updates
## Quick Start
// Design tokens with CSS custom properties
const tokens = {
colors: {
// Primitive tokens
gray: {
50: "#fafafa",
100: "#f5f5f5",
900: "#171717",
},
blue: {
500: "#3b82f6",
600: "#2563eb",
},
},
// Semantic tokens (reference primitives)
semantic: {
light: {
"text-primary": "var(--color-gray-900)",
"text-secondary": "var(--color-gray-600)",
"surface-default": "var(--color-white)",
"surface-elevated": "var(--color-gray-50)",
"border-default": "var(--color-gray-200)",
"interactive-primary": "var(--color-blue-500)",
},
dark: {
"text-primary": "var(--color-gray-50)",
"text-secondary": "var(--color-gray-400)",
"surface-default": "var(--color-gray-900)",
"surface-elevated": "var(--color-gray-800)",
"border-default": "var(--color-gray-700)",
"interactive-primary": "var(--color-blue-400)",
},
},
};## Key Patterns
### Pattern 1: Token Hierarchy
/* Layer 1: Primitive tokens (raw values) */
:root {
--color-blue-500: #3b82f6;
--color-blue-600: #2563eb;
--color-gray-50: #fafafa;
--color-gray-900: #171717;
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-4: 1rem;
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--radius-sm: 0.25rem;
--radius-md: 0.5rem;
--radius-lg: 1rem;
}
/* Layer 2: Semantic tokens (meaning) */
:root {
--text-primary: var(--color-gray-900);
--text-secondary: var(--color-gray-600);
--surface-default: white;
--interactive-primary: var(--color-blue-500);
--interactive-primary-hover: var(--color-blue-600);
}
/* Layer 3: Component tokens (specific usage) */
:root {
--button-bg: var(--interactive-primary);
--button-bg-hover: var(--interactive-primary-hover);
--button-text: white;
--button-radius: var(--radius-md);
--button-padding-x: var(--space-4);
--button-padding-y: var(--space-2);
}### Pattern 2: Theme Switching with React
import { createContext, useContext, useEffect, useState } from "react";
type Theme = "light" | "dark" | "system";
interface ThemeContextValue {
theme: Theme;
resolvedTheme: "light" | "dark";
setTheme: (theme: Theme) => void;
}
const ThemeContext = createContext<ThemeContextValue | null>(null);
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = useState<Theme>(() => {
if (typeof window !== "undefined") {
return (localStorage.getItem("theme") as Theme) || "system";
}
return "system";
});
const [resolvedTheme, setResolvedTheme] = useState<"light" | "dark">("light");
useEffect(() => {
const root = document.documentElement;
const applyTheme = (isDark: boolean) => {
root.classList.remove("light", "dark");
root.classList.add(isDark ? "dark" : "light");
setResolvedTheme(isDark ? "dark" : "light");
};
if (theme === "system") {
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
applyTheme(mediaQuery.matches);
const handler = (e: MediaQueryListEvent) => applyTheme(e.matches);
mediaQuery.addEventListener("change", handler);
return () => mediaQuery.removeEventListener("change", handler);
} else {
applyTheme(theme === "dark");
}
}, [theme]);
useEffect(() => {
localStorage.setItem("theme", theme);
}, [theme]);
return (
<ThemeContext.Provider value={{ theme, resolvedTheme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) throw new Error("useTheme must be used within ThemeProvider");
return context;
};### Pattern 3: Variant System with CVA
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
// Base styles
"inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
sm: "h-9 px-3 text-sm",
md: "h-10 px-4 text-sm",
lg: "h-11 px-8 text-base",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "md",
},
},
);
interface ButtonProps
extends
React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
export function Button({ className, variant, size, ...props }: ButtonProps) {
return (
<button
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
);
}### Pattern 4: Style Dictionary Configuration
// style-dictionary.config.js
module.exports = {
source: ["tokens/**/*.json"],
platforms: {
css: {
transformGroup: "css",
buildPath: "dist/css/",
files: [
{
destination: "variables.css",
format: "css/variables",
options: {
outputReferences: true, // Preserve token references
},
},
],
},
scss: {
transformGroup: "scss",
buildPath: "dist/scss/",
files: [
{
destination: "_variables.scss",
format: "scss/variables",
},
],
},
ios: {
transformGroup: "ios-swift",
buildPath: "dist/ios/",
files: [
{
destination: "DesignTokens.swift",
format: "ios-swift/class.swift",
className: "DesignTokens",
},
],
},
android: {
transformGroup: "android",
buildPath: "dist/android/",
files: [
{
destination: "colors.xml",
format: "android/colors",
filter: { attributes: { category: "color" } },
},
],
},
},
};## Best Practices
1. **Name Tokens by Purpose**: Use semantic names (text-primary) not visual descriptions (dark-gray)
2. **Maintain Token Hierarchy**: Primitives > Semantic > Component tokens
3. **Document Token Usage**: Include usage guidelines with token definitions
4. **Version Tokens**: Treat token changes as API changes with semver
5. **Test Theme Combinations**: Verify all themes work with all components
6. **Automate Token Pipeline**: CI/CD for Figma-to-code synchronization
7. **Provide Migration Paths**: Deprecate tokens gradually with clear alternatives
## Common Issues
- **Token Sprawl**: Too many tokens without clear hierarchy
- **Inconsistent Naming**: Mixed conventions (camelCase vs kebab-case)
- **Missing Dark Mode**: Tokens that don't adapt to theme changes
- **Hardcoded Values**: Using raw values instead of tokens
- **Circular References**: Tokens referencing each other in loops
- **Platform Gaps**: Tokens missing for some platforms (web but not mobile)
## Resources
- [Style Dictionary Documentation](https://amzn.github.io/style-dictionary/)
- [Tokens Studio for Figma](https://tokens.studio/)
- [Design Tokens W3C Spec](https://design-tokens.github.io/community-group/format/)
- [Radix UI Themes](https://www.radix-ui.com/themes)
- [shadcn/ui Theming](https://ui.shadcn.com/docs/theming)
How to Use This Skill Unit
Option A: Project-Specific (Recommended)
- Click "Download" above
- In your project, create the directory:
.agent/skills/design-system-patterns/ - Save the file as
SKILL.md - The agent will automatically discover the skill based on its description.
Option B: Global Installation (All Agents)
Save the file to these locations to make it available across all projects:
- Claude Code:
~/.claude/skills/wshobson/agents/design-system-patterns/SKILL.md - Cursor:
~/.cursor/skills/wshobson/agents/design-system-patterns/SKILL.md - Antigravity:
~/.gemini/antigravity/skills/wshobson/agents/design-system-patterns/SKILL.md
🚀 Install with CLI:npx skills add wshobson/agents