Guide
Shipping dark mode right
Semantic tokens, contrast checks, and the three mistakes that make dark mode feel like an afterthought.
Dark mode isn't a color inversion. It's a second design pass. Three mistakes we see constantly.
Mistake 1: Inverting hex values
#ffffff → #000000 breaks contrast and kills brand color. Use semantic tokens per mode.
Mistake 2: Forgetting images and shadows
Photos, gradients, and box shadows need dark-mode variants. A hero glow that works in light often looks muddy in dark.
Mistake 3: Shipping dark mode last
If you bolt it on after launch, you'll refactor every component. Build both modes from day one.
Our checklist
Semantic --background, --foreground, --border per mode
Brand color rebalanced for dark (usually lighter/more saturated)
Test contrast at WCAG AA minimum
Respect prefers-color-scheme and manual toggle
Related
- 01
AtroUI indie site kit: portfolio chrome you can own
We extracted the narrow personal homepage patterns from a real portfolio into AtroUI: ~640px chrome, command menu, ship log, personal hero, reading shelf, and more. A second altitude next to studio Blocks.
Essay · 8 min read - 02
Introducing AtroUI
We extracted the UI we actually ship on client sprints into a free React / shadcn registry. Own the source, edit CONTENT, keep the dark-first system.
Essay · 8 min read
Want this built for you?
Fixed-scope MVP sprints and AI integrations. Same stack as this guide.
