Dark website color palettes: roles, contrast and a worked example
A dark palette needs its own role decisions. Keep the page dark, lift the supporting surface, and check the words on every colored fill.
Reviewed 26 September 2026 · 3 min read
Start with two dark surfaces
Our After hours palette starts with a blue-black page, #161922, and a lighter panel, #252B3B. These colors provide visual grouping without making every panel a bright rectangle.
The surface-to-page contrast is 1.24:1. That is a decorative separation, not a guarantee of a visible form boundary. If a border or shape is required to identify a control, test that edge against its adjacent background and give it stronger definition where necessary. W3C’s non-text contrast criterion explains when 3:1 is required.
Give text its own light color
The palette’s body text, #F0F1F7, reaches 15.57:1 on the page and 12.53:1 on the panel. Both exceed 7:1. This makes the two basic reading surfaces easy to check, while still leaving room to choose a softer appearance than pure white.
Do not assume that reducing text opacity preserves the same result. Transparency produces a different rendered color against each backdrop. Our studio accepts solid colors only, so calculate the composited color separately or choose an explicit solid hex value before testing.
Use a brighter action color on the dark page
The action color in After hours is #9BAAFE. It has 8.00:1 contrast against the page background and can carry underlined text links there. The exact same hue family does not need to use the same lightness in a light and dark theme.
A filled action changes the pairing. On the periwinkle button, the light body text has only 1.95:1 contrast. Black gives 9.57:1. Keep a separate --color-on-primary token so the button label does not accidentally inherit the page’s light text.
Check the accent label separately
The warm accent, #EBBD75, is useful for a small badge or highlighted region. The body text on that fill has only 1.54:1 contrast. A black label reaches 12.07:1. That pairing is exported as the separate --color-on-accent value.
This is a common dark-theme failure: a bright fill looks clear against the page, but the text placed inside it disappears. Always check both relationships—the fill against its surroundings when needed, and the label against the fill.
Keep the meaning independent of hue
Dark interfaces still need underlined or otherwise identifiable links, clear focus states, and explicit status messages. A pink error and a blue success may look different to one person without being sufficient cues for another. Add words and, where appropriate, distinct symbols or patterns. Color alone should not communicate required information.
A practical dark-theme review
- List each page and panel background actually used.
- Test headings, paragraphs, muted text, and links against each one.
- Test labels on every button and badge fill.
- Check form boundaries and focus states in their real surroundings.
- Inspect screenshots and actual devices for reading comfort without treating that inspection as a substitute for contrast checks.
If you support both themes, store role tokens for each. Avoid an automatic color inversion as your final design method: it changes every relationship without considering what those colors are doing.
Explore After hours
See this exact dark palette, its derived labels, and all calculated pairs.
Open the dark palette ↗Our examples use original palette values and the WCAG 2.2 calculation. Full methodology and primary sources.
← All field notes