Dark mode takes three layers. <meta name="color-scheme" content="light dark">, applied before CSS loads, or color-scheme: light dark lets the browser follow the operating system for the page background, form controls, scrollbars and system colors. light-dark(light, dark) (Color Values, Baseline since May 2024) gives your own colors both values, chosen by the element's used scheme. @media (prefers-color-scheme: dark) handles the rest, such as dimming photos.
<style>
:root { color-scheme: light dark; --bg: light-dark(#fff, #151b26);
--text: light-dark(#1b1b1b, #e3e7ee); --accent: light-dark(#1565c0, #90caf9); }
body { font: 15px system-ui; display: flex; gap: 12px; }
section { flex: 1; padding: 0 14px 14px; background: var(--bg); color: var(--text);
border: 1px solid #90a4ae; border-radius: 8px; }
h3 { color: var(--accent); }
</style>
<section style="color-scheme: light"><h3>color-scheme: light</h3>
<input value="Text field"> <input type="checkbox" checked> <button>Button</button></section>
<section style="color-scheme: dark"><h3>color-scheme: dark</h3>
<input value="Text field"> <input type="checkbox" checked> <button>Button</button></section>
Custom properties keep light-dark() unresolved until used, so each section resolves it against its own scheme. A theme switch therefore needs only :root[data-theme="dark"] { color-scheme: dark } and its light twin, plus a script that stores the choice (Colors and Dark Mode). Avoid pure black and saturated accents, and check contrast in both schemes.