import type { Theme } from "../api.js"; import { FONT_SCALE_MAX, FONT_SCALE_MIN } from "../api.js"; // Theme + font-scale application. The whole UI reads colour through the --color-term-* // tokens; the light palette lives in index.css under `html.theme-light`. Applying a theme // is just toggling that class on . Both are the LOGGED-IN USER's stored preferences // (users.theme / users.font_scale), applied after auth resolves — mirroring how language // works. Defaults (dark, 100%) apply before auth resolves. Printed tickets are unaffected. /** Apply a theme by toggling `theme-light` on . Dark is the absence of the * class (the base tokens). No-op-safe to call repeatedly. */ export function applyTheme(theme: Theme): void { document.documentElement.classList.toggle("theme-light", theme === "light"); } /** Apply a font scale by setting the ROOT font-size (percent). The app's text is sized in * rem (the `text-[…rem]` utilities + the .label/.input/.hint/.btn component classes all * derive from the root), so only TEXT scales — viewport-locked layout (h-screen frame, * max-h-[90vh] modals, vh units) is unaffected, so headers/footers never clip; taller * content just scrolls its own container. NOT `zoom` (which scaled those vh boxes too and * pushed modal chrome out of view). Clamped to the band; no-op-safe to call repeatedly. */ export function applyFontScale(pct: number): void { const clamped = Math.min(FONT_SCALE_MAX, Math.max(FONT_SCALE_MIN, Math.round(pct))); // 100% = the browser's 16px root. The app's rem units scale off this. document.documentElement.style.fontSize = clamped === 100 ? "" : `${clamped}%`; }