--- name: ux-design-systems description: Build consistent design systems with tokens, components, and theming. Use when creating component libraries, implementing design tokens, building theme systems, or ensuring design consistency. Triggers on design system, design tokens, component library, theming, dark mode. --- # UX Design Systems Build consistent, maintainable design systems with tokens, components, and theming. ## Design Tokens ### CSS Variables ```css :root { /* Colors */ --color-primary-50: #eff6ff; --color-primary-500: #3b82f6; --color-primary-900: #1e3a8a; /* Typography */ --font-sans: 'Inter', system-ui, sans-serif; --font-size-sm: 0.875rem; --font-size-base: 1rem; --font-size-lg: 1.125rem; /* Spacing */ --space-1: 0.25rem; --space-2: 0.5rem; --space-4: 1rem; --space-8: 2rem; /* Border Radius */ --radius-sm: 0.25rem; --radius-md: 0.375rem; --radius-lg: 0.5rem; --radius-full: 9999px; /* 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); } ``` ### TypeScript Token System ```typescript export const tokens = { colors: { primary: { 50: '#eff6ff', 500: '#3b82f6', 900: '#1e3a8a', }, gray: { 50: '#f9fafb', 500: '#6b7280', 900: '#111827', }, }, spacing: { 1: '0.25rem', 2: '0.5rem', 4: '1rem', 8: '2rem', }, fontSize: { sm: '0.875rem', base: '1rem', lg: '1.125rem', xl: '1.25rem', }, } as const; type ColorToken = keyof typeof tokens.colors; type SpaceToken = keyof typeof tokens.spacing; ``` ## Component Patterns ### Button Component ```tsx import { cva, type VariantProps } from 'class-variance-authority'; const buttonVariants = cva( '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: { primary: 'bg-primary-500 text-white hover:bg-primary-600', secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200', outline: 'border border-gray-300 bg-transparent hover:bg-gray-50', ghost: 'hover:bg-gray-100', destructive: 'bg-red-500 text-white hover:bg-red-600', }, size: { sm: 'h-8 px-3 text-sm', md: 'h-10 px-4 text-base', lg: 'h-12 px-6 text-lg', }, }, defaultVariants: { variant: 'primary', size: 'md', }, } ); interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { isLoading?: boolean; } export function Button({ className, variant, size, isLoading, children, ...props }: ButtonProps) { return ( ); } ``` ## Dark Mode ### CSS-Based Theme Switching ```css :root { --bg-primary: #ffffff; --text-primary: #111827; --border-color: #e5e7eb; } [data-theme='dark'] { --bg-primary: #111827; --text-primary: #f9fafb; --border-color: #374151; } ``` ### React Theme Provider ```tsx import { createContext, useContext, useEffect, useState } from 'react'; type Theme = 'light' | 'dark' | 'system'; const ThemeContext = createContext<{ theme: Theme; setTheme: (theme: Theme) => void; }>({ theme: 'system', setTheme: () => {} }); export function ThemeProvider({ children }: { children: React.ReactNode }) { const [theme, setTheme] = useState('system'); useEffect(() => { const root = document.documentElement; if (theme === 'system') { const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; root.setAttribute('data-theme', systemTheme); } else { root.setAttribute('data-theme', theme); } }, [theme]); return ( {children} ); } export const useTheme = () => useContext(ThemeContext); ``` ## Resources - **Tailwind CSS**: https://tailwindcss.com - **CVA (Class Variance Authority)**: https://cva.style