/** * Theme hook — persists user choice in localStorage, respects prefers-color-scheme * on first visit, and reflects the current theme as data-theme on . * The initial paint happens in index.html to avoid a flash. */ import { useCallback, useEffect, useState } from "react"; export type Theme = "light" | "dark"; const STORAGE_KEY = "theme"; function getInitial(): Theme { if (typeof window === "undefined") return "light"; const stored = window.localStorage.getItem(STORAGE_KEY) as Theme | null; if (stored === "light" || stored === "dark") return stored; const dark = window.matchMedia("(prefers-color-scheme: dark)").matches; return dark ? "dark" : "light"; } export function useTheme() { const [theme, setThemeState] = useState(getInitial); useEffect(() => { document.documentElement.setAttribute("data-theme", theme); window.localStorage.setItem(STORAGE_KEY, theme); }, [theme]); const setTheme = useCallback((t: Theme) => setThemeState(t), []); const toggle = useCallback( () => setThemeState((t) => (t === "dark" ? "light" : "dark")), [] ); return { theme, setTheme, toggle }; }