Dark mode colour palettes that hold up

Picking dark colours you like takes ten minutes. Making them survive a real interface — disabled states, borders on two surfaces, an accent that still passes contrast — is the part that goes wrong. This is that part, with numbers from real shipping palettes.

Updated July 27, 2026

Should dark mode be pure black?

Almost never, and it is worth seeing why in numbers rather than as a rule of thumb. Here are the dark backgrounds and card surfaces from five unrelated shipping palettes, in HSL:

BackgroundCardNeutral hue
Warm industrial30 8% 10%24 7% 14%Warm orange-brown
Neutral product0 0% 10%0 0% 15%True grey
Archival blue222 31% 11%222 34% 15%Deep blue
Quiet green128 40% 8%137 26% 11%Forest green
Earth dashboard36 10% 10%36 7% 14%Warm sand
Dark background and card surfaces from five design kits, read from their live token files. Values are HSL: hue, saturation, lightness.

Three patterns, all consistent, none of them accidental.

  • Nothing is at 0% lightness. The darkest is 8%. Pure black is the one value with no room beneath it — the moment you need a surface *below* the background, you have nowhere to go.
  • Cards are lighter than the background, by 3 to 5 points. In dark interfaces, raised means lighter. This inverts the light-mode instinct, where a card is often the lighter thing sitting on a tinted page.
  • Only one of the five is true grey. The rest carry a hue — 30, 222, 128, 36 — usually pulled toward the accent. A tinted dark neutral reads as designed; an untinted one reads as a default, because it is the default.

The one case for near-black

OLED screens genuinely draw less power at #000000, and a media or photography interface can want the frame to disappear. That is a deliberate trade against having an elevation range, and it works when the content supplies the contrast. It is not a general-purpose default, and it is not what most people mean when they reach for black.

Dark is not an inversion

The fastest way to a bad dark mode is to flip the lightness of every light-mode value. Four specific things break, in roughly this order:

  1. Shadows stop working. A shadow is darkness cast on a lighter surface. On a dark surface there is nothing left to darken, so every elevation cue you had silently disappears and the interface flattens.
  2. The accent fails contrast. A saturated mid-tone brand colour that reads cleanly on white is often too dark against a near-black background. Inverting the neutrals does not touch it, so it fails quietly rather than obviously.
  3. Borders vanish or shout. A light-mode border is a slightly darker line. Inverted, it becomes a slightly lighter line — which either disappears against the card or glows against the background, depending on which surface it lands on.
  4. Disabled and muted states collapse. In light mode these are lighter greys. Inverted, they become dark greys on a dark background, and "muted" turns into "invisible".
A dark palette is a second design, not a filter applied to the first.

Elevation without shadow

Since shadows are unavailable, dark interfaces express depth through surface lightness. That is what the background-to-card gap in the table above is doing: each step up in the stack is a step up in lightness.

You need at least three levels, and it is worth naming them rather than improvising: the page background, a raised surface (cards, panels), and an overlay surface (popovers, dropdowns, dialogs) that sits above both. Spacing them 3 to 5 lightness points apart keeps the boundaries readable without turning the screen into stripes. Below about 3 points the levels stop being distinguishable at normal brightness; much above 6 and the top surface starts looking like a light-mode panel someone dropped in.

Surface vs tonal surface

Some systems distinguish a neutral raised surface from a *tonal* one that mixes a little of the brand hue into the elevation. Both are legitimate. The tonal version makes the whole interface feel deliberately coloured rather than grey-with-an-accent; the neutral version keeps colour meaning for things that need it. Pick one and apply it everywhere — mixing them is what makes a dark theme look like two themes.

Accents have to move

Look again at the primaries from those same five kits: 12 71% 46%, 46 85% 60%, 225 63% 80%, 114 47% 50%, 23 92% 60%. Every one is a light or mid tone. None is a deep saturated version of the hue, because a deep saturated colour on a near-black surface is both hard to read and hard to look at.

The general rule is that a light-mode accent has to lighten and usually desaturate for dark mode. Lightening buys contrast; desaturating stops it vibrating against the dark neutral, which is the effect that makes some dark themes physically tiring. And the accent needs its own foreground decision: a colour bright enough to read on dark is often bright enough to need *dark* text on top of it, which is the reverse of the light-mode pairing.

