Dark mode is easy to add and easy to get subtly wrong. The classic bug: the page loads white, then snaps to dark a moment later. That flash happens because the theme choice is applied too late.
Three moving parts
A dark mode that never blinks needs only three things working together.
1. A token system
Every color in the theme is a CSS variable. The light values are the default; a single [data-theme="dark"] selector overrides them. No individual component ever knows which mode it is in.
2. A pre-paint script
A tiny inline script runs before the browser paints anything. It reads the saved preference, falls back to the operating system setting, and applies the result immediately:
var saved = localStorage.getItem('gl-theme');
var mode = saved || (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', mode);3. A toggle
The visible control just flips the attribute and writes the choice to localStorage. Because the markup is static and only CSS decides which icon shows, there is no hydration mismatch to chase down.
The flash is not a styling bug. It is a timing bug.
Try it now — the round control sits in the top-right corner of every page on this site. The choice follows you from page to page, and survives a reload.