Light and dark

Dark Mode Color Palette Generator

Dark mode is not a flipped light theme. Surfaces, borders and accents all need their own contrast decisions. Generate both themes from one palette and compare them side by side.

Short answer

A dark mode palette needs a dark background, a slightly lighter surface, readable body text, a muted text color and an adjusted primary accent. Check each pair against WCAG, because a color that passes on white may fail on a dark surface.

The same brand palette shown as a light interface and a dark interface with measured contrast pairs

Live theme

Preview a complete light and dark theme

Choose a sample palette, switch themes, and copy the CSS variables a real component library consumes.

Light
BrandHueDocsPricingGet started
Color system

A theme that holds up in both modes.

Surfaces, borders and text pairs are generated from the same palette. Switch the theme and compare the hierarchy.

Primary actionSecondary
Monthly reportUpdated today
+24.8%
Conversion8.4%
Activation62%

Semantic roles

Contrast checks

Light body text16.96:1AA
Light muted text16.96:1AA
Light primary button4.48:1Check
Dark body text17.85:1AA
Dark muted text7.77:1AA
Dark primary button4.48:1Check
Copy the theme
CSS variables
:root {
  --color-primary: #0B84D8;
  --color-primary-foreground: #111827;
  --color-secondary: #E0F2FE;
  --color-accent: #F59E0B;
  --color-neutral: #64748B;
  --color-background: #F8FAFC;
  --color-surface: #FCFDFE;
  --color-text: #111827;
  --color-muted-text: #111827;
  --color-border: #CFD4DC;
  --color-success: #22C55E;
  --color-warning: #F59E0B;
  --color-danger: #DC2626;
}

[data-theme="dark"] {
  --color-background: #0F172A;
  --color-surface: #0A1123;
  --color-text: #FFFFFF;
  --color-muted-text: #A2ACB9;
  --color-border: #344055;
  --color-primary: #0B84D8;
  --color-primary-foreground: #111827;
}
shadcn theme
:root {
  --background: #F8FAFC;
  --foreground: #111827;
  --card: #FCFDFE;
  --card-foreground: #111827;
  --primary: #0B84D8;
  --primary-foreground: #111827;
  --secondary: #E0F2FE;
  --secondary-foreground: #111827;
  --accent: #F59E0B;
  --accent-foreground: #111827;
  --muted: #FAFCFD;
  --muted-foreground: #111827;
  --border: #CFD4DC;
  --destructive: #DC2626;
  --destructive-foreground: #FFFFFF;
  --ring: #0B84D8;
}

.dark {
  --background: #0F172A;
  --foreground: #FFFFFF;
  --card: #0A1123;
  --card-foreground: #FFFFFF;
  --primary: #0B84D8;
  --primary-foreground: #111827;
  --secondary: #E0F2FE;
  --secondary-foreground: #111827;
  --accent: #F59E0B;
  --accent-foreground: #111827;
  --muted: #0D1427;
  --muted-foreground: #A2ACB9;
  --border: #344055;
  --destructive: #DC2626;
  --destructive-foreground: #FFFFFF;
  --ring: #0B84D8;
}
Figma tokens
{
  "color": {
    "primary": {
      "value": "#0B84D8",
      "type": "color"
    },
    "secondary": {
      "value": "#E0F2FE",
      "type": "color"
    },
    "accent": {
      "value": "#F59E0B",
      "type": "color"
    },
    "neutral": {
      "value": "#64748B",
      "type": "color"
    },
    "background": {
      "value": "#F8FAFC",
      "type": "color"
    },
    "surface": {
      "value": "#FCFDFE",
      "type": "color"
    },
    "text": {
      "value": "#111827",
      "type": "color"
    },
    "mutedText": {
      "value": "#111827",
      "type": "color"
    },
    "success": {
      "value": "#22C55E",
      "type": "color"
    },
    "warning": {
      "value": "#F59E0B",
      "type": "color"
    },
    "danger": {
      "value": "#DC2626",
      "type": "color"
    }
  },
  "dark": {
    "background": {
      "value": "#0F172A",
      "type": "color"
    },
    "surface": {
      "value": "#0A1123",
      "type": "color"
    },
    "text": {
      "value": "#FFFFFF",
      "type": "color"
    },
    "mutedText": {
      "value": "#A2ACB9",
      "type": "color"
    }
  }
}
OKLCH tokens
{
  "primary": "oklch(59.84% 0.1578 247.9)",
  "secondary": "oklch(95.14% 0.0250 236.8)",
  "accent": "oklch(76.86% 0.1647 70.1)",
  "neutral": "oklch(55.44% 0.0407 257.4)",
  "background": "oklch(98.42% 0.0034 247.9)",
  "foreground": "oklch(21.01% 0.0318 264.7)",
  "surface": "oklch(99.36% 0.0017 247.8)",
  "success": "oklch(72.27% 0.1920 149.6)",
  "warning": "oklch(76.86% 0.1647 70.1)",
  "danger": "oklch(57.71% 0.2152 27.3)"
}
Keep this palette

