export const UI_THEME_STORAGE_KEY = "dashboard-ui-theme"; export type UiTheme = "dark" | "light"; type ReadableThemeStorage = | { getItem(key: string): string | null } | { get(key: string): string | undefined }; type WritableThemeStorage = | { setItem(key: string, value: string): void } | { set(key: string, value: string): unknown }; export function isUiTheme(value: unknown): value is UiTheme { return value === "dark" || value === "light"; } export function getNextUiTheme(theme: UiTheme): UiTheme { return theme === "dark" ? "light" : "dark"; } export function resolveInitialUiTheme( storage?: ReadableThemeStorage | null, fallback: UiTheme = "dark", ): UiTheme { const stored = safeReadStoredTheme(storage); return isUiTheme(stored) ? stored : fallback; } export function persistUiTheme( theme: UiTheme, storage?: WritableThemeStorage | null, ): void { if (!storage) return; try { if ("setItem" in storage) { storage.setItem(UI_THEME_STORAGE_KEY, theme); return; } storage.set(UI_THEME_STORAGE_KEY, theme); } catch { // Browser storage may be blocked or quota-constrained. } } function safeReadStoredTheme( storage?: ReadableThemeStorage | null, ): string | undefined { try { return readStoredTheme(storage); } catch { return undefined; } } function readStoredTheme( storage?: ReadableThemeStorage | null, ): string | undefined { if (!storage) return undefined; if ("getItem" in storage) { return storage.getItem(UI_THEME_STORAGE_KEY) ?? undefined; } return storage.get(UI_THEME_STORAGE_KEY); }