Check both directions against a contrast target. Body text on the background is the obvious one; the two that get missed are muted text on a card, and the accent's foreground on the accent itself.

Five swatches is not a palette

This is where most palette galleries leave you. A row of five hexes tells you the mood and answers almost none of the questions a real screen asks: what colour is a border on a card, what does muted text look like on an overlay, what does a destructive button look like when it is disabled, what colour is the ring on a focused input.

Token specimen · real values

Ambient Sage

Live render

Ambient Sage's actual tokens — the same values its exports use.

Color tokensSemantic roles with HEX / HSL / CMYK

Color tokens

Ambient Sage

dark · HEX · HSL · CMYK

Core

#1A1C17

background

H 84 · C7, 0, 18, 89

#E3E4DC

foreground

H 68 · C0, 0, 4, 11

#242620

card

H 80 · C5, 0, 16, 85

#292B24

muted

H 77 · C5, 0, 16, 83

#35372E

border

H 73 · C4, 0, 16, 78

Brand

#FEE951

primary

H 53 · C0, 8, 68, 0

#1A1C17

primary-fg

H 84 · C7, 0, 18, 89

#2F3129

secondary

H 75 · C4, 0, 16, 81

#F7E464

accent

H 52 · C0, 8, 60, 3

#FEE951

ring

H 53 · C0, 8, 68, 0

Semantic

#CC3333

destructive

H 0 · C0, 75, 75, 20

#FFFFFF

destructive-fg

H 0 · C0, 0, 0, 0

#66BB6A

success

H 123 · C45, 0, 43, 27

#FFA726

warning

H 36 · C0, 35, 85, 0

#FFFFFF

muted-fg

H 0 · C0, 0, 0, 0

Charts

#FEE951

chart-1

H 53 · C0, 8, 68, 0

#64B5F6

chart-2

H 207 · C59, 26, 0, 4

#81C784

chart-3

H 123 · C35, 0, 34, 22

#F48FB1

chart-4

H 340 · C0, 41, 27, 4

#FFCC80

chart-5

H 36 · C0, 20, 50, 0

A complete dark set: named roles rather than swatches, each with its hex. Every one of these is a question a component would otherwise ask the person — or the agent — building it.

The role list is the same in both modes, which is the point: background, foreground, card, card-foreground, popover, popover-foreground, muted, muted-foreground, primary, primary-foreground, secondary, accent, destructive, border, input, ring, plus chart series. Define them once per mode and every component resolves without anyone picking. Skip them and each new screen re-picks, differently. The full list and what each role is for is in semantic colour tokens explained.

Ambient Sage

Live render

Rendered from the kit's actual tokens, fonts, and treatments

Ambient Sage/Dashboard
Search...⌘K
AS

Dashboard

Welcome back — here's how Ambient Sage is performing today.

Jan 1 – Jan 30, 2026
Overview
Analytics
Reports
Notifications

Active users

15.1k

+5%

Trending up this month

vs. previous 30 days

MRR

$49.1k

+3%

Strong recurring growth

Net of churn

Retention

89%

+2%

Engagement above target

Rolling 28-day window

NPS

69

+3

Meets growth projections

Survey · n=1,204

Total revenue

Last 12 months

$49.1k+18.2%

12m30d7d
JanFebMarAprMayJunJulAugSepOctNovDec

Recent sales

You closed 265 deals this month.

AR

Alex Rivera

alex@ambientsage.com

+$1,999.00
MO

Mira Okonkwo

mira@ambientsage.com

+$39.00
JF

Jonas Feld

jonas@ambientsage.com

+$299.00
SQ

Sana Qureshi

sana@ambientsage.com

+$99.00
TL

Theo Lindgren

theo@ambientsage.com

+$2,400.00

Recent transactions

View all
CustomerStatusDateAmount
AR

Alex Rivera

Founder & CEO

Paid2m ago$1,999.00
MO

Mira Okonkwo

Head of Product

Pending1h ago$39.00
JF

Jonas Feld

Design Lead

Processing3h ago$299.00
SQ

Sana Qureshi

Engineering Lead

PaidYesterday$99.00
TL

Theo Lindgren

