@thesage/ui 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/fontThemes-Bwf7_lFg.d.mts +842 -0
  2. package/dist/fontThemes-Bwf7_lFg.d.ts +842 -0
  3. package/dist/hooks-C8PrmIXy.d.mts +225 -0
  4. package/dist/hooks-Ct9RBhg-.d.ts +225 -0
  5. package/dist/hooks.d.mts +3 -0
  6. package/dist/hooks.d.ts +3 -0
  7. package/dist/hooks.js +1342 -0
  8. package/dist/hooks.js.map +1 -0
  9. package/dist/hooks.mjs +1314 -0
  10. package/dist/hooks.mjs.map +1 -0
  11. package/dist/index-CsnncHSm.d.mts +23 -0
  12. package/dist/index-CsnncHSm.d.ts +23 -0
  13. package/dist/index.d.mts +2830 -0
  14. package/dist/index.d.ts +2830 -0
  15. package/dist/index.js +12637 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/index.mjs +12319 -0
  18. package/dist/index.mjs.map +1 -0
  19. package/dist/providers-Dv3LFGtJ.d.mts +17 -0
  20. package/dist/providers-Dv3LFGtJ.d.ts +17 -0
  21. package/dist/providers.d.mts +2 -0
  22. package/dist/providers.d.ts +2 -0
  23. package/dist/providers.js +1944 -0
  24. package/dist/providers.js.map +1 -0
  25. package/dist/providers.mjs +1918 -0
  26. package/dist/providers.mjs.map +1 -0
  27. package/dist/tokens.d.mts +831 -0
  28. package/dist/tokens.d.ts +831 -0
  29. package/dist/tokens.js +2399 -0
  30. package/dist/tokens.js.map +1 -0
  31. package/dist/tokens.mjs +2319 -0
  32. package/dist/tokens.mjs.map +1 -0
  33. package/dist/utils-DlJKRVzQ.d.mts +986 -0
  34. package/dist/utils-xrpHqxXR.d.ts +986 -0
  35. package/dist/utils.d.mts +4 -0
  36. package/dist/utils.d.ts +4 -0
  37. package/dist/utils.js +873 -0
  38. package/dist/utils.js.map +1 -0
  39. package/dist/utils.mjs +805 -0
  40. package/dist/utils.mjs.map +1 -0
  41. package/dist/validation-Bj1ye-v_.d.mts +114 -0
  42. package/dist/validation-Bj1ye-v_.d.ts +114 -0
  43. package/package.json +117 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/store/theme.ts","../src/hooks/useTheme.ts","../src/hooks/useMotionPreference.ts","../src/lib/store/customizer.ts","../../tokens/src/base.ts","../../tokens/src/typography.ts","../../tokens/src/color-utils.ts","../../tokens/src/token-graph.ts","../src/lib/colors.ts","../src/hooks/useForm.ts","../src/lib/validation.ts"],"sourcesContent":["/**\n * Theme Store\n * Manages theme and color mode state with localStorage persistence\n */\n\nimport { create } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport type { ThemeName, ColorMode } from '@thesage/tokens';\n\n// Re-export types for convenience\nexport type { ThemeName, ColorMode };\n\ninterface ThemeState {\n // Current theme and mode\n theme: ThemeName;\n mode: ColorMode;\n\n // Actions\n setTheme: (theme: ThemeName) => void;\n setMode: (mode: ColorMode) => void;\n toggleMode: () => void;\n\n // Computed\n themeConfig: { name: ThemeName; mode: ColorMode };\n}\n\nexport const useThemeStore = create<ThemeState>()(\n persist(\n (set, get) => ({\n // Defaults\n theme: 'volt',\n mode: 'dark',\n\n // Actions\n setTheme: (theme) => set({ theme }),\n setMode: (mode) => set({ mode }),\n toggleMode: () =>\n set((state) => ({ mode: state.mode === 'light' ? 'dark' : 'light' })),\n\n // Computed\n get themeConfig() {\n const state = get();\n return { name: state.theme, mode: state.mode };\n },\n }),\n {\n name: 'ecosystem-theme',\n // Only persist theme and mode\n partialize: (state) => ({\n theme: state.theme,\n mode: state.mode,\n }),\n }\n )\n);\n","'use client';\n\nimport { useThemeStore } from '../lib/store/theme';\nimport type { ThemeName, ColorMode } from '@thesage/tokens';\n\nexport interface ThemeHook {\n /**\n * Current theme name\n */\n theme: ThemeName;\n\n /**\n * Current color mode (light/dark)\n */\n mode: ColorMode;\n\n /**\n * Set the theme\n */\n setTheme: (theme: ThemeName) => void;\n\n /**\n * Set the color mode\n */\n setMode: (mode: ColorMode) => void;\n\n /**\n * Toggle between light and dark mode\n */\n toggleMode: () => void;\n\n /**\n * Combined theme configuration\n */\n themeConfig: { name: ThemeName; mode: ColorMode };\n}\n\n/**\n * Hook to access and control theme settings\n *\n * @example\n * ```tsx\n * function ThemeSelector() {\n * const { theme, mode, setTheme, toggleMode } = useTheme();\n *\n * return (\n * <div>\n * <p>Current: {theme} - {mode}</p>\n * <button onClick={() => setTheme('sage')}>Sage Theme</button>\n * <button onClick={toggleMode}>Toggle Mode</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useTheme(): ThemeHook {\n return useThemeStore();\n}\n","'use client';\n\nimport { useEffect } from 'react';\nimport { useCustomizer } from '../lib/store/customizer';\n\nexport interface MotionPreference {\n /**\n * Motion intensity level (0-10)\n * 0 = no motion, 10 = full motion\n */\n scale: number;\n\n /**\n * Whether animations should be displayed\n * False when scale is 0 or prefersReducedMotion is true\n */\n shouldAnimate: boolean;\n\n /**\n * System preference for reduced motion\n */\n prefersReducedMotion: boolean;\n}\n\n/**\n * Hook to access motion preferences\n *\n * Automatically syncs with system `prefers-reduced-motion` media query\n * and respects user's manual motion intensity setting.\n *\n * @example\n * ```tsx\n * function AnimatedComponent() {\n * const { scale, shouldAnimate } = useMotionPreference();\n *\n * if (!shouldAnimate) {\n * return <div>Content without animation</div>;\n * }\n *\n * return (\n * <motion.div\n * animate={{ opacity: 1 }}\n * transition={{ duration: 0.3 * (scale / 10) }}\n * >\n * Content with scaled animation\n * </motion.div>\n * );\n * }\n * ```\n */\nexport function useMotionPreference(): MotionPreference {\n const { motion, prefersReducedMotion, setPrefersReducedMotion } = useCustomizer();\n\n // Listen for system prefers-reduced-motion changes\n useEffect(() => {\n // Only run in browser environment\n if (typeof window === 'undefined') return;\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n\n // Set initial value\n setPrefersReducedMotion(mediaQuery.matches);\n\n // Listen for changes\n const handleChange = (e: MediaQueryListEvent) => {\n setPrefersReducedMotion(e.matches);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, [setPrefersReducedMotion]);\n\n return {\n scale: motion,\n shouldAnimate: motion > 0 && !prefersReducedMotion,\n prefersReducedMotion,\n };\n}\n","import { create } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { computeDerivedTokens, type FontTheme } from '@thesage/tokens';\nimport {\n generateColorScale,\n getOptimalForeground,\n} from '../colors';\n\nexport type CustomizationMode = 'simple' | 'advanced';\n\nexport interface ColorPalette {\n /* Metadata */\n name?: string; // Name of the source palette\n description?: string; // Description of the source palette\n\n /* Colors */\n primary: string; // Base hex\n primaryForeground: string; // Calculated contrast\n secondary?: string; // Optional secondary color\n secondaryForeground?: string; // Calculated contrast\n accent?: string; // Optional accent color\n accentForeground?: string; // Calculated contrast\n scale: Record<number, string>; // 50-900 tints/shades\n derivedTokens: Record<string, string>; // Computed dependent tokens\n}\n\nexport interface SavedPalette {\n id: string; // Unique ID\n name: string; // User-defined name\n description: string; // Palette description\n primary: string; // Primary color hex\n accent: string; // Accent color hex\n secondary?: string; // Optional secondary color\n category: 'custom'; // Always 'custom' for user palettes\n wcagAA: boolean; // Calculated accessibility\n wcagAAA: boolean; // Calculated accessibility\n createdAt: number; // Timestamp\n mood: string[]; // Mood tags\n bestFor?: string[]; // Best use cases\n harmony?: string;\n rationale?: string;\n}\n\nexport interface SavedFontTheme extends FontTheme {\n id: string; // Unique ID (overrides FontTheme.id)\n createdAt: number; // Timestamp\n category: 'custom'; // Always 'custom' for user font themes\n}\n\nexport interface ColorCustomization {\n mode: CustomizationMode;\n palette: ColorPalette | null;\n}\n\nexport type ThemeName = 'studio' | 'sage' | 'volt';\nexport type ColorMode = 'light' | 'dark';\n\ninterface CustomizerState {\n // Motion settings\n motion: number; // 0-10\n prefersReducedMotion: boolean;\n\n // Color customization\n customizationMode: CustomizationMode;\n customColors: {\n [theme in ThemeName]?: {\n [mode in ColorMode]?: ColorPalette;\n };\n };\n\n // Saved custom palettes\n savedPalettes: SavedPalette[];\n\n // Font theme customization\n customFontThemes: {\n [theme in ThemeName]?: {\n [mode in ColorMode]?: FontTheme;\n };\n };\n\n // Saved custom font themes\n savedFontThemes: SavedFontTheme[];\n\n // Motion actions\n setMotion: (level: number) => void;\n setPrefersReducedMotion: (value: boolean) => void;\n\n // Color customization actions\n setCustomizationMode: (mode: CustomizationMode) => void;\n\n setCustomPrimaryColor: (\n theme: ThemeName,\n mode: ColorMode,\n hexColor: string\n ) => void;\n\n setCustomSecondaryColor: (\n theme: ThemeName,\n mode: ColorMode,\n hexColor: string\n ) => void;\n\n setCustomAccentColor: (\n theme: ThemeName,\n mode: ColorMode,\n hexColor: string\n ) => void;\n\n applyColorPalette: (\n theme: ThemeName,\n mode: ColorMode,\n colors: {\n primary: string;\n secondary?: string;\n accent?: string;\n name?: string;\n description?: string;\n }\n ) => void;\n\n resetCustomColors: (theme: ThemeName, mode?: ColorMode) => void;\n\n getActiveColorPalette: (theme: ThemeName, mode: ColorMode) => ColorPalette | null;\n\n // Saved palette actions\n savePalette: (palette: Omit<SavedPalette, 'id' | 'createdAt' | 'category'>) => void;\n updatePalette: (id: string, updates: Partial<SavedPalette>) => void;\n renamePalette: (id: string, newName: string) => void;\n deletePalette: (id: string) => void;\n reorderPalettes: (palettes: SavedPalette[]) => void;\n getSavedPalettes: () => SavedPalette[];\n\n // Font theme actions\n applyFontTheme: (\n theme: ThemeName,\n mode: ColorMode,\n fontTheme: FontTheme\n ) => void;\n\n resetCustomFonts: (theme: ThemeName, mode?: ColorMode) => void;\n\n getActiveFontTheme: (theme: ThemeName, mode: ColorMode) => FontTheme | null;\n\n // Saved font theme actions\n saveFontTheme: (fontTheme: Omit<SavedFontTheme, 'id' | 'createdAt' | 'category'>) => void;\n updateFontTheme: (id: string, updates: Partial<SavedFontTheme>) => void;\n renameFontTheme: (id: string, newName: string) => void;\n deleteFontTheme: (id: string) => void;\n reorderFontThemes: (fontThemes: SavedFontTheme[]) => void;\n getSavedFontThemes: () => SavedFontTheme[];\n}\n\nexport const useCustomizer = create<CustomizerState>()(\n persist(\n (set, get) => ({\n motion: 5,\n prefersReducedMotion: false,\n customizationMode: 'simple',\n customColors: {},\n savedPalettes: [],\n customFontThemes: {},\n savedFontThemes: [],\n\n setMotion: (level) => set({ motion: level }),\n setPrefersReducedMotion: (value) => set({ prefersReducedMotion: value }),\n setCustomizationMode: (mode) => set({ customizationMode: mode }),\n\n setCustomPrimaryColor: (theme, mode, hexColor) => {\n const state = get();\n const currentPalette = state.customColors[theme]?.[mode];\n\n // Generate complete color palette\n const scale = generateColorScale(hexColor);\n const primaryForeground = getOptimalForeground(hexColor);\n\n // Compute all derived tokens based on dependency graph\n const derivedTokens = computeDerivedTokens('--color-primary', hexColor, mode);\n\n // In simple mode, generate secondary/accent from primary\n const isSimple = state.customizationMode === 'simple';\n\n const palette: ColorPalette = {\n primary: hexColor,\n primaryForeground,\n secondary: isSimple ? undefined : currentPalette?.secondary,\n secondaryForeground: isSimple ? undefined : currentPalette?.secondaryForeground,\n accent: isSimple ? undefined : currentPalette?.accent,\n accentForeground: isSimple ? undefined : currentPalette?.accentForeground,\n scale,\n derivedTokens,\n };\n\n set((state) => ({\n customColors: {\n ...state.customColors,\n [theme]: {\n ...state.customColors[theme],\n [mode]: palette,\n },\n },\n }));\n },\n\n setCustomSecondaryColor: (theme, mode, hexColor) => {\n const state = get();\n const currentPalette = state.customColors[theme]?.[mode];\n\n if (!currentPalette) return;\n\n const secondaryForeground = getOptimalForeground(hexColor);\n const derivedTokens = computeDerivedTokens('--color-secondary', hexColor, mode);\n\n set((state) => ({\n customColors: {\n ...state.customColors,\n [theme]: {\n ...state.customColors[theme],\n [mode]: {\n ...currentPalette,\n secondary: hexColor,\n secondaryForeground,\n derivedTokens: {\n ...currentPalette.derivedTokens,\n ...derivedTokens,\n },\n },\n },\n },\n }));\n },\n\n setCustomAccentColor: (theme, mode, hexColor) => {\n const state = get();\n const currentPalette = state.customColors[theme]?.[mode];\n\n if (!currentPalette) return;\n\n const accentForeground = getOptimalForeground(hexColor);\n const derivedTokens = computeDerivedTokens('--color-accent', hexColor, mode);\n\n set((state) => ({\n customColors: {\n ...state.customColors,\n [theme]: {\n ...state.customColors[theme],\n [mode]: {\n ...currentPalette,\n accent: hexColor,\n accentForeground,\n derivedTokens: {\n ...currentPalette.derivedTokens,\n ...derivedTokens,\n },\n },\n },\n },\n }));\n },\n\n applyColorPalette: (theme, mode, colors: {\n primary: string;\n secondary?: string;\n accent?: string;\n name?: string;\n description?: string;\n }) => {\n // Generate complete color palette with all three colors in a single atomic update\n const scale = generateColorScale(colors.primary);\n const primaryForeground = getOptimalForeground(colors.primary);\n\n // Compute all derived tokens\n let derivedTokens = computeDerivedTokens('--color-primary', colors.primary, mode);\n\n // Add secondary color if provided\n let secondary = colors.secondary;\n let secondaryForeground = secondary ? getOptimalForeground(secondary) : undefined;\n if (secondary) {\n const secondaryDerived = computeDerivedTokens('--color-secondary', secondary, mode);\n derivedTokens = { ...derivedTokens, ...secondaryDerived };\n }\n\n // Add accent color if provided\n let accent = colors.accent;\n let accentForeground = accent ? getOptimalForeground(accent) : undefined;\n if (accent) {\n const accentDerived = computeDerivedTokens('--color-accent', accent, mode);\n derivedTokens = { ...derivedTokens, ...accentDerived };\n }\n\n const palette: ColorPalette = {\n name: colors.name,\n description: colors.description,\n primary: colors.primary,\n primaryForeground,\n secondary,\n secondaryForeground,\n accent,\n accentForeground,\n scale,\n derivedTokens,\n };\n\n set((state) => ({\n customColors: {\n ...state.customColors,\n [theme]: {\n ...state.customColors[theme],\n [mode]: palette,\n },\n },\n }));\n },\n\n resetCustomColors: (theme, mode) => {\n if (mode) {\n // Reset specific mode\n set((state) => ({\n customColors: {\n ...state.customColors,\n [theme]: {\n ...state.customColors[theme],\n [mode]: undefined,\n },\n },\n }));\n } else {\n // Reset entire theme\n set((state) => {\n const { [theme]: _, ...rest } = state.customColors;\n return { customColors: rest };\n });\n }\n },\n\n getActiveColorPalette: (theme, mode) => {\n return get().customColors[theme]?.[mode] || null;\n },\n\n // Saved palette management\n savePalette: (paletteData) => {\n const id = `custom-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const newPalette: SavedPalette = {\n ...paletteData,\n id,\n category: 'custom',\n createdAt: Date.now(),\n };\n\n set((state) => ({\n savedPalettes: [...state.savedPalettes, newPalette],\n }));\n },\n\n updatePalette: (id, updates) => {\n set((state) => ({\n savedPalettes: state.savedPalettes.map((p) =>\n p.id === id ? { ...p, ...updates } : p\n ),\n }));\n },\n\n renamePalette: (id, newName) => {\n set((state) => ({\n savedPalettes: state.savedPalettes.map((p) =>\n p.id === id ? { ...p, name: newName } : p\n ),\n }));\n },\n\n deletePalette: (id) => {\n set((state) => ({\n savedPalettes: state.savedPalettes.filter((p) => p.id !== id),\n }));\n },\n\n reorderPalettes: (palettes) => {\n set({ savedPalettes: palettes });\n },\n\n getSavedPalettes: () => {\n return get().savedPalettes;\n },\n\n // Font theme management\n applyFontTheme: (theme, mode, fontTheme) => {\n set((state) => ({\n customFontThemes: {\n ...state.customFontThemes,\n [theme]: {\n ...state.customFontThemes[theme],\n [mode]: fontTheme,\n },\n },\n }));\n },\n\n resetCustomFonts: (theme, mode) => {\n if (mode) {\n // Reset specific mode\n set((state) => ({\n customFontThemes: {\n ...state.customFontThemes,\n [theme]: {\n ...state.customFontThemes[theme],\n [mode]: undefined,\n },\n },\n }));\n } else {\n // Reset entire theme\n set((state) => {\n const { [theme]: _, ...rest } = state.customFontThemes;\n return { customFontThemes: rest };\n });\n }\n },\n\n getActiveFontTheme: (theme, mode) => {\n return get().customFontThemes[theme]?.[mode] || null;\n },\n\n // Saved font theme management\n saveFontTheme: (fontThemeData) => {\n const id = `font-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const newFontTheme: SavedFontTheme = {\n ...fontThemeData,\n id,\n category: 'custom',\n createdAt: Date.now(),\n isCustom: true,\n };\n\n set((state) => ({\n savedFontThemes: [...state.savedFontThemes, newFontTheme],\n }));\n },\n\n updateFontTheme: (id, updates) => {\n set((state) => ({\n savedFontThemes: state.savedFontThemes.map((ft) =>\n ft.id === id ? { ...ft, ...updates } : ft\n ),\n }));\n },\n\n renameFontTheme: (id, newName) => {\n set((state) => ({\n savedFontThemes: state.savedFontThemes.map((ft) =>\n ft.id === id ? { ...ft, name: newName } : ft\n ),\n }));\n },\n\n deleteFontTheme: (id) => {\n set((state) => ({\n savedFontThemes: state.savedFontThemes.filter((ft) => ft.id !== id),\n }));\n },\n\n reorderFontThemes: (fontThemes) => {\n set({ savedFontThemes: fontThemes });\n },\n\n getSavedFontThemes: () => {\n return get().savedFontThemes;\n },\n }),\n {\n name: 'ecosystem-customizer',\n version: 4,\n partialize: (state) => ({\n motion: state.motion,\n prefersReducedMotion: state.prefersReducedMotion,\n customizationMode: state.customizationMode,\n customColors: state.customColors,\n savedPalettes: state.savedPalettes,\n customFontThemes: state.customFontThemes,\n savedFontThemes: state.savedFontThemes,\n }),\n }\n )\n);\n","/**\n * Base Design Tokens\n * Shared across all themes (spacing, typography scales, motion)\n */\n\nexport const baseTokens = {\n /**\n * Spacing scale (based on 4px grid)\n */\n spacing: {\n '0': '0',\n '0.5': '0.125rem', // 2px\n '1': '0.25rem', // 4px\n '2': '0.5rem', // 8px\n '3': '0.75rem', // 12px\n '4': '1rem', // 16px\n '5': '1.25rem', // 20px\n '6': '1.5rem', // 24px\n '8': '2rem', // 32px\n '10': '2.5rem', // 40px\n '12': '3rem', // 48px\n '16': '4rem', // 64px\n '20': '5rem', // 80px\n '24': '6rem', // 96px\n '32': '8rem', // 128px\n },\n\n /**\n * Typography scales\n */\n fontSize: {\n 'xs': '0.75rem', // 12px\n 'sm': '0.875rem', // 14px\n 'base': '1rem', // 16px\n 'lg': '1.125rem', // 18px\n 'xl': '1.25rem', // 20px\n '2xl': '1.5rem', // 24px\n '3xl': '1.875rem', // 30px\n '4xl': '2.25rem', // 36px\n '5xl': '3rem', // 48px\n '6xl': '3.75rem', // 60px\n '7xl': '4.5rem', // 72px\n '8xl': '6rem', // 96px\n },\n\n fontWeight: {\n light: '300',\n normal: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n extrabold: '800',\n black: '900',\n },\n\n lineHeight: {\n none: '1',\n tight: '1.25',\n snug: '1.375',\n normal: '1.5',\n relaxed: '1.625',\n loose: '2',\n },\n\n /**\n * Border radius\n */\n borderRadius: {\n none: '0',\n sm: '0.125rem', // 2px\n DEFAULT: '0.25rem', // 4px\n md: '0.375rem', // 6px\n lg: '0.5rem', // 8px\n xl: '0.75rem', // 12px\n '2xl': '1rem', // 16px\n '3xl': '1.5rem', // 24px\n full: '9999px',\n },\n\n /**\n * Motion durations (base values - themes can override)\n */\n duration: {\n instant: '0ms',\n fast: '150ms',\n normal: '300ms',\n slow: '500ms',\n slower: '800ms',\n },\n\n /**\n * Easing curves (base values - themes can override)\n */\n ease: {\n linear: 'linear',\n in: 'cubic-bezier(0.4, 0, 1, 1)',\n out: 'cubic-bezier(0, 0, 0.2, 1)',\n inOut: 'cubic-bezier(0.4, 0, 0.2, 1)',\n },\n\n /**\n * Z-index scale\n */\n zIndex: {\n 'auto': 'auto',\n '0': '0',\n '10': '10',\n '20': '20',\n '30': '30',\n '40': '40',\n '50': '50',\n dropdown: '1000',\n sticky: '1020',\n fixed: '1030',\n modalBackdrop: '1040',\n modal: '1050',\n popover: '1060',\n tooltip: '1070',\n },\n\n /**\n * Focus ring configuration\n */\n focus: {\n width: '2px',\n offset: '2px',\n style: 'solid',\n },\n} as const;\n\nexport type BaseTokens = typeof baseTokens;\n\n/**\n * Semantic spacing aliases\n * Provides human-readable names matching the README documentation\n */\nexport const spacing = {\n xs: baseTokens.spacing['1'], // 4px — Tight internal padding\n sm: baseTokens.spacing['2'], // 8px — Default gap\n md: baseTokens.spacing['4'], // 16px — Section padding\n lg: baseTokens.spacing['6'], // 24px — Card padding\n xl: baseTokens.spacing['8'], // 32px — Section margins\n '2xl': baseTokens.spacing['12'], // 48px — Page sections\n '3xl': baseTokens.spacing['16'], // 64px — Major divisions\n} as const;\n\n/**\n * Semantic typography aliases\n */\nexport const typography = {\n fonts: {\n sans: 'var(--font-body)',\n serif: 'var(--font-heading)',\n mono: 'var(--font-mono)',\n },\n sizes: {\n xs: baseTokens.fontSize.xs, // 12px — Fine print\n sm: baseTokens.fontSize.sm, // 14px — Secondary text\n base: baseTokens.fontSize.base, // 16px — Body text\n lg: baseTokens.fontSize.lg, // 18px — Lead paragraphs\n xl: baseTokens.fontSize.xl, // 20px — Section headers\n '2xl': baseTokens.fontSize['2xl'], // 24px — Page headers\n '3xl': baseTokens.fontSize['3xl'], // 30px — Hero text\n },\n weights: {\n normal: baseTokens.fontWeight.normal, // 400\n medium: baseTokens.fontWeight.medium, // 500\n semibold: baseTokens.fontWeight.semibold, // 600\n bold: baseTokens.fontWeight.bold, // 700\n },\n leading: {\n tight: baseTokens.lineHeight.tight, // 1.25 — Headings\n normal: baseTokens.lineHeight.normal, // 1.5 — Body\n relaxed: baseTokens.lineHeight.relaxed, // 1.625 — Spacious reading\n },\n} as const;\n\n/**\n * Motion configuration\n */\nexport const motion = {\n duration: baseTokens.duration,\n easing: {\n default: baseTokens.ease.out, // Most transitions\n spring: 'cubic-bezier(0.16, 1, 0.3, 1)', // Playful interactions\n linear: baseTokens.ease.linear, // Progress indicators\n },\n} as const;\n","/**\n * Typography Tokens\n *\n * Central typography system for the design system.\n * Defines font families, sizes, weights, line heights, and letter spacing.\n *\n * Architecture:\n * - Font families are theme-specific and loaded via Next.js font optimization\n * - Sizes, weights, etc. are universal across all themes\n * - Easily extensible for new themes/font sets\n *\n * Usage:\n * 1. Import in theme-specific apps to load fonts\n * 2. Reference via CSS variables (--font-*, --text-*, etc.)\n * 3. Add to Customizer for theme switching\n */\n\n// ============================================================================\n// FONT FAMILIES\n// ============================================================================\n\n/**\n * Font Family Definitions\n *\n * Each theme has its own font personality:\n * - Studio: Modern, geometric, professional\n * - Sage: Elegant, serif + sans combo\n * - Volt: Tech-forward, consistent throughout\n *\n * To add a new theme:\n * 1. Add entry to fontFamilies\n * 2. Load fonts in consuming app's layout\n * 3. Map to CSS variables in ThemeProvider\n */\nexport const fontFamilies = {\n studio: {\n heading: 'Outfit',\n body: 'Manrope',\n mono: 'Fira Code',\n description: 'Modern geometric sans-serif with clean readability',\n usage: {\n heading: 'Headlines, titles, emphasis',\n body: 'Paragraphs, UI text, readable content',\n mono: 'Code blocks, technical content',\n },\n },\n sage: {\n heading: 'Lora', // Serif for elegance\n body: 'Instrument Sans',\n serif: 'Lora', // Explicit serif reference\n sans: 'Instrument Sans', // Explicit sans reference\n mono: 'Fira Code',\n description: 'Elegant serif headings with modern sans body',\n usage: {\n heading: 'Elegant headings, article titles',\n body: 'Long-form content, UI text',\n serif: 'Pull quotes, emphasis',\n sans: 'UI elements, captions',\n mono: 'Code blocks, technical content',\n },\n },\n volt: {\n heading: 'Space Grotesk',\n body: 'Space Grotesk',\n sans: 'Space Grotesk',\n mono: 'Fira Code',\n description: 'Tech-forward, consistent geometric throughout',\n usage: {\n heading: 'All headlines',\n body: 'All body text (unified typography)',\n sans: 'All sans-serif needs',\n mono: 'Code blocks, technical content',\n },\n },\n} as const;\n\n/**\n * Type-safe theme names based on font families\n */\nexport type TypographyTheme = keyof typeof fontFamilies;\n\n/**\n * Font loading configuration for Next.js\n * Use this to load fonts in app layouts\n */\nexport const fontLoadingConfig = {\n studio: {\n heading: { family: 'Outfit', weights: ['300', '400', '500', '600', '700', '800'] },\n body: { family: 'Manrope', weights: ['300', '400', '500', '600', '700', '800'] },\n mono: { family: 'Fira Code', weights: ['400', '500', '600', '700'] },\n },\n sage: {\n heading: { family: 'Lora', weights: ['400', '500', '600', '700'] },\n body: { family: 'Instrument Sans', weights: ['400', '500', '600', '700'] },\n mono: { family: 'Fira Code', weights: ['400', '500', '600', '700'] },\n },\n volt: {\n heading: { family: 'Space Grotesk', weights: ['300', '400', '500', '600', '700'] },\n body: { family: 'Space Grotesk', weights: ['300', '400', '500', '600', '700'] },\n mono: { family: 'Fira Code', weights: ['400', '500', '600', '700'] },\n },\n} as const;\n\n// ============================================================================\n// FONT SIZES\n// ============================================================================\n\n/**\n * Font Size Scale\n *\n * Based on a modular scale for harmonious typography.\n * Mobile-first with responsive scaling.\n *\n * Naming convention:\n * - xs, sm, base, lg, xl, 2xl, etc. for body text\n * - Numeric for headings (aligns with h1-h6)\n */\nexport const fontSizes = {\n // Body text scale\n xs: { base: '0.75rem', mobile: '0.75rem' }, // 12px\n sm: { base: '0.875rem', mobile: '0.875rem' }, // 14px\n base: { base: '1rem', mobile: '1rem' }, // 16px\n lg: { base: '1.125rem', mobile: '1rem' }, // 18px / 16px mobile\n xl: { base: '1.25rem', mobile: '1.125rem' }, // 20px / 18px mobile\n '2xl': { base: '1.5rem', mobile: '1.25rem' }, // 24px / 20px mobile\n '3xl': { base: '1.875rem', mobile: '1.5rem' }, // 30px / 24px mobile\n\n // Heading scale (h6 → h1)\n '4xl': { base: '2.25rem', mobile: '1.875rem' }, // 36px / 30px - h3\n '5xl': { base: '3rem', mobile: '2.25rem' }, // 48px / 36px - h2\n '6xl': { base: '3.75rem', mobile: '2.5rem' }, // 60px / 40px - h1\n '7xl': { base: '4.5rem', mobile: '3rem' }, // 72px / 48px - Display\n '8xl': { base: '6rem', mobile: '3.75rem' }, // 96px / 60px - Hero\n '9xl': { base: '8rem', mobile: '4.5rem' }, // 128px / 72px - Ultra\n} as const;\n\n/**\n * Semantic font size mappings\n * Maps semantic names to scale values\n */\nexport const semanticSizes = {\n 'heading-1': 'hero',\n 'heading-2': '5xl',\n 'heading-3': '4xl',\n 'heading-4': '2xl',\n 'heading-5': 'xl',\n 'heading-6': 'lg',\n 'body-large': 'lg',\n 'body': 'base',\n 'body-small': 'sm',\n 'caption': 'xs',\n} as const;\n\n// ============================================================================\n// FONT WEIGHTS\n// ============================================================================\n\n/**\n * Font Weight Scale\n *\n * Standard numeric weights with semantic aliases.\n * Not all fonts support all weights - check font-specific availability.\n */\nexport const fontWeights = {\n thin: '100',\n extralight: '200',\n light: '300',\n normal: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n extrabold: '800',\n black: '900',\n} as const;\n\n/**\n * Semantic weight mappings\n */\nexport const semanticWeights = {\n heading: 'bold', // Default heading weight\n 'heading-light': 'semibold',\n 'heading-heavy': 'extrabold',\n body: 'normal', // Default body weight\n 'body-emphasis': 'medium',\n 'body-strong': 'semibold',\n caption: 'normal',\n} as const;\n\n// ============================================================================\n// LINE HEIGHTS\n// ============================================================================\n\n/**\n * Line Height Scale\n *\n * Unitless values for better scalability.\n * Tighter for headings, relaxed for body text.\n */\nexport const lineHeights = {\n none: '1',\n tight: '1.25',\n snug: '1.375',\n normal: '1.5',\n relaxed: '1.625',\n loose: '1.75',\n extraloose: '2',\n} as const;\n\n/**\n * Semantic line height mappings\n */\nexport const semanticLineHeights = {\n heading: 'tight',\n 'heading-display': 'none', // Very tight for large display text\n body: 'normal',\n 'body-relaxed': 'relaxed',\n caption: 'snug',\n} as const;\n\n// ============================================================================\n// LETTER SPACING\n// ============================================================================\n\n/**\n * Letter Spacing (Tracking) Scale\n *\n * In ems for scalability across font sizes.\n * Negative for headings, positive for small caps.\n */\nexport const letterSpacing = {\n tighter: '-0.05em',\n tight: '-0.025em',\n normal: '0',\n wide: '0.025em',\n wider: '0.05em',\n widest: '0.1em',\n} as const;\n\n/**\n * Semantic letter spacing mappings\n */\nexport const semanticLetterSpacing = {\n heading: 'tight',\n 'heading-display': 'tighter',\n body: 'normal',\n 'small-caps': 'wider',\n 'all-caps': 'widest',\n} as const;\n\n// ============================================================================\n// TYPE SCALE PRESETS\n// ============================================================================\n\n/**\n * Complete typography presets for common use cases\n * Combines size, weight, line-height, and letter-spacing\n *\n * Usage: Apply entire preset to a component\n */\nexport const typePresets = {\n 'display-large': {\n size: fontSizes['8xl'],\n weight: fontWeights.bold,\n lineHeight: lineHeights.none,\n letterSpacing: letterSpacing.tighter,\n description: 'Large hero text, landing pages',\n },\n 'display': {\n size: fontSizes['7xl'],\n weight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n description: 'Hero sections, major headings',\n },\n 'heading-1': {\n size: fontSizes['6xl'],\n weight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.tight,\n description: 'Page titles, h1',\n },\n 'heading-2': {\n size: fontSizes['5xl'],\n weight: fontWeights.bold,\n lineHeight: lineHeights.tight,\n letterSpacing: letterSpacing.normal,\n description: 'Section titles, h2',\n },\n 'heading-3': {\n size: fontSizes['4xl'],\n weight: fontWeights.semibold,\n lineHeight: lineHeights.snug,\n letterSpacing: letterSpacing.normal,\n description: 'Subsection titles, h3',\n },\n 'heading-4': {\n size: fontSizes['2xl'],\n weight: fontWeights.semibold,\n lineHeight: lineHeights.snug,\n letterSpacing: letterSpacing.normal,\n description: 'Component titles, h4',\n },\n 'heading-5': {\n size: fontSizes.xl,\n weight: fontWeights.medium,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n description: 'Small headings, h5',\n },\n 'heading-6': {\n size: fontSizes.lg,\n weight: fontWeights.medium,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n description: 'Tiny headings, h6',\n },\n 'body-large': {\n size: fontSizes.lg,\n weight: fontWeights.normal,\n lineHeight: lineHeights.relaxed,\n letterSpacing: letterSpacing.normal,\n description: 'Lead paragraphs, intro text',\n },\n 'body': {\n size: fontSizes.base,\n weight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n description: 'Default body text',\n },\n 'body-small': {\n size: fontSizes.sm,\n weight: fontWeights.normal,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.normal,\n description: 'Small body text, fine print',\n },\n 'caption': {\n size: fontSizes.xs,\n weight: fontWeights.normal,\n lineHeight: lineHeights.snug,\n letterSpacing: letterSpacing.wide,\n description: 'Captions, labels, metadata',\n },\n 'overline': {\n size: fontSizes.xs,\n weight: fontWeights.semibold,\n lineHeight: lineHeights.normal,\n letterSpacing: letterSpacing.widest,\n description: 'Eyebrows, categories, all-caps labels',\n },\n} as const;\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Get CSS variable name for a font family\n */\nexport function getFontVariable(theme: TypographyTheme, type: 'heading' | 'body' | 'mono' | 'serif' | 'sans'): string {\n return `--font-${theme}-${type}`;\n}\n\n/**\n * Get all font family CSS variables for a theme\n */\nexport function getThemeFontVariables(theme: TypographyTheme): Record<string, string> {\n const fonts = fontFamilies[theme];\n const vars: Record<string, string> = {};\n\n Object.entries(fonts).forEach(([key, value]) => {\n if (typeof value === 'string') {\n vars[`--font-${theme}-${key}`] = value;\n }\n });\n\n return vars;\n}\n\n/**\n * Get responsive font size CSS\n */\nexport function getResponsiveFontSize(sizeKey: keyof typeof fontSizes): string {\n const size = fontSizes[sizeKey];\n return `font-size: ${size.mobile}; @media (min-width: 768px) { font-size: ${size.base}; }`;\n}\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\n/**\n * Complete typography system export\n * Import this for access to entire typography token set\n *\n * Note: This is the comprehensive typography system with font families,\n * scales, presets, and utilities. For simple semantic aliases compatible\n * with existing code, use `typography` from './base'\n */\nexport const typographySystem = {\n families: fontFamilies,\n sizes: fontSizes,\n weights: fontWeights,\n lineHeights,\n letterSpacing,\n presets: typePresets,\n semantic: {\n sizes: semanticSizes,\n weights: semanticWeights,\n lineHeights: semanticLineHeights,\n letterSpacing: semanticLetterSpacing,\n },\n utils: {\n getFontVariable,\n getThemeFontVariables,\n getResponsiveFontSize,\n },\n} as const;\n\n/**\n * Type exports for TypeScript consumers\n */\nexport type FontSize = keyof typeof fontSizes;\nexport type FontWeight = keyof typeof fontWeights;\nexport type LineHeight = keyof typeof lineHeights;\nexport type LetterSpacing = keyof typeof letterSpacing;\nexport type TypePreset = keyof typeof typePresets;\n","/**\n * Color Transformation Utilities\n * Standalone utilities for the token system (no external dependencies)\n */\n\n/**\n * Convert hex to RGB\n */\nexport function hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16),\n }\n : null;\n}\n\n/**\n * Convert hex to HSL\n */\nexport function hexToHSL(hex: string): { h: number; s: number; l: number } {\n const rgb = hexToRgb(hex);\n if (!rgb) return { h: 0, s: 0, l: 0 };\n\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h = 0, s = 0, l = (max + min) / 2;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n switch (max) {\n case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;\n case g: h = ((b - r) / d + 2) / 6; break;\n case b: h = ((r - g) / d + 4) / 6; break;\n }\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\n/**\n * Convert HSL to hex\n */\nexport function hslToHex(h: number, s: number, l: number): string {\n h = h / 360;\n s = s / 100;\n l = l / 100;\n\n let r, g, b;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1/6) return p + (q - p) * 6 * t;\n if (t < 1/2) return q;\n if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n return p;\n };\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n r = hue2rgb(p, q, h + 1/3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1/3);\n }\n\n const toHex = (x: number) => {\n const hex = Math.round(x * 255).toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n };\n\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\n/**\n * Adjust lightness of a hex color\n */\nexport function adjustLightness(hex: string, percent: number): string {\n const hsl = hexToHSL(hex);\n const newL = Math.max(0, Math.min(100, hsl.l + percent));\n return hslToHex(hsl.h, hsl.s, newL);\n}\n\n/**\n * Adjust saturation of a hex color\n */\nexport function adjustSaturation(hex: string, percent: number): string {\n const hsl = hexToHSL(hex);\n const newS = Math.max(0, Math.min(100, hsl.s + percent));\n return hslToHex(hsl.h, newS, hsl.l);\n}\n\n/**\n * Rotate hue of a hex color\n */\nexport function rotateHue(hex: string, degrees: number): string {\n const hsl = hexToHSL(hex);\n const newH = (hsl.h + degrees) % 360;\n return hslToHex(newH, hsl.s, hsl.l);\n}\n\n/**\n * Add opacity to a hex color (returns rgba CSS value)\n */\nexport function adjustOpacity(hex: string, opacity: number): string {\n const rgb = hexToRgb(hex);\n if (!rgb) return hex;\n return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${opacity})`;\n}\n\n/**\n * Calculate relative luminance (WCAG formula)\n */\nexport function getLuminance(r: number, g: number, b: number): number {\n const [rs, gs, bs] = [r, g, b].map((c) => {\n const srgb = c / 255;\n return srgb <= 0.03928 ? srgb / 12.92 : Math.pow((srgb + 0.055) / 1.055, 2.4);\n });\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n}\n\n/**\n * Calculate contrast ratio between two colors (WCAG formula)\n */\nexport function getContrastRatio(hex1: string, hex2: string): number {\n const rgb1 = hexToRgb(hex1);\n const rgb2 = hexToRgb(hex2);\n\n if (!rgb1 || !rgb2) return 0;\n\n const lum1 = getLuminance(rgb1.r, rgb1.g, rgb1.b);\n const lum2 = getLuminance(rgb2.r, rgb2.g, rgb2.b);\n\n const lighter = Math.max(lum1, lum2);\n const darker = Math.min(lum1, lum2);\n\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Get optimal foreground color (white or black) for a background\n */\nexport function getOptimalForeground(\n bgHex: string,\n whiteHex: string = '#ffffff',\n blackHex: string = '#000000'\n): string {\n const whiteRatio = getContrastRatio(bgHex, whiteHex);\n const blackRatio = getContrastRatio(bgHex, blackHex);\n\n return whiteRatio > blackRatio ? whiteHex : blackHex;\n}\n","/**\n * Token Dependency Graph\n * Defines which tokens are computed from other tokens for \"change once, ripple everywhere\"\n */\n\nimport {\n adjustLightness,\n adjustSaturation,\n adjustOpacity,\n rotateHue,\n getOptimalForeground,\n} from './color-utils';\n\nexport type TokenDerivation = {\n source: string; // Which token it derives from\n transform: (sourceValue: string) => string; // How to compute it\n description: string; // Why this derivation exists\n};\n\n/**\n * Primary Color Derivations\n * These tokens automatically update when primary color changes\n */\nexport const primaryColorDerivations: Record<string, TokenDerivation> = {\n // Links use primary color\n '--color-link': {\n source: '--color-primary',\n transform: (primary) => primary,\n description: 'Links inherit primary brand color',\n },\n\n // Focus ring uses primary color\n '--color-ring': {\n source: '--color-primary',\n transform: (primary) => primary,\n description: 'Focus rings use primary for brand consistency',\n },\n\n // Link hover is slightly darker primary\n '--color-link-hover': {\n source: '--color-primary',\n transform: (primary) => adjustLightness(primary, -10),\n description: 'Link hover is 10% darker for visual feedback',\n },\n\n // Chart primary series\n '--chart-1': {\n source: '--color-primary',\n transform: (primary) => primary,\n description: 'First chart series uses primary',\n },\n\n // Chart secondary series (lighter tint)\n '--chart-2': {\n source: '--color-primary',\n transform: (primary) => adjustLightness(primary, 20),\n description: 'Second chart series is lighter tint of primary',\n },\n\n // Chart tertiary series (darker shade)\n '--chart-3': {\n source: '--color-primary',\n transform: (primary) => adjustLightness(primary, -15),\n description: 'Third chart series is darker shade of primary',\n },\n\n // Chart quaternary (desaturated primary)\n '--chart-4': {\n source: '--color-primary',\n transform: (primary) => adjustSaturation(primary, -30),\n description: 'Fourth chart series is muted primary',\n },\n\n // Chart quinary (complementary color)\n '--chart-5': {\n source: '--color-primary',\n transform: (primary) => rotateHue(primary, 180),\n description: 'Fifth chart series is complementary to primary',\n },\n};\n\n/**\n * Secondary Color Derivations\n * These derive from secondary color\n */\nexport const secondaryColorDerivations: Record<string, TokenDerivation> = {\n // Hover states\n '--color-hover': {\n source: '--color-secondary',\n transform: (secondary) => secondary,\n description: 'Hover backgrounds use secondary',\n },\n\n // Active states\n '--color-active': {\n source: '--color-secondary',\n transform: (secondary) => adjustLightness(secondary, -5),\n description: 'Active state is slightly darker secondary',\n },\n\n // Muted backgrounds\n '--color-muted': {\n source: '--color-secondary',\n transform: (secondary) => secondary,\n description: 'Muted sections use secondary color',\n },\n};\n\n/**\n * Accent Color Derivations\n * These derive from accent (used for highlights and CTAs)\n */\nexport const accentColorDerivations: Record<string, TokenDerivation> = {\n // Info semantic color uses accent\n '--color-info': {\n source: '--color-accent',\n transform: (accent) => accent,\n description: 'Info semantic color uses accent',\n },\n\n // Info foreground calculated for contrast\n '--color-info-foreground': {\n source: '--color-accent',\n transform: (accent) => getOptimalForeground(accent),\n description: 'Info foreground calculated for contrast',\n },\n};\n\n/**\n * Mode-Specific Derivations\n * These need different transforms for light vs dark mode\n */\nexport const modeSpecificDerivations: Record<string, {\n light: TokenDerivation;\n dark: TokenDerivation;\n}> = {\n '--color-primary-muted': {\n light: {\n source: '--color-primary',\n transform: (primary) => adjustLightness(primary, 40),\n description: 'Muted primary for light backgrounds',\n },\n dark: {\n source: '--color-primary',\n transform: (primary) => adjustLightness(primary, -20),\n description: 'Muted primary for dark backgrounds',\n },\n },\n\n '--color-primary-subtle': {\n light: {\n source: '--color-primary',\n transform: (primary) => adjustOpacity(primary, 0.1),\n description: 'Subtle primary background for light mode',\n },\n dark: {\n source: '--color-primary',\n transform: (primary) => adjustOpacity(primary, 0.2),\n description: 'Subtle primary background for dark mode',\n },\n },\n};\n\n/**\n * Complete dependency graph\n */\nexport const tokenDependencyGraph = {\n primary: primaryColorDerivations,\n secondary: secondaryColorDerivations,\n accent: accentColorDerivations,\n modeSpecific: modeSpecificDerivations,\n};\n\n/**\n * Get all tokens that depend on a source token\n */\nexport function getDependentTokens(sourceToken: string): string[] {\n const dependents: string[] = [];\n\n Object.entries(primaryColorDerivations).forEach(([token, config]) => {\n if (config.source === sourceToken) {\n dependents.push(token);\n }\n });\n\n Object.entries(secondaryColorDerivations).forEach(([token, config]) => {\n if (config.source === sourceToken) {\n dependents.push(token);\n }\n });\n\n Object.entries(accentColorDerivations).forEach(([token, config]) => {\n if (config.source === sourceToken) {\n dependents.push(token);\n }\n });\n\n return dependents;\n}\n\n/**\n * Compute all derived tokens from a source\n */\nexport function computeDerivedTokens(\n sourceToken: string,\n sourceValue: string,\n mode: 'light' | 'dark'\n): Record<string, string> {\n const derived: Record<string, string> = {};\n\n // Compute from primary derivations\n Object.entries(primaryColorDerivations).forEach(([token, config]) => {\n if (config.source === sourceToken) {\n derived[token] = config.transform(sourceValue);\n }\n });\n\n // Compute from secondary derivations\n Object.entries(secondaryColorDerivations).forEach(([token, config]) => {\n if (config.source === sourceToken) {\n derived[token] = config.transform(sourceValue);\n }\n });\n\n // Compute from accent derivations\n Object.entries(accentColorDerivations).forEach(([token, config]) => {\n if (config.source === sourceToken) {\n derived[token] = config.transform(sourceValue);\n }\n });\n\n // Compute mode-specific derivations\n Object.entries(modeSpecificDerivations).forEach(([token, configs]) => {\n const config = configs[mode];\n if (config.source === sourceToken) {\n derived[token] = config.transform(sourceValue);\n }\n });\n\n return derived;\n}\n","/**\n * Semantic Color Utilities\n *\n * Helper functions for working with the design system's color tokens\n * and CSS variables.\n */\n\n/**\n * Color token categories\n */\nexport const colorTokens = {\n // Background colors\n background: 'var(--color-background)',\n backgroundSecondary: 'var(--color-background-secondary)',\n backgroundTertiary: 'var(--color-background-tertiary)',\n surface: 'var(--color-surface)',\n\n // Foreground/Text colors\n foreground: 'var(--color-foreground)',\n foregroundSecondary: 'var(--color-foreground-secondary)',\n foregroundTertiary: 'var(--color-foreground-tertiary)',\n textPrimary: 'var(--color-text-primary)',\n textSecondary: 'var(--color-text-secondary)',\n textMuted: 'var(--color-text-muted)',\n\n // Brand colors\n primary: 'var(--color-primary)',\n primaryForeground: 'var(--color-primary-foreground)',\n secondary: 'var(--color-secondary)',\n secondaryForeground: 'var(--color-secondary-foreground)',\n accent: 'var(--color-accent)',\n accentForeground: 'var(--color-accent-foreground)',\n\n // Semantic colors\n success: 'var(--color-success)',\n successForeground: 'var(--color-success-foreground)',\n warning: 'var(--color-warning)',\n warningForeground: 'var(--color-warning-foreground)',\n error: 'var(--color-error)',\n errorForeground: 'var(--color-error-foreground)',\n info: 'var(--color-info)',\n infoForeground: 'var(--color-info-foreground)',\n\n // Borders\n border: 'var(--color-border)',\n borderSubtle: 'var(--color-border-subtle)',\n\n // Interactive states\n hover: 'var(--color-hover)',\n active: 'var(--color-active)',\n focus: 'var(--color-focus)',\n\n // Links\n link: 'var(--color-link)',\n linkHover: 'var(--color-link-hover)',\n linkHoverForeground: 'var(--color-link-hover-foreground)',\n} as const;\n\n/**\n * Get CSS variable value from computed styles\n *\n * @param variableName - CSS variable name (with or without --)\n * @param element - Element to get computed style from (defaults to document.documentElement)\n * @returns The computed value of the CSS variable\n *\n * @example\n * ```ts\n * const primaryColor = getCSSVariable('--color-primary');\n * // Returns: '#0066ff' (or whatever the current theme's primary color is)\n * ```\n */\nexport function getCSSVariable(\n variableName: string,\n element: HTMLElement = document.documentElement\n): string {\n const name = variableName.startsWith('--') ? variableName : `--${variableName}`;\n return getComputedStyle(element).getPropertyValue(name).trim();\n}\n\n/**\n * Set CSS variable value\n *\n * @param variableName - CSS variable name (with or without --)\n * @param value - Value to set\n * @param element - Element to set the variable on (defaults to document.documentElement)\n *\n * @example\n * ```ts\n * setCSSVariable('--color-primary', '#ff0000');\n * ```\n */\nexport function setCSSVariable(\n variableName: string,\n value: string,\n element: HTMLElement = document.documentElement\n): void {\n const name = variableName.startsWith('--') ? variableName : `--${variableName}`;\n element.style.setProperty(name, value);\n}\n\n/**\n * Get contrasting foreground color for a background color\n *\n * @param backgroundToken - Background color token name (without 'var()')\n * @returns The appropriate foreground color token\n *\n * @example\n * ```ts\n * const foreground = getForegroundColor('--color-primary');\n * // Returns: 'var(--color-primary-foreground)'\n * ```\n */\nexport function getForegroundColor(backgroundToken: string): string {\n // Remove var() wrapper if present\n const token = backgroundToken.replace(/var\\(|\\)/g, '');\n\n // Map background tokens to their foreground pairs\n const foregroundMap: Record<string, string> = {\n '--color-primary': 'var(--color-primary-foreground)',\n '--color-secondary': 'var(--color-secondary-foreground)',\n '--color-accent': 'var(--color-accent-foreground)',\n '--color-success': 'var(--color-success-foreground)',\n '--color-warning': 'var(--color-warning-foreground)',\n '--color-error': 'var(--color-error-foreground)',\n '--color-info': 'var(--color-info-foreground)',\n '--color-background': 'var(--color-foreground)',\n '--color-surface': 'var(--color-text-primary)',\n };\n\n return foregroundMap[token] || 'var(--color-text-primary)';\n}\n\n/**\n * Semantic color groups for different use cases\n */\nexport const semanticColors = {\n /**\n * Status colors for indicating states\n */\n status: {\n success: {\n bg: colorTokens.success,\n fg: colorTokens.successForeground,\n },\n warning: {\n bg: colorTokens.warning,\n fg: colorTokens.warningForeground,\n },\n error: {\n bg: colorTokens.error,\n fg: colorTokens.errorForeground,\n },\n info: {\n bg: colorTokens.info,\n fg: colorTokens.infoForeground,\n },\n },\n\n /**\n * Brand colors for primary UI elements\n */\n brand: {\n primary: {\n bg: colorTokens.primary,\n fg: colorTokens.primaryForeground,\n },\n secondary: {\n bg: colorTokens.secondary,\n fg: colorTokens.secondaryForeground,\n },\n accent: {\n bg: colorTokens.accent,\n fg: colorTokens.accentForeground,\n },\n },\n\n /**\n * Interactive state colors\n */\n interactive: {\n default: {\n bg: colorTokens.background,\n fg: colorTokens.foreground,\n },\n hover: {\n bg: colorTokens.hover,\n fg: colorTokens.foreground,\n },\n active: {\n bg: colorTokens.active,\n fg: colorTokens.foreground,\n },\n focus: {\n border: colorTokens.focus,\n },\n },\n} as const;\n\n/**\n * Helper to create color pairs (background + foreground)\n *\n * @param type - Semantic color type\n * @returns Object with bg and fg (and optionally border)\n *\n * @example\n * ```tsx\n * const errorColors = getSemanticColorPair('error');\n * <div style={{\n * backgroundColor: errorColors.bg,\n * color: errorColors.fg\n * }}>\n * Error message\n * </div>\n * ```\n */\nexport function getSemanticColorPair(\n type: 'success' | 'warning' | 'error' | 'info' | 'primary' | 'secondary' | 'accent'\n): { bg: string; fg: string } {\n if (type === 'primary' || type === 'secondary' || type === 'accent') {\n return semanticColors.brand[type];\n }\n return semanticColors.status[type];\n}\n\n/**\n * Convert hex color to RGB values\n *\n * @param hex - Hex color string (with or without #)\n * @returns Object with r, g, b values (0-255)\n *\n * @example\n * ```ts\n * const rgb = hexToRgb('#0066ff');\n * // Returns: { r: 0, g: 102, b: 255 }\n * ```\n */\nexport function hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16),\n }\n : null;\n}\n\n/**\n * Calculate relative luminance of a color (WCAG formula)\n *\n * @param r - Red value (0-255)\n * @param g - Green value (0-255)\n * @param b - Blue value (0-255)\n * @returns Relative luminance (0-1)\n */\nexport function getLuminance(r: number, g: number, b: number): number {\n const [rs, gs, bs] = [r, g, b].map((c) => {\n const srgb = c / 255;\n return srgb <= 0.03928 ? srgb / 12.92 : Math.pow((srgb + 0.055) / 1.055, 2.4);\n });\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n}\n\n/**\n * Calculate contrast ratio between two colors (WCAG formula)\n *\n * @param hex1 - First color (hex)\n * @param hex2 - Second color (hex)\n * @returns Contrast ratio (1-21)\n *\n * @example\n * ```ts\n * const ratio = getContrastRatio('#ffffff', '#000000');\n * // Returns: 21 (maximum contrast)\n * ```\n */\nexport function getContrastRatio(hex1: string, hex2: string): number {\n const rgb1 = hexToRgb(hex1);\n const rgb2 = hexToRgb(hex2);\n\n if (!rgb1 || !rgb2) return 0;\n\n const lum1 = getLuminance(rgb1.r, rgb1.g, rgb1.b);\n const lum2 = getLuminance(rgb2.r, rgb2.g, rgb2.b);\n\n const lighter = Math.max(lum1, lum2);\n const darker = Math.min(lum1, lum2);\n\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * Check if color pair meets WCAG AA contrast requirements\n *\n * @param foreground - Foreground color (hex)\n * @param background - Background color (hex)\n * @param level - WCAG level ('AA' or 'AAA')\n * @param size - Text size ('normal' or 'large')\n * @returns true if contrast ratio meets requirements\n *\n * @example\n * ```ts\n * const isAccessible = meetsContrastRequirements('#000000', '#ffffff', 'AA', 'normal');\n * // Returns: true\n * ```\n */\nexport function meetsContrastRequirements(\n foreground: string,\n background: string,\n level: 'AA' | 'AAA' = 'AA',\n size: 'normal' | 'large' = 'normal'\n): boolean {\n const ratio = getContrastRatio(foreground, background);\n\n const requirements = {\n AA: { normal: 4.5, large: 3 },\n AAA: { normal: 7, large: 4.5 },\n };\n\n return ratio >= requirements[level][size];\n}\n\n/**\n * Convert hex to HSL for manipulation\n */\nexport function hexToHSL(hex: string): { h: number; s: number; l: number } {\n const rgb = hexToRgb(hex);\n if (!rgb) return { h: 0, s: 0, l: 0 };\n\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h = 0, s = 0, l = (max + min) / 2;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n switch (max) {\n case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;\n case g: h = ((b - r) / d + 2) / 6; break;\n case b: h = ((r - g) / d + 4) / 6; break;\n }\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n };\n}\n\n/**\n * Convert HSL to hex\n */\nexport function hslToHex(h: number, s: number, l: number): string {\n h = h / 360;\n s = s / 100;\n l = l / 100;\n\n let r, g, b;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1/6) return p + (q - p) * 6 * t;\n if (t < 1/2) return q;\n if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n return p;\n };\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n r = hue2rgb(p, q, h + 1/3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1/3);\n }\n\n const toHex = (x: number) => {\n const hex = Math.round(x * 255).toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n };\n\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\n/**\n * Adjust lightness of a hex color\n * @param hex - Input color\n * @param percent - Amount to adjust (-100 to 100)\n */\nexport function adjustLightness(hex: string, percent: number): string {\n const hsl = hexToHSL(hex);\n const newL = Math.max(0, Math.min(100, hsl.l + percent));\n return hslToHex(hsl.h, hsl.s, newL);\n}\n\n/**\n * Adjust saturation of a hex color\n * @param hex - Input color\n * @param percent - Amount to adjust (-100 to 100)\n */\nexport function adjustSaturation(hex: string, percent: number): string {\n const hsl = hexToHSL(hex);\n const newS = Math.max(0, Math.min(100, hsl.s + percent));\n return hslToHex(hsl.h, newS, hsl.l);\n}\n\n/**\n * Rotate hue of a hex color\n * @param hex - Input color\n * @param degrees - Degrees to rotate (0-360)\n */\nexport function rotateHue(hex: string, degrees: number): string {\n const hsl = hexToHSL(hex);\n const newH = (hsl.h + degrees) % 360;\n return hslToHex(newH, hsl.s, hsl.l);\n}\n\n/**\n * Add opacity to a hex color (returns rgba CSS value)\n * @param hex - Input color\n * @param opacity - Opacity (0-1)\n */\nexport function adjustOpacity(hex: string, opacity: number): string {\n const rgb = hexToRgb(hex);\n if (!rgb) return hex;\n return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${opacity})`;\n}\n\n/**\n * Get optimal foreground color (white or black) for a background\n * Uses WCAG contrast formula\n */\nexport function getOptimalForeground(\n bgHex: string,\n whiteHex: string = '#ffffff',\n blackHex: string = '#000000'\n): string {\n const whiteRatio = getContrastRatio(bgHex, whiteHex);\n const blackRatio = getContrastRatio(bgHex, blackHex);\n\n return whiteRatio > blackRatio ? whiteHex : blackHex;\n}\n\n/**\n * Generate a complete tint/shade scale (like Tailwind)\n * Returns 50, 100, 200, ..., 900 variants\n */\nexport function generateColorScale(baseHex: string): Record<number, string> {\n const hsl = hexToHSL(baseHex);\n\n return {\n 50: hslToHex(hsl.h, Math.max(hsl.s - 10, 20), 95),\n 100: hslToHex(hsl.h, Math.max(hsl.s - 5, 30), 90),\n 200: hslToHex(hsl.h, hsl.s, 80),\n 300: hslToHex(hsl.h, hsl.s, 70),\n 400: hslToHex(hsl.h, hsl.s, 60),\n 500: baseHex, // Base color\n 600: hslToHex(hsl.h, Math.min(hsl.s + 5, 100), 45),\n 700: hslToHex(hsl.h, Math.min(hsl.s + 10, 100), 35),\n 800: hslToHex(hsl.h, Math.min(hsl.s + 15, 100), 25),\n 900: hslToHex(hsl.h, Math.min(hsl.s + 20, 100), 15),\n };\n}\n\n/**\n * Color utilities for common operations\n */\nexport const colorUtils = {\n getCSSVariable,\n setCSSVariable,\n getForegroundColor,\n getSemanticColorPair,\n hexToRgb,\n hexToHSL,\n hslToHex,\n adjustLightness,\n adjustSaturation,\n rotateHue,\n adjustOpacity,\n getOptimalForeground,\n generateColorScale,\n getContrastRatio,\n meetsContrastRequirements,\n} as const;\n","'use client';\n\nimport { useState, useCallback } from 'react';\nimport type { FieldValidation, FormErrors } from '../lib/validation';\nimport { validateField, validateForm } from '../lib/validation';\n\nexport interface UseFormOptions<T> {\n /**\n * Initial form values\n */\n initialValues: T;\n\n /**\n * Validation rules for each field\n */\n validations?: Partial<Record<keyof T, FieldValidation>>;\n\n /**\n * Callback fired when form is submitted and valid\n */\n onSubmit?: (values: T) => void | Promise<void>;\n\n /**\n * When to validate fields\n * @default 'onBlur'\n */\n validateOn?: 'onChange' | 'onBlur' | 'onSubmit';\n}\n\nexport interface UseFormReturn<T> {\n /**\n * Current form values\n */\n values: T;\n\n /**\n * Current form errors\n */\n errors: FormErrors;\n\n /**\n * Whether the form is currently submitting\n */\n isSubmitting: boolean;\n\n /**\n * Whether the form has been touched/modified\n */\n isDirty: boolean;\n\n /**\n * Set value for a specific field\n */\n setValue: (name: keyof T, value: any) => void;\n\n /**\n * Set error for a specific field\n */\n setError: (name: keyof T, error: string | undefined) => void;\n\n /**\n * Handle input change event\n */\n handleChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => void;\n\n /**\n * Handle input blur event\n */\n handleBlur: (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => void;\n\n /**\n * Handle form submit\n */\n handleSubmit: (e?: React.FormEvent<HTMLFormElement>) => Promise<void>;\n\n /**\n * Reset form to initial values\n */\n reset: () => void;\n\n /**\n * Manually validate all fields\n */\n validate: () => boolean;\n\n /**\n * Get props for a field (value, onChange, onBlur, error)\n */\n getFieldProps: (name: keyof T) => {\n name: string;\n value: any;\n onChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => void;\n onBlur: (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => void;\n error: boolean;\n };\n}\n\n/**\n * useForm Hook\n *\n * A lightweight form state management hook with built-in validation.\n *\n * Features:\n * - Field-level validation\n * - Configurable validation timing (onChange, onBlur, onSubmit)\n * - Dirty state tracking\n * - Submit handling with loading state\n * - Helper functions for common patterns\n *\n * Example:\n * ```tsx\n * const form = useForm({\n * initialValues: { email: '', password: '' },\n * validations: {\n * email: { required: true, pattern: patterns.email },\n * password: { required: true, minLength: { value: 8, message: 'Min 8 chars' } }\n * },\n * onSubmit: async (values) => {\n * await login(values);\n * }\n * });\n *\n * return (\n * <form onSubmit={form.handleSubmit}>\n * <FormField label=\"Email\" error={form.errors.email}>\n * <TextField {...form.getFieldProps('email')} />\n * </FormField>\n * <Button type=\"submit\" loading={form.isSubmitting}>Submit</Button>\n * </form>\n * );\n * ```\n */\nexport function useForm<T extends Record<string, any>>({\n initialValues,\n validations = {},\n onSubmit,\n validateOn = 'onBlur',\n}: UseFormOptions<T>): UseFormReturn<T> {\n const [values, setValues] = useState<T>(initialValues);\n const [errors, setErrors] = useState<FormErrors>({});\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isDirty, setIsDirty] = useState(false);\n\n const setValue = useCallback((name: keyof T, value: any) => {\n setValues((prev) => ({ ...prev, [name]: value }));\n setIsDirty(true);\n }, []);\n\n const setError = useCallback((name: keyof T, error: string | undefined) => {\n setErrors((prev) => ({ ...prev, [name as string]: error }));\n }, []);\n\n const validateFieldByName = useCallback(\n (name: keyof T) => {\n const fieldRules = validations[name];\n if (!fieldRules) return;\n\n const error = validateField(values[name], fieldRules);\n setError(name, error);\n return !error;\n },\n [values, validations, setError]\n );\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {\n const { name, value, type } = e.target;\n const fieldValue = type === 'checkbox' ? (e.target as HTMLInputElement).checked : value;\n\n setValue(name as keyof T, fieldValue);\n\n if (validateOn === 'onChange') {\n validateFieldByName(name as keyof T);\n }\n },\n [setValue, validateOn, validateFieldByName]\n );\n\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {\n const { name } = e.target;\n\n if (validateOn === 'onBlur') {\n validateFieldByName(name as keyof T);\n }\n },\n [validateOn, validateFieldByName]\n );\n\n const validate = useCallback(() => {\n const formErrors = validateForm(values, validations as any);\n setErrors(formErrors);\n return Object.keys(formErrors).length === 0;\n }, [values, validations]);\n\n const handleSubmit = useCallback(\n async (e?: React.FormEvent<HTMLFormElement>) => {\n e?.preventDefault();\n\n const isValid = validate();\n if (!isValid) return;\n\n if (onSubmit) {\n setIsSubmitting(true);\n try {\n await onSubmit(values);\n } finally {\n setIsSubmitting(false);\n }\n }\n },\n [validate, onSubmit, values]\n );\n\n const reset = useCallback(() => {\n setValues(initialValues);\n setErrors({});\n setIsDirty(false);\n setIsSubmitting(false);\n }, [initialValues]);\n\n const getFieldProps = useCallback(\n (name: keyof T) => ({\n name: name as string,\n value: values[name] ?? '',\n onChange: handleChange,\n onBlur: handleBlur,\n error: !!errors[name as string],\n }),\n [values, errors, handleChange, handleBlur]\n );\n\n return {\n values,\n errors,\n isSubmitting,\n isDirty,\n setValue,\n setError,\n handleChange,\n handleBlur,\n handleSubmit,\n reset,\n validate,\n getFieldProps,\n };\n}\n","/**\n * Form Validation Utilities\n *\n * Simple validation helpers for form fields.\n * Works seamlessly with FormField and other form components.\n */\n\nexport type ValidationRule = {\n validate: (value: any) => boolean;\n message: string;\n};\n\nexport type FieldValidation = {\n required?: boolean | string;\n minLength?: { value: number; message: string };\n maxLength?: { value: number; message: string };\n pattern?: { value: RegExp; message: string };\n custom?: ValidationRule[];\n};\n\nexport type FormErrors = Record<string, string | undefined>;\n\n/**\n * Common validation patterns\n */\nexport const patterns = {\n email: {\n value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i,\n message: 'Invalid email address',\n },\n url: {\n value: /^https?:\\/\\/.+\\..+/,\n message: 'Invalid URL',\n },\n phone: {\n value: /^[\\d\\s\\-\\+\\(\\)]+$/,\n message: 'Invalid phone number',\n },\n alphanumeric: {\n value: /^[a-zA-Z0-9]+$/,\n message: 'Only letters and numbers allowed',\n },\n noSpaces: {\n value: /^\\S+$/,\n message: 'Spaces are not allowed',\n },\n};\n\n/**\n * Validate a single field value against validation rules\n *\n * @param value - The field value to validate\n * @param rules - Validation rules to apply\n * @returns Error message if validation fails, undefined if valid\n *\n * @example\n * ```tsx\n * const error = validateField(email, {\n * required: true,\n * pattern: patterns.email\n * });\n * ```\n */\nexport function validateField(\n value: any,\n rules: FieldValidation\n): string | undefined {\n // Required check\n if (rules.required) {\n const isEmpty =\n value === undefined ||\n value === null ||\n value === '' ||\n (Array.isArray(value) && value.length === 0);\n\n if (isEmpty) {\n return typeof rules.required === 'string'\n ? rules.required\n : 'This field is required';\n }\n }\n\n // Skip other validations if value is empty and not required\n if (!value && !rules.required) {\n return undefined;\n }\n\n // Min length check\n if (rules.minLength && value.length < rules.minLength.value) {\n return rules.minLength.message;\n }\n\n // Max length check\n if (rules.maxLength && value.length > rules.maxLength.value) {\n return rules.maxLength.message;\n }\n\n // Pattern check\n if (rules.pattern && !rules.pattern.value.test(value)) {\n return rules.pattern.message;\n }\n\n // Custom validations\n if (rules.custom) {\n for (const rule of rules.custom) {\n if (!rule.validate(value)) {\n return rule.message;\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Validate all fields in a form\n *\n * @param values - Object containing all form field values\n * @param validations - Object containing validation rules for each field\n * @returns Object containing errors for each field\n *\n * @example\n * ```tsx\n * const errors = validateForm(\n * { email: 'test', password: '123' },\n * {\n * email: { required: true, pattern: patterns.email },\n * password: { required: true, minLength: { value: 8, message: 'Min 8 chars' } }\n * }\n * );\n * // errors = { email: 'Invalid email address', password: 'Min 8 chars' }\n * ```\n */\nexport function validateForm(\n values: Record<string, any>,\n validations: Record<string, FieldValidation>\n): FormErrors {\n const errors: FormErrors = {};\n\n for (const [field, rules] of Object.entries(validations)) {\n const error = validateField(values[field], rules);\n if (error) {\n errors[field] = error;\n }\n }\n\n return errors;\n}\n\n/**\n * Check if form has any errors\n *\n * @param errors - Form errors object\n * @returns true if there are any errors\n *\n * @example\n * ```tsx\n * if (hasErrors(errors)) {\n * console.log('Form has errors');\n * }\n * ```\n */\nexport function hasErrors(errors: FormErrors): boolean {\n return Object.values(errors).some((error) => error !== undefined);\n}\n\n/**\n * Common validation rule builders\n */\nexport const rules = {\n required: (message = 'This field is required'): FieldValidation => ({\n required: message,\n }),\n\n email: (message = 'Invalid email address'): FieldValidation => ({\n pattern: { value: patterns.email.value, message },\n }),\n\n minLength: (length: number, message?: string): FieldValidation => ({\n minLength: {\n value: length,\n message: message || `Minimum ${length} characters required`,\n },\n }),\n\n maxLength: (length: number, message?: string): FieldValidation => ({\n maxLength: {\n value: length,\n message: message || `Maximum ${length} characters allowed`,\n },\n }),\n\n match: (\n otherValue: any,\n message = 'Values do not match'\n ): FieldValidation => ({\n custom: [\n {\n validate: (value) => value === otherValue,\n message,\n },\n ],\n }),\n};\n"],"mappings":"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","names":["create","persist","p","q","hexToRgb","getLuminance","getContrastRatio","hexToHSL","hexToRgb","hslToHex","p","q","getOptimalForeground","getContrastRatio","hexToHSL","hslToHex","create","persist","getOptimalForeground","state","motion"]}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Design Tokens Exports
