Dark mode is not a toggle
You have seen the half-built version: text that sits a shade too dim to read comfortably, a shadow that vanishes into the dark it was drawn on, one stubborn white card glowing in a room that has gone quiet. Each is a small tell that the dark theme was an inversion applied late, not a design decided early.
Treating the two themes as equals is a different decision, made at the start. Neither is the "real" design with the other bolted on; both are first-class, and a component is not finished until it is right in both. That framing costs almost nothing when it is the starting assumption and a great deal when it is a retrofit — the same lesson accessibility teaches, in another key.
Tokens only, no raw values
The mechanism that makes two equal themes tractable is tokens. No colour is written as a raw hex value inside a component; every colour is a named token — surface, text, border, accent, the muted background behind a card — and a theme is nothing more than a second set of values for those same names. Switching themes swaps the values, not the components. The button does not know which theme it is in, and does not need to.
The discipline is absolute or it is nothing. One raw #ffffff hardcoded in a corner is the white card that will not turn off — the single value the theme switch cannot reach. So the rule is zero raw values in components: tokens for every colour, both themes defined for every token, and a lint that fails the moment a bare hex sneaks in. A single source of truth for colour is what lets two themes stay honest with each other.
Tested in both, across breakpoints
Two themes double the surface that can break, and neither can be verified by remembering to look. Contrast that passes in light can fail in dark and the reverse; a layout can be right on a wide screen and wrong on a phone in exactly one theme. So the check runs the full grid — light and dark, mobile and desktop — against the built page, and a component earns "done" only when every cell of that grid passes.
We hold this on our own work: Koryvant renders both themes as a matter of course, because a design system that only exists in light is only half a design system. It is the same standard we bring to software we build for others, and it sits right beside the accessibility bar in accessibility is a requirement — quality that stays verifiable in every theme a real person will actually use.