// SPDX-FileCopyrightText: 2025-2026 Kat Suricata // SPDX-License-Identifier: (CC-BY-4.0+ OR Apache-2.0+) /** * Mode selection for the site. `src/app.html` holds the same two literals in a * small script that runs before the first paint. Change both places together. */ /** The root element attribute that selects a mode. */ export const SCHEME_ATTRIBUTE = 'data-scheme'; /** The localStorage key that holds a saved mode. */ export const SCHEME_STORAGE_KEY = 'digitalrust-scheme'; export type Scheme = 'dark' | 'safe-mode'; export const schemes: readonly Scheme[] = ['dark', 'safe-mode']; export function isScheme(value: unknown): value is Scheme { return value === 'dark' || value === 'safe-mode'; } /** The saved mode, or null when the reader saved none. */ export function savedScheme(): Scheme | null { try { const value = localStorage.getItem(SCHEME_STORAGE_KEY); return isScheme(value) ? value : null; } catch { /* A blocked storage call means no saved mode. */ return null; } } /** The platform preference. The dark theme is the default when the platform gives no preference. */ export function platformScheme(): Scheme { return window.matchMedia('(prefers-color-scheme: light)').matches ? 'safe-mode' : 'dark'; } /** The mode on screen now: a saved preference first, then the platform preference. */ export function activeScheme(): Scheme { return savedScheme() ?? platformScheme(); } /** Saves a mode and applies it to the root element. */ export function applyScheme(scheme: Scheme): void { try { localStorage.setItem(SCHEME_STORAGE_KEY, scheme); } catch { /* A blocked storage call keeps the mode for this page only. */ } document.documentElement.setAttribute(SCHEME_ATTRIBUTE, scheme); }