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

Merged
brendan merged 2 commits from feat/auto-dark-mode into main 2026-05-11 16:56:44 +00:00

2 Commits

Author SHA1 Message Date
38e7c0c4a1 refactor: restore var(--border) shorthand after dark-mode tokenization
The dark-mode refactor expanded `border: var(--border);` to
`1px solid var(--border-color);` in three rules (.share-box button,
th, button.copy-link). The rest of the file still uses the
var(--border) shorthand for the same value, so restore it for
consistency.

`--border` is defined as `1px solid var(--border-color)`, so the
substitution is byte-equivalent at the cascade level: same border
in light mode, same border in dark mode, identical to the prior
commit.

Behavior unchanged. 130/130 tests pass; tsc --noEmit clean.
2026-05-11 09:53:24 -07:00
012c544bdc 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).
2026-05-11 09:50:44 -07:00