/** * Zero-dependency theme mode/accent runtime, published as the `@aceshooting/lyra-ui/theme.js` * subpath. Nothing here imports Lit, any component, or any other module in this package: the * whole point of the subpath is that an application can persist and apply a theme without * pulling the component graph into its first-paint bundle. Keep it dependency-free. * * This module is side-effect-free -- importing it never touches the document or storage -- and * therefore carries no `package.json#sideEffects` entry, so bundlers may drop it when unused. */ export interface LyraThemeBootstrapOptions{ /** The localStorage key holding a `{ mode, accent, surface }` theme record. */ storageKey?:string;} /** * Theme selection mode. `'light'` and `'dark'` are explicit overrides. `'auto'` resolves and * continues following `prefers-color-scheme`; `'unset'` removes Lyra's mode attributes so an * application-owned cascade can decide instead. */ export type LyraThemeMode='light'|'dark'|'auto'|'unset'; /** * A semantic role the runtime can derive a contrast-checked quiet/normal/loud/on-* ramp for. * Mirrors the five roles `--lr-color--*` already exposes in the static palette * (`src/internal/tokens/palette.styles.ts`): only `'brand'` also drives `--lr-theme-color-focus`. */ export type LyraThemeSemanticRole='brand'|'success'|'warning'|'danger'|'neutral'; /** * One semantic role's accent input: an absolute CSS color, `null` to clear that role back to the * palette default, or `{ light?, dark? }` to derive the role's ramp from a *different* base color * per resolved mode (each branch independently absolute-CSS-color-or-`null`, defaulting to `null` * when omitted). A bare string/`null` applies to both modes uniformly, matching every pre-16.0.0 * per-role value unchanged. */ export type LyraThemeAccentValue=string|null|{readonly light?:string|null;readonly dark?:string|null;}; /** * Absolute CSS color input for the accent ramp(s). A bare string is shorthand for * `{ brand: }`, matching every pre-16.0.0 caller unchanged. An object supplies a * `LyraThemeAccentValue` per semantic role -- only the roles present are (re)derived; omitted * roles keep whatever the shipped/inherited palette already provides. `null` (at either level) * clears that role back to the palette default. */ export type LyraThemeAccent=string|null|{readonly[role in LyraThemeSemanticRole]?:LyraThemeAccentValue;}; /** Persisted theme selection, optional per-role accent, and optional surface reference. */ export interface LyraTheme{ /** Requested selection mode; `auto` remains distinct from its resolved light/dark value. */ mode:LyraThemeMode; /** * Absolute CSS brand color, a per-role `LyraThemeAccentValue` map (each role optionally * per-mode via `{ light?, dark? }`), or `null` to use the active stylesheet palette. */ accent:LyraThemeAccent; /** * Absolute CSS color used as the ramp mix base instead of the shipped light/dark surface * defaults (`#1a1a1a` dark / `#ffffff` light). `null` keeps those defaults. An alpha channel in * the supplied color is composited against the default surface for that mode before use. */ surface:string|null;} /** Snapshot carried by the global `lr-theme-change` event. */ export type LyraThemeChangeDetail=Readonly;declare global{interface WindowEventMap{'lr-theme-change':CustomEvent;}} /** * Sets the persisted theme mode/accent/surface, applies it to `document.documentElement` (via * `data-lr-theme`/`data-theme` and a complete `--lr-theme-color--*` ramp per role `accent` * supplies), and dispatches `lr-theme-change` on `window` with `detail: { mode, accent, surface }`. * Unspecified fields keep their current value. Never throws -- a `localStorage` failure (private * browsing, quota, sandboxed iframe) degrades to apply-without-persist, and unspecified fields * still keep their value across calls in that state, because the merge falls back to the last * applied theme rather than to the default. * * `accent` is either an absolute CSS color (shorthand for `{ brand: }`), a per-role * `{ brand?, success?, warning?, danger?, neutral? }` map, or `null`. Each role's value is in turn * either a bare CSS color/`null` (applied to both resolved modes) or a `{ light?, dark? }` map * deriving that role's ramp from a *different* base color per resolved mode -- e.g. * `{ brand: { light: '#2563eb', dark: '#60a5fa' } }`. `surface` is an absolute CSS color used as * every ramp's mix base instead of the shipped light/dark defaults, or `null` to keep those * defaults. Malformed, CSS-wide, relative, and unresolved `var()` values fail closed to `null` at * the field (or, for a per-role/per-mode value, the individual role/branch) they appear in. Each * generated fill receives a black or white foreground with at least 4.5:1 contrast; normal/loud * borders and the brand focus color have at least 3:1 contrast against the resolved surface. */ export declare function setLyraTheme(theme:Partial):void; /** * Reads the current theme mode/accent/surface, defaulting to * `{ mode: 'auto', accent: null, surface: null }` when nothing has been set or the stored value is * malformed. Storage is re-read on every call -- there is no in-memory cache -- so a value written * by another tab or a previous session is picked up cold. * * When `localStorage` is unreadable or unwritable this reports the theme this module last * applied, not the default: the returned value always describes what the document is actually * showing, so a toggle UI bound to it stays in sync even where nothing can be persisted. */ export declare function getLyraTheme():LyraTheme; /** * Creates a self-contained IIFE body, safe to inline into a `