Theme pairing — ship two brands by mode
Most design systems give you dark mode. cia lets you ship a second brand at night — in two HTML lines. No JavaScript, no mixin, no cia API surface. The browser does the work via native <link media> behavior.
0 KB JS 0 cia code Native browser feature since 2002 Editorial moat
How it works
The media attribute on a <link> tag accepts any media query. The browser loads every linked stylesheet but only applies the ones whose media query matches. Pair two theme files with prefers-color-scheme media queries and you get two complete brand identities, system-flipped.
<!-- light mode: warm paper Sketchbook --> <link rel="stylesheet" href="/cia/themes/sketchbook.css" media="(prefers-color-scheme: light)"> <!-- dark mode: green-on-black Terminal --> <link rel="stylesheet" href="/cia/themes/terminal.css" media="(prefers-color-scheme: dark)">
No data-theme needed on <html>. Each shipped theme file emits :root, :root[data-theme=“sketchbook”] — the bare :root is what makes a single file apply on its own, and here the media attribute does the gating for you. Include both files and let the OS preference decide.
Use the per-theme files for this, not the 24-theme bundle. The bundle has the bare :root stripped precisely so its themes don’t collide, which means it needs the attribute and can only ever express one theme at a time.
Why this is distinctive
No mainstream design system lets you do this. Bootstrap = one theme + tinted dark mode. Tailwind = utility classes that respond to dark: prefix. Material/Spectrum/Carbon = symmetric color flips. They all assume your brand is the same in light and dark.
cia doesn’t. With <link media> pairing, you can ship:
- Newspaper by day, hacker terminal by night — Sketchbook + Terminal
- Editorial light, neon cyberpunk dark — Press + Glass
- Corporate brand light, personal portfolio dark — Boilerplate + Sketchbook
- ...any of the 8 theme families × 8 = 64 combinations, or 56 once you drop the self-pairs — and 24 files to draw from if you want to pin specific light/dark variants
What you should know
- The browser loads both files. Individual themes run 1.9–2.7 KB gzipped, so a pairing lands around 4–5 KB. No conditional download — just conditional application.
- OS preference drives the swap. If a user toggles their system theme, the page re-applies immediately. No reload, no JS.
- Component tokens differ wildly. Make sure your components use semantic tokens (
var(--action-primary-default), not hard-coded colors) so they survive both modes. - Image assets need to flip too. Use
<picture>withmediaattributes for art-directed images per mode. - Each cia theme already pairs its own light + dark via
light-dark(). Use pairing when you want a different brand per mode, not a different mode of the same brand.
Forcing a mode
If a user wants to override their OS preference (force light or force dark on your site regardless of system), cia provides CSS hooks. The mechanism for SETTING the class is the consumer’s responsibility (server cookie, localStorage JS, manual toggle — cia ships zero JS).
<!-- Server-rendered or set by your own JS --> <html class="cia-force-light">...</html>
The marketing line
“Most design systems give you dark mode. cia lets you ship a second brand at night — in two HTML lines.”