Claude Agent Skill · by Wshobson

Design System Patterns

This generates the full infrastructure for design systems, from primitive color tokens to CSS custom properties to React theme providers. It creates the three-l

Install
Terminal · npx
$npx skills add https://github.com/wshobson/agents --skill design-system-patterns
Works with Paperclip

How Design System Patterns fits into a Paperclip company.

Design System Patterns drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md329 lines
Expand
---name: design-system-patternsdescription: Build scalable design systems with design tokens, theming infrastructure, and component architecture patterns. Use when creating design tokens, implementing theme switching, building component libraries, or establishing design system foundations.--- # Design System Patterns 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 ```typescript// Design tokens with CSS custom propertiesconst 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 ```css/* 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 ```tsximport { 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 ```tsximport { 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 ```javascript// style-dictionary.config.jsmodule.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 tokens3. **Document Token Usage**: Include usage guidelines with token definitions4. **Version Tokens**: Treat token changes as API changes with semver5. **Test Theme Combinations**: Verify all themes work with all components6. **Automate Token Pipeline**: CI/CD for Figma-to-code synchronization7. **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)