import { create } from 'zustand'; import { persist } from 'zustand/middleware'; export type ThemeMode = 'light' | 'dark'; export type AccentColor = 'indigo' | 'teal' | 'rose' | 'amber' | 'slate'; interface ThemeState { mode: ThemeMode; accent: AccentColor; setMode: (mode: ThemeMode) => void; setAccent: (accent: AccentColor) => void; toggleMode: () => void; } export const ACCENT_TOKENS: Record = { indigo: { base: '#6366f1', light: '#e0e7ff', label: 'Indigo' }, teal: { base: '#14b8a6', light: '#ccfbf1', label: 'Teal' }, rose: { base: '#f43f5e', light: '#ffe4e6', label: 'Rose' }, amber: { base: '#f59e0b', light: '#fef3c7', label: 'Amber' }, slate: { base: '#64748b', light: '#f1f5f9', label: 'Slate' }, }; function applyTheme(mode: ThemeMode, accent: AccentColor) { const root = document.documentElement; const { base, light } = ACCENT_TOKENS[accent]; // Toggle dark class on root.classList.toggle('dark', mode === 'dark'); // Accent tokens (same in both modes) root.style.setProperty('--color-accent', base); root.style.setProperty('--color-accent-light', light); // Surface tokens if (mode === 'dark') { root.style.setProperty('--color-bg', '#0f172a'); root.style.setProperty('--color-surface', '#1e293b'); root.style.setProperty('--color-surface-raised', '#263548'); root.style.setProperty('--color-border', '#334155'); root.style.setProperty('--color-text-primary', '#f1f5f9'); root.style.setProperty('--color-text-secondary', '#94a3b8'); root.style.setProperty('--color-text-muted', '#64748b'); } else { root.style.setProperty('--color-bg', '#f8fafc'); root.style.setProperty('--color-surface', '#ffffff'); root.style.setProperty('--color-surface-raised', '#f1f5f9'); root.style.setProperty('--color-border', '#e2e8f0'); root.style.setProperty('--color-text-primary', '#0f172a'); root.style.setProperty('--color-text-secondary', '#475569'); root.style.setProperty('--color-text-muted', '#94a3b8'); } } export const useThemeStore = create()( persist( (set, get) => ({ mode: 'light', accent: 'indigo', setMode: (mode) => { set({ mode }); applyTheme(mode, get().accent); }, setAccent: (accent) => { set({ accent }); applyTheme(get().mode, accent); }, toggleMode: () => { const next = get().mode === 'light' ? 'dark' : 'light'; set({ mode: next }); applyTheme(next, get().accent); }, }), { name: 'fp-theme' } ) ); /** Call once at app boot to hydrate CSS tokens from persisted state */ export function initTheme() { const { mode, accent } = useThemeStore.getState(); applyTheme(mode, accent); }