Email a private link to reopen it and its CSS, Tailwind, shadcn, Figma and OKLCH exports.

No account. We store the palette colors and your email, never the image.

Dark mode is not inverted light mode

The naive approach is to swap white for black and keep every other color the same. That usually produces harsh contrast, glowing accents and surfaces that blend together. Dark interfaces need their own hierarchy.

In a dark theme, pure black is rarely the best background. A very dark neutral with a slight tint from the brand palette is easier on the eyes and gives the surface colors room to separate. Pure white text can also be too harsh; an off-white or very light neutral often reads better.

The goal is not to make the interface darker. The goal is to preserve the same information hierarchy with a different set of surfaces.

The three surfaces of a dark UI

A dark interface usually needs a background, a surface and an elevated surface. The background is the page. The surface is a card or panel. The elevated surface is a modal, menu or popover.

Each step should be distinguishable without relying on a heavy border. If the surface and background are too close, the layout will feel flat. If they are too far apart, the interface will feel like a stack of disconnected boxes.

Borders in dark mode often work better as a low-contrast light line than as a dark line. A dark border on a dark surface disappears; a subtle light border defines the edge without shouting.

LayerJobTypical relationship
BackgroundThe pageDarkest neutral
SurfaceCards and panelsSlightly lighter than background
ElevatedModals and menusLighter again, or a stronger border

Desaturate, then re-check contrast

Highly saturated colors can vibrate on dark backgrounds. A bright pink that looks cheerful on white may feel neon on near-black. Reducing saturation and adjusting lightness often produces a more comfortable dark-mode accent.

But desaturation changes contrast. A color that was readable as a button background may no longer support white text. Re-check every pair after the adjustment instead of assuming the light-mode result still holds.

PhotoColors adjusts the primary, secondary and accent colors for the dark theme and reports the resulting contrast ratios. Use that as a starting point, then test the final values in the product.

Status colors need separate treatment

Success, warning and danger colors are semantic, not decorative. They need to remain distinguishable in both themes and should never rely on hue alone. Pair each status color with an icon or a text label.

In dark mode, a deep red danger state can disappear into a dark surface. A warning amber may become too bright. Adjust the lightness of the status colors separately from the brand accents.

If the brand color is green and the success color is also green, the two roles will compete. Consider using the brand green for actions and a different green, or a green with a distinct icon, for success.

A practical dark-mode workflow

Start with the light palette. Choose the background, surface, text and primary action. Then create the dark palette by choosing a new background family and re-checking the same roles.

Do not copy the light-mode neutral scale directly. The dark scale needs its own steps, especially in the 800-950 range. The surface and border colors often need more separation than they do in light mode.

Finally, preview real content. A dashboard, a pricing card and a form will reveal different problems than a swatch strip. The palette is ready when the hierarchy survives all three.

  • Choose a dark neutral background, not pure black.
  • Give surfaces and elevated surfaces distinct steps.
  • Adjust brand accents for dark backgrounds.
  • Re-check every text pair after the adjustment.
  • Test with real cards, forms and menus.

FAQ

Dark Mode Color Palette Generator FAQ

Should dark mode use pure black?

Usually not. A very dark neutral with a slight brand tint gives surfaces room to separate and is easier to read. Pure black can make bright accents vibrate.

Can I use the same primary color in light and dark mode?

Sometimes, but it often needs adjustment. A color that passes contrast on white may fail on a dark surface. Re-check the pair and adjust lightness or saturation if needed.

How many dark surfaces do I need?

At least three: background, surface and elevated surface. The exact values depend on the product, but the hierarchy should be visible without heavy borders.

Does PhotoColors generate dark mode automatically?

Yes. Every extracted palette includes a light and a dark theme, and the preview lets you compare them. The dark theme is a starting point, not a substitute for testing real screens.

What contrast ratio should dark mode text use?

The same WCAG thresholds apply: 4.5:1 for normal text and 3:1 for large text under AA, with higher targets under AAA.