'use client'; import { useSyncExternalStore } from 'react'; import { Moon, Sun } from 'lucide-react'; type Theme = 'light' | 'dark'; const listeners = new Set<() => void>(); function subscribe(cb: () => void) { listeners.add(cb); const mq = window.matchMedia('(prefers-color-scheme: dark)'); mq.addEventListener('change', cb); return () => { listeners.delete(cb); mq.removeEventListener('change', cb); }; } function getSnapshot(): Theme { const attr = document.documentElement.getAttribute('data-theme'); if (attr === 'dark' || attr === 'light') return attr; return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } function getServerSnapshot(): Theme { return 'light'; } function applyTheme(t: Theme) { document.documentElement.setAttribute('data-theme', t); try { localStorage.setItem('ri-theme', t); } catch { /* ignore */ } for (const l of listeners) l(); } export function ThemeToggle({ className }: { className?: string }) { const theme = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); return ( ); } /** Inline script: apply the stored theme before paint to avoid flashes. */ export const THEME_SCRIPT = `(function(){try{var t=localStorage.getItem('ri-theme');if(t==='dark'||t==='light'){document.documentElement.setAttribute('data-theme',t);}}catch(e){}})();`;