import { createContext, useContext, useEffect, useState } from 'react'; /** * Themes: 'light' | 'dark' * Persisted to localStorage under key 'bt-theme'. * * Class mapping on document.documentElement: * light → (no classes) * dark → 'dark' */ const STORAGE_KEY = 'bt-theme'; const VALID_THEMES = ['light', 'dark']; const DEFAULT_THEME = 'light'; function applyTheme(theme) { const root = document.documentElement; root.classList.remove('dark'); if (theme === 'dark') { root.classList.add('dark'); } // 'light' → no classes } function loadStoredTheme() { try { const stored = localStorage.getItem(STORAGE_KEY); if (stored === 'dark-purple') return 'dark'; if (stored && VALID_THEMES.includes(stored)) return stored; } catch { // localStorage unavailable } return DEFAULT_THEME; } const ThemeContext = createContext(null); export function ThemeProvider({ children }) { const [theme, setThemeState] = useState(() => { const stored = loadStoredTheme(); // Apply immediately (before first paint) to avoid flash applyTheme(stored); return stored; }); const setTheme = (newTheme) => { if (!VALID_THEMES.includes(newTheme)) return; applyTheme(newTheme); setThemeState(newTheme); try { localStorage.setItem(STORAGE_KEY, newTheme); } catch { // localStorage unavailable } }; // Keep DOM in sync if theme state ever changes externally useEffect(() => { applyTheme(theme); }, [theme]); return ( {children} ); } export function useTheme() { const ctx = useContext(ThemeContext); if (!ctx) { throw new Error('useTheme must be used within a ThemeProvider'); } return ctx; }