Brand Director

Refunded2d ago$2,400.00

Typography

Plus Jakarta Sans

Color system

28 semantic roles, light + dark

Agent outputs

DESIGN.md, CSS, Tailwind, shadcn

The same roles rendered as an interface. A palette is only testable once it is on a screen with real hierarchy.

Four complete dark palettes, and what separates them

Everything above is a rule. These are four dark sets that follow it, chosen because they resolve the same problem in visibly different ways. Read the background and card pair in each: that gap is the elevation model, and it is the decision that most determines whether a dark UI reads as designed or as inverted.

Preview unavailable here. Browse complete kits in the kit gallery.

Token specimen · real values

Files Archival

Live render

Files Archival's actual tokens — the same values its exports use.

Color tokensSemantic roles with HEX / HSL / CMYK

Color tokens

Files Archival

dark · HEX · HSL · CMYK

Core

#191919

background

H 0 · C0, 0, 0, 90

#FAF6F3

foreground

H 26 · C0, 2, 3, 2

#242424

card

H 0 · C0, 0, 0, 86

#2A2A2A

muted

H 0 · C0, 0, 0, 84

#333333

border

H 0 · C0, 0, 0, 80

Brand

#4A6FE0

primary

H 225 · C67, 50, 0, 12

#FFFFFF

primary-fg

H 0 · C0, 0, 0, 0

#3D2B2E

secondary

H 350 · C0, 30, 25, 76

#F5DB7B

accent

H 47 · C0, 11, 50, 4

#4A6FE0

ring

H 225 · C67, 50, 0, 12

Semantic

#C9362A

destructive

H 5 · C0, 73, 79, 21

#FFFFFF

destructive-fg

H 0 · C0, 0, 0, 0

#2D7A4F

success

H 146 · C63, 0, 35, 52

#D4921A

warning

H 39 · C0, 31, 88, 17

#9A8E88

muted-fg

H 20 · C0, 8, 12, 40

Charts

#4A6FE0

chart-1

H 225 · C67, 50, 0, 12

#E29AA5

chart-2

H 351 · C0, 32, 27, 11

#F5DB7B

chart-3

H 47 · C0, 11, 50, 4

#E05040

chart-4

H 6 · C0, 64, 71, 12

#D2BDB6

chart-5

H 15 · C0, 10, 13, 18

The archival end: a warmer, lifted ground that never reaches black, with the separation carried by borders rather than by a big surface step.
Preview unavailable here. Browse complete kits in the kit gallery.

Token specimen · real values

The Social Club

Live render

The Social Club's actual tokens — the same values its exports use.

Color tokensSemantic roles with HEX / HSL / CMYK

Color tokens

The Social Club

dark · HEX · HSL · CMYK

Core

#2E2C1F

background

H 52 · C0, 4, 33, 82

#F4F0E4

foreground

H 45 · C0, 2, 7, 4

#3C3A29

card

H 54 · C0, 3, 32, 76

#3C3A29

muted

H 54 · C0, 3, 32, 76

#4E503A

border

H 65 · C2, 0, 28, 69

Brand

#D6D84A

primary

H 61 · C1, 0, 66, 15

#1A1800

primary-fg

H 55 · C0, 8, 100, 90

#736E4E

secondary

H 52 · C0, 4, 32, 55

#D6D84A

accent

H 61 · C1, 0, 66, 15

#D6D84A

ring

H 61 · C1, 0, 66, 15

Semantic

#9C3C2C

destructive

H 9 · C0, 62, 72, 39

#FFFFFF

destructive-fg

H 0 · C0, 0, 0, 0

#2D702C

success

H 119 · C60, 0, 61, 56

#C47A15

warning

H 35 · C0, 38, 89, 23

#C4C1AE

muted-fg

H 52 · C0, 2, 11, 23

Charts

#D6D84A

chart-1

H 61 · C1, 0, 66, 15

#9C3C2C

chart-2

H 9 · C0, 62, 72, 39

#426063

chart-3

H 185 · C33, 3, 0, 61

#2D702C

chart-4

H 119 · C60, 0, 61, 56

#945C37

chart-5

H 24 · C0, 38, 63, 42