3
+ */
4
+
5
+ /**
6
+ * Theme names
7
+ */
8
+ declare const THEME_NAMES: readonly ["studio", "sage", "volt"];
9
+ type ThemeName = typeof THEME_NAMES[number];
10
+ /**
11
+ * Color modes
12
+ */
13
+ declare const COLOR_MODES: readonly ["light", "dark"];
14
+ type ColorMode = typeof COLOR_MODES[number];
15
+ /**
16
+ * Theme configuration type
17
+ */
18
+ interface ThemeConfig {
19
+ name: ThemeName;
20
+ mode: ColorMode;
21
+ }
22
+
23
+ export { type ColorMode as C, type ThemeName as T, THEME_NAMES as a, COLOR_MODES as b, type ThemeConfig as c };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Design Tokens Exports
3
+ */
4
+
5
+ /**
6
+ * Theme names
7
+ */
8
+ declare const THEME_NAMES: readonly ["studio", "sage", "volt"];
9
+ type ThemeName = typeof THEME_NAMES[number];
10
+ /**
11
+ * Color modes
12
+ */
13
+ declare const COLOR_MODES: readonly ["light", "dark"];
14
+ type ColorMode = typeof COLOR_MODES[number];
15
+ /**
16
+ * Theme configuration type
17
+ */
18
+ interface ThemeConfig {
19
+ name: ThemeName;
20
+ mode: ColorMode;
21
+ }
22
+
23
+ export { type ColorMode as C, type ThemeName as T, THEME_NAMES as a, COLOR_MODES as b, type ThemeConfig as c };