Never pure black
Pure #000 in dark mode causes halation — text and surfaces bloom against it. Use a near-black with a slight hue: #141414 with a warm or cool tint, depending on the brand. The tint keeps surfaces from looking dead.
The same rule applies to pure white text. #f5f5f6 or similar off-white reads softer and does not bloom on OLED screens.
Stack surfaces with borders, not just color
In light mode, surfaces separate by lightness — white card on gray page. In dark mode, lightness barely moves, so you need borders. Every surface step gets a border alpha bump: 0.09, 0.14, 0.22 across three levels.
The pattern: page background, surface-1 for cards, surface-2 for raised headers, and alpha-based borders between them. Semantics over absolute values — the same token works when the brand hue shifts.
Text hierarchy inverts
In light mode, secondary text is darker gray than the background. In dark mode it is lighter gray — and the levels must stay ordered. A common bug: tertiary text ends up lighter than secondary, breaking the reading order.
Check your token file: text, text-2, text-3, text-4 must monotonically lose contrast in both themes.
The glow trap
Accent glows and shadows tuned for dark mode look muddy in light mode. If a glow exists, give it a per-theme value — a 0.25 alpha in light, 0.5 in dark. Shadows shift too: dark mode wants deeper, tighter shadows; light mode wants softer and wider.