complete.systems logo

Designing dual light and dark themes without losing your brand

How we keep the complete.systems look and feel consistent while offering a reader-friendly light and dark experience.

Giving people a choice between light and dark reading modes is table stakes, but it can also dilute the brand if done poorly. We recently refreshed the blog theme toggles to mirror the feel of the main site while keeping the reading experience comfortable.

Map out the shared design tokens

We started by auditing our existing palette and identifying which values must stay consistent across themes:

  • Primary accents (our red) and interaction blues
  • Spacing, border radii, and button proportions
  • Layout primitives such as card padding and section shells

Keeping these stable let us change background and text values without rewriting every component.

Use system preferences as a sensible default

Not everyone wants to click a toggle. We detect prefers-color-scheme on first load, then persist the reader’s choice so the site always loads the same way on return visits.

const stored = localStorage.getItem('cs-theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = stored || (prefersDark ? 'dark' : 'light');

Make the toggle obvious but unobtrusive

The toggle lives in the header next to other global actions, using the same pill shape and focus treatments as our buttons. Icons swap based on the current theme to keep the control predictable at a glance.

Light and dark theme mockups side by side

Test the reading experience on long articles

We previewed long-form posts in both modes to ensure body text, links, and inline code blocks meet contrast guidelines. The small adjustments—like slightly muted borders on dark backgrounds—prevent visual noise during long reading sessions.

With these tweaks, the blog now mirrors the polish of complete.systems while giving readers a comfortable experience in both light and dark modes.