An olive-and-yellow set, which is the hardest case here — a low-lightness accent needs its foreground checked in both directions, not assumed to be white.

How to read four palettes quickly

Ignore the accent first; it is the part you will remember and the part that matters least structurally. Compare background against card to see the elevation model, then muted-foreground against card to see whether secondary text survives on a raised surface. Those two comparisons predict most of how the palette will behave in a real screen.

Why this got urgent

Interfaces are increasingly built by coding agents working from a written brief, and dark mode is the single most commonly missing thing in those briefs. We sampled 299 public DESIGN.md files — the file a coding agent reads before writing UI — and measured what they cover.

Share of files
No dark mode at all69%
No semantic colour roles — raw hex only86%
No prohibitions, only preferences76%
Omissions across 72 public visual-design DESIGN.md files. Detection is heading-based and deliberately generous, so these are a floor.

The consequence is predictable. Asked for a dark variant with nothing written down, an agent inverts the greys — the exact move that breaks all four things listed earlier. It produces something plausible on the first screen and inconsistent by the fifth, and because each individual screen looks fine, nobody catches it until the whole app is built.

A ten-minute check

  1. 1

    Stack three surfaces

    Put an overlay on a card on the background, with a one-pixel border on each. If any boundary disappears, your lightness steps are too close or your border role is doing double duty.

  2. 2

    Render muted text on every surface

    Not just on the background. Muted-on-card is where an inverted palette usually falls apart, and it is the most common text state in a dense interface.

  3. 3

    Build a destructive confirmation

    It exercises destructive, its foreground, its hover and its border together — the cluster of roles people define last and use first.

  4. 4

    Focus something

    Tab to an input. A focus ring is a colour nobody picks deliberately, so it is either your accent doing a job it is bad at, or a browser default nobody chose.

  5. 5

    Look at a dense table

    Three greys next to each other is the hardest thing a dark palette does. A palette that survives a settings table survives a marketing page trivially; the reverse is not true.

Common mistakes

  • Starting at pure black. It removes the level below your background before you have discovered you need one.
  • Reusing the light-mode accent unchanged. It usually needs to lighten, often needs to desaturate, and may need dark text on top of it.
  • Keeping shadows and adding lightness steps. Pick one elevation language. Doing both makes raised surfaces read as smudged.
  • Defining only what the first screen needed. The roles you skip are the ones the next screen invents, and it will invent them differently.
  • Testing on a marketing page. Hero sections flatter every palette. Test on the densest screen you have.

Browse complete dark palettes, not swatch rows

Every kit here defines all its colour roles in both light and dark, plus type, radii and motion — installable as one shadcn registry item. Free kits need no account.

FAQ

Should I use pure black for dark mode?

Generally no. Across five shipping palettes the darkest background is 8% HSL lightness and none is 0%. Pure black leaves no surface below the background, so you lose the ability to show anything recessed. The exception is an OLED-power or media-viewing context where the frame is meant to disappear.

Is dark mode just inverting the light palette?

No. Four things break: shadows stop working because there is nothing left to darken, the accent usually fails contrast, borders either vanish or glow depending on which surface they land on, and muted and disabled states become invisible. A dark palette is a second design, not a filter.

How do I show elevation in dark mode without shadows?

With surface lightness. Define at least three levels — background, raised surface, overlay — spaced roughly 3 to 5 HSL lightness points apart. Below about 3 points the levels stop being distinguishable; much above 6 and the top surface starts to look like a light-mode panel.

What is the difference between a surface and a tonal surface?

A neutral surface raises lightness only; a tonal surface also mixes in some of the brand hue as it rises. Tonal makes the whole interface feel deliberately coloured, neutral keeps colour meaning available for things that need it. Both work — mixing them within one theme does not.

Do my brand colours work in dark mode?

Usually not unchanged. A saturated mid-tone that reads well on white tends to be too dark and too vibrant against a near-black surface. Lighten it for contrast, desaturate it slightly so it stops vibrating, and check whether it now needs dark rather than light text on top.

How many colours does a dark palette need?

About 28 named roles, not five swatches: background and foreground, card, popover, muted, primary, secondary, accent, destructive and their foregrounds, plus border, input, ring and chart series. Anything you leave undefined gets invented per screen, differently each time.