Blog

Dark mode without surprise

Dark mode fails when it is an afterthought: text tokens flip but photographs do not, or the toggle hides inside a menu nobody can close.

Class on html

The dark class on <html> drives every token. A blocking inline script runs before paint, reads localStorage.theme, and falls back to prefers-color-scheme.

Fixed colours on photos

Text sitting on an image uses a fixed colour — usually white over a scrim — because the photograph does not change between modes.

Test both schemes

Run through every section in light and dark. Muted text is where contrast usually breaks first. Adjust tokens, not individual components.