/** * CHORUS Services Design Token System * * Comprehensive design tokens implementing the brand system updates * based on the design director's strategy and UX architect's guidelines. * * This system provides: * - Core brand colors (Carbon Black, Walnut Brown, Brushed Aluminum, Natural Paper) * - System colors (Orchestration Blue, Harmony Green, Resonance Amber, Alert Coral) * - Typography scale with proper font families and responsive sizing * - Semantic tokens for consistent component usage * - Accessibility-compliant color combinations */ // ============================================================================= // CORE BRAND COLORS // ============================================================================= export const brandColors = { // Primary brand identity colors carbon: { black: '#000000', dark: '#0f0f0f', medium: '#1a1a1a', light: '#2a2a2a', }, walnut: { deep: '#8B4513', // Primary Walnut Brown medium: '#A0522D', // Secondary Walnut warm: '#D2691E', // Light Walnut light: '#DEB887', // Subtle Walnut accent }, aluminum: { metallic: '#C0C0C0', // Primary Brushed Aluminum slate: '#708090', // Dark Aluminum light: '#E5E5E5', // Light Silver subtle: '#F8F9FA', // Subtle aluminum tint }, paper: { natural: '#F5F5DC', // Primary Natural Paper pure: '#FFFEF7', // Off-White aged: '#F0E68C', // Light Parchment cream: '#FDF6E3', // Subtle cream variation }, } as const; // ============================================================================= // SYSTEM COLORS // ============================================================================= export const systemColors = { // Primary interaction and system feedback colors orchestration: { blue: '#007AFF', // Primary system color deep: '#0051D5', // Hover/pressed states light: '#4A90E2', // Secondary actions pale: '#E3F2FD', // Light backgrounds }, harmony: { green: '#30D158', // Success states forest: '#228B22', // Secondary success sage: '#9CAF88', // Subtle positive indicators mint: '#F0FFF4', // Light success backgrounds }, resonance: { amber: '#FF9F0A', // Warning/attention states golden: '#FFD700', // Premium highlights copper: '#B87333', // Secondary attention cream: '#FFFAF0', // Light warning backgrounds }, alert: { coral: '#FF453A', // Error/critical states warm: '#FF6B6B', // Secondary errors rose: '#E55B5B', // Soft error states blush: '#FFF5F5', // Light error backgrounds }, } as const; // ============================================================================= // SEMANTIC COLOR TOKENS // ============================================================================= export const semanticColors = { // Primary theme colors primary: systemColors.orchestration.blue, secondary: brandColors.aluminum.slate, // Feedback colors success: systemColors.harmony.green, warning: systemColors.resonance.amber, error: systemColors.alert.coral, info: systemColors.orchestration.light, // Background hierarchy (dark mode default) background: { primary: brandColors.carbon.black, // Main app background secondary: brandColors.carbon.medium, // Card/elevated surfaces tertiary: brandColors.carbon.light, // Input fields, secondary surfaces elevated: brandColors.carbon.dark, // Headers, footers }, // Text hierarchy (dark mode default) text: { primary: '#F2F2F7', // Primary content (19.96:1 contrast) secondary: '#A1A1A6', // Secondary content (6.64:1 contrast) tertiary: '#6D6D73', // Captions, metadata (4.51:1 contrast) disabled: '#48484A', // Disabled text inverse: brandColors.carbon.black, // Text on light backgrounds }, // Interactive elements interactive: { primary: systemColors.orchestration.blue, primaryHover: systemColors.orchestration.deep, secondary: brandColors.aluminum.metallic, secondaryHover: brandColors.aluminum.slate, }, // Borders and dividers border: { primary: '#48484A', // Main borders secondary: '#2a2a2a', // Subtle dividers accent: systemColors.orchestration.blue, // Focus states }, } as const; // ============================================================================= // TYPOGRAPHY TOKENS // ============================================================================= export const typography = { // Font family stacks fontFamily: { display: ['Exo', '-apple-system', 'BlinkMacSystemFont', 'SF Pro Display', 'Inter', 'sans-serif'], interface: ['-apple-system', 'BlinkMacSystemFont', 'SF Pro Text', 'Inter', 'Segoe UI', 'Roboto', 'sans-serif'], body: ['Roboto', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'sans-serif'], mono: ['SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', 'monospace'], }, // Font weights fontWeight: { thin: 100, // Exo Thin for hero displays extraLight: 200, // Exo ExtraLight for section displays light: 300, regular: 400, // Body text default medium: 500, // Interface elements semiBold: 600, // Emphasis, buttons bold: 700, extraBold: 800, black: 900, }, // Responsive font sizes using clamp() fontSize: { // Display sizes (large headlines) hero: 'clamp(48px, 8vw, 84px)', // Hero sections display1: 'clamp(32px, 5vw, 48px)', // Section headers display2: 'clamp(24px, 4vw, 36px)', // Subsection headers // Body sizes bodyLarge: '18px', // Important descriptions body: '16px', // Standard body copy bodySmall: '14px', // Captions, metadata // Interface sizes interface: '16px', // UI elements interfaceSmall: '14px', // Small UI elements // Code sizes code: '14px', // Code blocks codeInline: '0.9em', // Inline code (relative to parent) }, // Line heights lineHeight: { tight: 1.0, // Large displays, buttons snug: 1.1, // Section headers normal: 1.2, // UI elements relaxed: 1.4, // Small text, code loose: 1.5, // Body text reading: 1.6, // Long-form content }, // Letter spacing letterSpacing: { tight: '-0.02em', // Large text optical correction snug: '-0.015em', // Section headers normal: '0', // Default wide: '0.005em', // Small text readability wider: '0.01em', // Button text, labels }, } as const; // ============================================================================= // SPACING TOKENS // ============================================================================= export const spacing = { // Base spacing scale (4px grid) xs: '4px', sm: '8px', md: '12px', lg: '16px', xl: '24px', '2xl': '32px', '3xl': '48px', '4xl': '64px', '5xl': '96px', '6xl': '128px', // Component-specific spacing component: { buttonPadding: '12px 24px', inputPadding: '12px 16px', cardPadding: '24px', sectionPadding: '64px 0', containerPadding: '0 16px', }, } as const; // ============================================================================= // BORDER RADIUS TOKENS // ============================================================================= export const borderRadius = { none: '0', sm: '4px', md: '8px', lg: '12px', xl: '16px', '2xl': '24px', full: '9999px', // Component-specific radii button: '8px', card: '12px', input: '8px', modal: '16px', } as const; // ============================================================================= // SHADOW TOKENS // ============================================================================= export const shadows = { none: 'none', sm: '0 1px 2px rgba(0, 0, 0, 0.05)', md: '0 4px 6px rgba(0, 0, 0, 0.1)', lg: '0 10px 15px rgba(0, 0, 0, 0.15)', xl: '0 20px 25px rgba(0, 0, 0, 0.25)', '2xl': '0 25px 50px rgba(0, 0, 0, 0.35)', // Interactive shadows button: '0 2px 8px rgba(0, 122, 255, 0.2)', buttonHover: '0 4px 12px rgba(0, 122, 255, 0.3)', card: '0 4px 20px rgba(0, 0, 0, 0.25)', cardHover: '0 8px 30px rgba(0, 0, 0, 0.35)', // Focus shadows focus: '0 0 0 3px rgba(0, 122, 255, 0.2)', } as const; // ============================================================================= // MOTION TOKENS // ============================================================================= export const motion = { // Duration duration: { fast: '150ms', normal: '250ms', slow: '350ms', slower: '500ms', }, // Timing functions easing: { linear: 'linear', ease: 'ease', easeIn: 'cubic-bezier(0.4, 0, 1, 1)', easeOut: 'cubic-bezier(0, 0, 0.2, 1)', easeInOut: 'cubic-bezier(0.4, 0, 0.2, 1)', spring: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', }, } as const; // ============================================================================= // BREAKPOINTS // ============================================================================= export const breakpoints = { sm: '640px', md: '768px', lg: '1024px', xl: '1280px', '2xl': '1536px', } as const; // ============================================================================= // DESIGN TOKEN EXPORT // ============================================================================= export const designTokens = { brand: brandColors, system: systemColors, semantic: semanticColors, typography, spacing, borderRadius, shadows, motion, breakpoints, } as const; // ============================================================================= // TYPE DEFINITIONS // ============================================================================= export type BrandColors = typeof brandColors; export type SystemColors = typeof systemColors; export type SemanticColors = typeof semanticColors; export type Typography = typeof typography; export type Spacing = typeof spacing; export type BorderRadius = typeof borderRadius; export type Shadows = typeof shadows; export type Motion = typeof motion; export type Breakpoints = typeof breakpoints; export type DesignTokens = typeof designTokens; // ============================================================================= // UTILITY FUNCTIONS // ============================================================================= /** * Get a color token with fallback */ export function getColor(path: string, fallback: string = '#000000'): string { try { const keys = path.split('.'); let current: any = designTokens; for (const key of keys) { current = current[key]; if (current === undefined) return fallback; } return current; } catch { return fallback; } } /** * Create CSS custom properties from design tokens */ export function createCSSVariables(tokens: Record, prefix = '--chorus'): Record { const variables: Record = {}; function flatten(obj: Record, currentPath = '') { for (const [key, value] of Object.entries(obj)) { const newPath = currentPath ? `${currentPath}-${key}` : key; if (typeof value === 'object' && value !== null && !Array.isArray(value)) { flatten(value, newPath); } else { variables[`${prefix}-${newPath}`] = String(value); } } } flatten(tokens); return variables; } /** * Accessibility helper: Check if color combination meets WCAG contrast requirements */ export function meetsContrastRequirement( foreground: string, background: string, level: 'AA' | 'AAA' = 'AA', size: 'normal' | 'large' = 'normal' ): boolean { // This is a simplified check - in production, use a proper contrast calculation library const requirements = { AA: { normal: 4.5, large: 3.0 }, AAA: { normal: 7.0, large: 4.5 }, }; // Placeholder - implement actual contrast calculation return true; // Replace with real calculation } export default designTokens;