'use client'; import { useCallback, useEffect, useState } from 'react'; export type DarkMode = 'light' | 'dark' | 'system'; export type ResolvedMode = 'light' | 'dark'; const STORAGE_KEY = 'pxlkit:dark-mode'; const VALID_MODES: ReadonlyArray = ['light', 'dark', 'system']; function isDarkMode(value: unknown): value is DarkMode { return typeof value === 'string' && (VALID_MODES as ReadonlyArray).includes(value); } function readStoredMode(): DarkMode { if (typeof window === 'undefined') return 'system'; try { const raw = window.localStorage.getItem(STORAGE_KEY); if (raw == null) return 'system'; try { const parsed = JSON.parse(raw); if (isDarkMode(parsed)) return parsed; } catch { if (isDarkMode(raw)) return raw; } } catch { /* swallow — private mode / disabled storage */ } return 'system'; } function writeStoredMode(mode: DarkMode) { if (typeof window === 'undefined') return; try { window.localStorage.setItem(STORAGE_KEY, JSON.stringify(mode)); } catch { /* swallow */ } } function systemPrefersDark(): boolean { if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') { return false; } return window.matchMedia('(prefers-color-scheme: dark)').matches; } function resolveMode(mode: DarkMode): ResolvedMode { if (mode === 'system') return systemPrefersDark() ? 'dark' : 'light'; return mode; } function applyResolvedToDocument(resolved: ResolvedMode) { if (typeof document === 'undefined') return; const root = document.documentElement; if (resolved === 'dark') { root.classList.add('dark'); root.classList.remove('light'); } else { root.classList.remove('dark'); root.classList.add('light'); } } export function useDarkMode(): { mode: DarkMode; resolved: ResolvedMode; setMode: (m: DarkMode) => void; } { // Deterministic initial state on BOTH server and first client render to // avoid hydration mismatch. The stored preference is read in a post-mount // effect; SSR consumers wanting a no-flash experience should inject an // inline `