import { create } from 'zustand' type Theme = 'light' | 'dark' | 'system' interface ThemeState { theme: Theme resolvedTheme: 'light' | 'dark' setTheme: (theme: Theme) => void } const THEME_KEY = 'mediacrawler_theme' function getSystemTheme(): 'light' | 'dark' { if (typeof window === 'undefined') return 'light' return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' } function getStoredTheme(): Theme { if (typeof window === 'undefined') return 'light' const stored = localStorage.getItem(THEME_KEY) as Theme | null if (stored && ['light', 'dark', 'system'].includes(stored)) { return stored } return 'light' // Default to light } function applyTheme(resolved: 'light' | 'dark') { const root = document.documentElement if (resolved === 'dark') { root.classList.add('dark') } else { root.classList.remove('dark') } } function resolveTheme(theme: Theme): 'light' | 'dark' { return theme === 'system' ? getSystemTheme() : theme } // Initialize theme immediately to prevent flash const initialTheme = getStoredTheme() const initialResolved = resolveTheme(initialTheme) if (typeof window !== 'undefined') { applyTheme(initialResolved) } export const useThemeStore = create((set) => ({ theme: initialTheme, resolvedTheme: initialResolved, setTheme: (theme) => { const resolved = resolveTheme(theme) localStorage.setItem(THEME_KEY, theme) applyTheme(resolved) set({ theme, resolvedTheme: resolved }) }, })) // Listen for system theme changes if (typeof window !== 'undefined') { window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { const state = useThemeStore.getState() if (state.theme === 'system') { const resolved = e.matches ? 'dark' : 'light' applyTheme(resolved) useThemeStore.setState({ resolvedTheme: resolved }) } }) }