feat: auto OS-driven dark mode (prefers-color-scheme)

Refactor public/style.css to semantic CSS custom properties under :root
(light palette by default) and add a @media (prefers-color-scheme: dark)
override block that flips background/foreground/accent/danger tokens to
a soft near-black palette. The original --black/--white/--gray-*/--red
literal tokens and the lone #fff5f5 floating literal are gone — every
color now derives from a semantic token, so the dark override is the
only place that re-declares them.

Add <meta name="color-scheme" content="light dark"> to the shared
layout <head> so the browser renders its UA backdrop, native scrollbars,
and form-control popups in the user's preferred scheme before the
stylesheet parses — this is what avoids a white flash on initial paint
in dark mode.

No toggle, no JS, no preference persistence — the page follows the OS
setting directly via the media query. The 16px font-size rule on
text-entry inputs is preserved (still asserted by tests/integration
/style.test.ts).
This commit is contained in:
2026-05-11 09:50:44 -07:00
parent 398c008c32
commit 012c544bdc
4 changed files with 122 additions and 67 deletions

View File

@@ -22,6 +22,7 @@ export function layout(title: string, body: string, opts: { authed?: boolean; hi
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>${escHtml(title)} — Nanodrop</title>
<link rel="stylesheet" href="/public/style.css">
</head>