Dark mode design is often treated as a filter: swap white for black and ship. The result is usually harsh, with glowing text, muddy images and accent colours that vibrate against the background.
A good dark theme is a second palette, designed with the same care as the first.
Avoid pure black#
Pure black backgrounds with pure white text create maximum contrast, which sounds good and reads badly. Text can appear to smear on some screens, and there is no room to show depth. A very dark grey, often with a slight hue from the brand palette, gives surfaces room to layer.
Building dark surfaces#
- Choose a base that is dark but not black
- Make raised surfaces slightly lighter, not darker
- Use borders sparingly; lighter surfaces already separate
- Keep shadows subtle, since they barely read on dark grounds
Adjust the accent#
A saturated accent that works on white can feel neon on dark grey. Most accents need to be desaturated or lightened slightly for dark mode, while still meeting contrast requirements against the new background.
Check contrast again#
WCAG asks for a contrast ratio of at least 4.5 to 1 for normal text and 3 to 1 for large text. Those targets apply to both themes. Test the dark palette separately; passing in light mode says nothing about dark.
Build it with tokens#
Define colours by role, such as background, surface, text and accent, rather than by value. Each theme then assigns its own values to the same roles, and components never need to know which theme is active.
Dark mode is not the light theme with the lights off. It is a room of its own.
Respect the choice#
Follow the system setting by default and offer a manual switch. Remember the choice, and make sure images and illustrations still read on both backgrounds.


