Dark mode, done properly
Inverting colors is not a dark theme. A proper one is designed, tested, and respectful of the reader's choice.
Not an inversion
The quickest dark mode inverts every color: white backgrounds become black, black text becomes white. The result is technically dark and usually unpleasant. Pure white text on pure black is harsh, saturated brand colors glow, shadows disappear, and images designed for light backgrounds look out of place.
A good dark theme is designed as its own palette.
Surfaces
Use dark grays rather than pure black for most surfaces. They reduce the contrast slightly to a comfortable level and leave room to express elevation. In light mode, raised surfaces are shown with shadows. In dark mode, shadows are hard to see, so raised surfaces are usually a little lighter than the background beneath them.
Text
Off-white text, slightly dimmed from pure white, is easier to read for long periods on a dark background. Secondary text should be dimmer still, but must keep sufficient contrast. Check every pair again; values that passed in light mode may not pass in dark.
Color
Saturated colors that look balanced on white can feel loud on dark gray. Most dark themes use slightly desaturated or lighter versions of brand colors. Status colors such as red and green need special care to remain distinct from one another and readable against the dark surface.
Images and illustrations
Photographs generally look fine in both themes. Illustrations and diagrams with white backgrounds become glaring rectangles. Options include providing dark variants, using transparent backgrounds, or slightly reducing the brightness of images in dark mode with a CSS filter.
Respect the system setting
The prefers-color-scheme media query reports the visitor's operating system preference. Default to it. If you offer a manual toggle, remember the choice and let it override the system setting, and provide a way back to following the system.
Avoid the flash
A site that renders light and then switches to dark after its JavaScript runs produces a jarring flash on every page load. Apply the theme before the first paint, either with CSS media queries alone or with a tiny inline script in the head that sets the theme class from the stored preference.
Declare it
The color-scheme property tells the browser which schemes the page supports, so form controls, scrollbars and the default background match the theme. Without it, a dark page may still show bright white input fields.
Test both
Every new screen should be reviewed in both themes before it ships. Dark mode bugs are easy to miss when the whole team works in light mode, and the visitors who chose dark mode notice immediately.