Colour Palette¶
"One accent colour, used with purpose. Everything else is neutral."
Mode Architecture¶
The site defaults to light mode and offers a dark mode toggle. Colours are defined as CSS custom properties on :root (light) and [data-theme="dark"] (dark).
Theme is determined by:
1. localStorage.getItem('theme') (user's explicit choice)
2. prefers-color-scheme media query (OS preference)
3. Fallback: light
Neutral Scale¶
The backbone of the system. Every background, text colour, and border comes from this scale.
Light Mode (Default)¶
| Token | Value | Swatch | Usage |
|---|---|---|---|
--bg-page |
#FAFAFA |
Page background | |
--bg-surface |
#FFFFFF |
Cards, panels, modals | |
--bg-elevated |
#F5F5F5 |
Sidebar, secondary surfaces | |
--text-primary |
#1A1A1A |
Headings, important text | |
--text-secondary |
#404040 |
Body text | |
--text-tertiary |
#737373 |
Descriptions, meta text | |
--text-muted |
#A3A3A3 |
Timestamps, placeholders | |
--border |
#E5E5E5 |
Default borders | |
--border-emphasis |
#D4D4D4 |
Hover/active borders |
Dark Mode¶
| Token | Value | Swatch | Usage |
|---|---|---|---|
--bg-page |
#0A0A0A |
Page background | |
--bg-surface |
#141414 |
Cards, panels | |
--bg-elevated |
#1A1A1A |
Secondary surfaces | |
--text-primary |
#F5F5F5 |
Headings | |
--text-secondary |
#D4D4D4 |
Body text | |
--text-tertiary |
#A3A3A3 |
Descriptions | |
--text-muted |
#737373 |
Timestamps | |
--border |
#262626 |
Default borders | |
--border-emphasis |
#404040 |
Hover/active borders |
Accent Colours¶
Primary — Indigo¶
The one accent colour for the entire site. Used for CTAs, links, active states, focus rings.
| Token | Light | Dark | Usage |
|---|---|---|---|
--accent |
#6366F1 |
#818CF8 |
Links, CTAs, active tabs |
--accent-hover |
#4F46E5 |
#6366F1 |
Hover states |
--accent-subtle |
#EEF2FF |
rgba(99,102,241,0.1) |
Accent backgrounds (selected row, active sidebar item) |
Why indigo? Linear uses #5e6ad2, Stripe uses #635bff. Indigo #6366F1 sits between both — professional, calm, works beautifully in both light and dark modes. Not warm, not cold. Not attention-seeking, not invisible.
Semantic Colours¶
Used only for their specific meaning. Never as decoration.
| Token | Light | Dark | Meaning |
|---|---|---|---|
--success |
#22C55E |
#4ADE80 |
Pass, correct, saved, healthy |
--warning |
#EAB308 |
#FACC15 |
Attention needed, expiring, new |
--error |
#EF4444 |
#F87171 |
Failed, wrong, error, critical |
--info |
#60A5FA |
#93C5FD |
References, docs, informational |
--teal |
#14B8A6 |
#5EEAD4 |
Scenarios, instructions, processes |
Badge Text Colours (Added Z4d)¶
Text colours for use ON tinted semantic backgrounds. Dark in light mode (contrast on light tints), light in dark mode (contrast on dark tints). Defined in body.zen-migrated.
| Token | Light | Dark | Usage |
|---|---|---|---|
--badge-red |
#B91C1C |
#FCA5A5 |
Text on red-tinted badges |
--badge-orange |
#C2410C |
#FDBA74 |
Text on orange-tinted badges |
--badge-amber |
#92400E |
#FDE68A |
Text on yellow/amber-tinted badges |
--badge-green |
#166534 |
#86EFAC |
Text on green-tinted badges |
--badge-blue |
#1D4ED8 |
#93C5FD |
Text on blue-tinted badges |
--badge-purple |
#6D28D9 |
#C4B5FD |
Text on purple-tinted badges |
What's NOT in the palette¶
These colours no longer exist anywhere in the system:
- ❌
#66ffff(neon cyan) - ❌
#ff66ff(neon magenta) - ❌
#39ff14(neon green) - ❌
#ffe600(neon yellow) - ❌ Any of the 53 per-tool accent colours from
tool_colours.toml - ❌ Any gradient fills or glow colours
- ❌ Any
color-mix()derived colours - ❌ Any
rgba(255, 102, 255, ...)magenta variants
WCAG Contrast Compliance¶
All colour combinations must pass WCAG AA (4.5:1 for normal text, 3:1 for large text).
| Combination | Ratio | Status |
|---|---|---|
--text-primary on --bg-page (light) |
15.3:1 | ✅ AAA |
--text-secondary on --bg-page (light) |
8.6:1 | ✅ AAA |
--text-tertiary on --bg-page (light) |
4.8:1 | ✅ AA |
--accent on --bg-page (light) |
4.6:1 | ✅ AA |
--text-primary on --bg-page (dark) |
17.4:1 | ✅ AAA |
--text-secondary on --bg-page (dark) |
12.2:1 | ✅ AAA |
--accent (dark) on --bg-page (dark) |
6.8:1 | ✅ AA |
CSS Implementation¶
:root {
/* Backgrounds */
--bg-page: #FAFAFA;
--bg-surface: #FFFFFF;
--bg-elevated: #F5F5F5;
/* Text */
--text-primary: #1A1A1A;
--text-secondary: #404040;
--text-tertiary: #737373;
--text-muted: #A3A3A3;
/* Borders */
--border: #E5E5E5;
--border-emphasis: #D4D4D4;
/* Accent */
--accent: #6366F1;
--accent-hover: #4F46E5;
--accent-subtle: #EEF2FF;
/* Semantic */
--success: #22C55E;
--warning: #EAB308;
--error: #EF4444;
}
[data-theme="dark"] {
--bg-page: #0A0A0A;
--bg-surface: #141414;
--bg-elevated: #1A1A1A;
--text-primary: #F5F5F5;
--text-secondary: #D4D4D4;
--text-tertiary: #A3A3A3;
--text-muted: #737373;
--border: #262626;
--border-emphasis: #404040;
--accent: #818CF8;
--accent-hover: #6366F1;
--accent-subtle: rgba(99, 102, 241, 0.1);
--success: #4ADE80;
--warning: #FACC15;
--error: #F87171;
}