/** * ThemeToggle — dark/light mode switch. * * Persists preference in localStorage and sets data-theme on . * Defaults to dark theme (matching existing design). * Uses useSyncExternalStore to satisfy React strict mode lint rules. */ 'use client'; import { useSyncExternalStore, useCallback } from 'react'; type Theme = 'dark' | 'light'; /** Module-level theme state — shared across all instances. */ let currentTheme: Theme = 'dark'; const listeners = new Set<() => void>(); function subscribe(callback: () => void): () => void { listeners.add(callback); return () => listeners.delete(callback); } function getSnapshot(): Theme { return currentTheme; } function getServerSnapshot(): Theme { return 'dark'; // SSR default } function applyTheme(theme: Theme) { currentTheme = theme; if (typeof document !== 'undefined') { document.documentElement.setAttribute('data-theme', theme); localStorage.setItem('theme', theme); } listeners.forEach((cb) => cb()); } // Initialize from localStorage on module load (client-side only) if (typeof window !== 'undefined') { const stored = localStorage.getItem('theme') as Theme | null; currentTheme = stored === 'light' ? 'light' : 'dark'; document.documentElement.setAttribute('data-theme', currentTheme); } export function ThemeToggle() { const theme = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); const toggle = useCallback(() => { applyTheme(theme === 'dark' ? 'light' : 'dark'); }, [theme]); return ( ); }