"use client"; // Zentrales Theming (Hell/Dunkel) — SHL-01 Akzeptanzkriterium 6. // Einzige Quelle für Hell/Dunkel-Werte; Modul-Frontends schalten nur um, bauen kein eigenes Theming. import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react"; import type { ReactNode } from "react"; import { colorTokens, cssVariables, type ColorScheme } from "../tokens/tokens"; const STORAGE_KEY = "nexarch-shl-theme"; interface ThemeContextValue { scheme: ColorScheme; setScheme: (scheme: ColorScheme) => void; toggle: () => void; } const ThemeContext = createContext(null); function readStoredScheme(): ColorScheme | null { if (typeof window === "undefined") return null; try { const stored = window.localStorage.getItem(STORAGE_KEY); return stored === "light" || stored === "dark" ? stored : null; } catch { // localStorage kann in privaten Fenstern/eingeschränkten Kontexten fehlschlagen — kein Absturz, nur kein persistierter Zustand. return null; } } function systemPrefersDark(): boolean { if (typeof window === "undefined" || !window.matchMedia) return false; return window.matchMedia("(prefers-color-scheme: dark)").matches; } export function ThemeProvider({ children }: { children: ReactNode }) { const [scheme, setSchemeState] = useState("light"); useEffect(() => { const stored = readStoredScheme(); setSchemeState(stored ?? (systemPrefersDark() ? "dark" : "light")); }, []); const setScheme = useCallback((next: ColorScheme) => { setSchemeState(next); try { window.localStorage.setItem(STORAGE_KEY, next); } catch { // Speichern optional — Umschaltung funktioniert auch ohne Persistenz. } }, []); const toggle = useCallback(() => { setScheme(scheme === "light" ? "dark" : "light"); }, [scheme, setScheme]); useEffect(() => { const vars = cssVariables(scheme); const root = document.documentElement; for (const [key, value] of Object.entries(vars)) { root.style.setProperty(key, value); } root.dataset.shlTheme = scheme; }, [scheme]); const value = useMemo(() => ({ scheme, setScheme, toggle }), [scheme, setScheme, toggle]); return {children}; } export function useTheme(): ThemeContextValue { const ctx = useContext(ThemeContext); if (!ctx) { throw new Error("useTheme muss innerhalb von aufgerufen werden"); } return ctx; } export function currentColors(scheme: ColorScheme) { return colorTokens[scheme]; }