1'use client';23import { useEffect, useState } from 'react';4import { Moon, Sun } from 'lucide-react';56type Theme = 'light' | 'dark';78function applyTheme(t: Theme) {9 document.documentElement.setAttribute('data-theme', t);10 try {11 localStorage.setItem('ri-theme', t);12 } catch {13 /* ignore */14 }15}1617export function ThemeToggle({ className }: { className?: string }) {18 const [theme, setTheme] = useState<Theme>('light');19 useEffect(() => {20 const attr = document.documentElement.getAttribute('data-theme') as Theme | null;21 if (attr) setTheme(attr);22 else setTheme(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');23 }, []);24 return (25 <button26 type="button"27 aria-label={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}28 className={className ?? 'inline-flex h-8 w-8 items-center justify-center rounded-md text-muted hover:bg-inset hover:text-fg'}29 onClick={() => {30 const next: Theme = theme === 'dark' ? 'light' : 'dark';31 setTheme(next);32 applyTheme(next);33 }}34 >35 {theme === 'dark' ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}36 </button>37 );38}3940/** Inline script: apply the stored theme before paint to avoid flashes. */41export const THEME_SCRIPT = `(function(){try{var t=localStorage.getItem('ri-theme');if(t==='dark'||t==='light'){document.documentElement.setAttribute('data-theme',t);}}catch(e){}})();`;42