export type ThemeMode = 'light' | 'dark' | 'system'; const STORAGE_KEY = 'llm-multiverse-theme'; function createThemeStore() { let mode: ThemeMode = $state('system'); let resolvedDark = $state(false); let initialized = false; let mediaQuery: MediaQueryList | null = null; let mediaListener: ((e: MediaQueryListEvent) => void) | null = null; function applyTheme(isDark: boolean) { if (typeof document === 'undefined') return; const root = document.documentElement; // Add transition class for smooth switching root.classList.add('theme-transition'); if (isDark) { root.classList.add('dark'); } else { root.classList.remove('dark'); } // Remove transition class after animation completes setTimeout(() => { root.classList.remove('theme-transition'); }, 300); } function getSystemPreference(): boolean { if (typeof window === 'undefined') return false; return window.matchMedia('(prefers-color-scheme: dark)').matches; } function init(): (() => void) | undefined { if (typeof window === 'undefined') return; if (initialized) return; initialized = true; // Load saved preference const saved = localStorage.getItem(STORAGE_KEY) as ThemeMode | null; if (saved === 'light' || saved === 'dark' || saved === 'system') { mode = saved; } else { mode = 'system'; } // Listen for system preference changes mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); mediaListener = (e: MediaQueryListEvent) => { if (mode === 'system') { resolvedDark = e.matches; applyTheme(resolvedDark); } }; mediaQuery.addEventListener('change', mediaListener); // Apply initial theme resolvedDark = mode === 'dark' ? true : mode === 'light' ? false : getSystemPreference(); applyTheme(resolvedDark); return () => { if (mediaQuery && mediaListener) { mediaQuery.removeEventListener('change', mediaListener); } initialized = false; }; } function setMode(newMode: ThemeMode) { mode = newMode; if (typeof window !== 'undefined') { localStorage.setItem(STORAGE_KEY, newMode); } resolvedDark = newMode === 'dark' ? true : newMode === 'light' ? false : getSystemPreference(); applyTheme(resolvedDark); } function cycle() { const order: ThemeMode[] = ['system', 'light', 'dark']; const idx = order.indexOf(mode); const next = order[(idx + 1) % order.length]; setMode(next); } return { get mode() { return mode; }, get isDark() { return resolvedDark; }, init, setMode, cycle }; } export const themeStore = createThemeStore();