CColorWell
Get ColorWell

ColorWell/Guides

How to Create Dark Mode Figma Tokens

Learn to generate harmonized dark mode color palettes with verified contrast and export them as ready-to-use Figma style tokens.

October 12, 2026 · 5 min read

Dark mode tokens are structured color values that define backgrounds, surfaces, text, and accents for a dark interface. To create them, start with your brand color, generate harmonized lighter and darker variations that maintain perceptual hue consistency, verify contrast ratios for accessibility, and export them as named JSON tokens that map directly to Figma styles.

Why Dark Mode Needs More Than Just Inverted Colors

Dark mode is not simply the inverse of light mode. If you take a light gray background and make it dark gray, you often lose the subtle hierarchy needed to distinguish cards, modals, and input fields. A proper dark mode system requires distinct tokens for different elevation levels and text weights.

A common mistake is using a single background color for everything. In practice, you need a base background, a slightly lighter surface color for cards or panels, and potentially a third shade for hover states. Text colors also need adjustment; pure white text on a dark background can cause halation (glowing edges) for some users, so off-white or light gray tokens are often better for body text.

The goal is to create a set of tokens that feel cohesive. This means ensuring that when you lighten a dark background, the hue doesn't shift unexpectedly. Using perceptual color spaces like Oklch helps maintain this consistency, ensuring that your dark mode feels intentional rather than accidental.

Generating a Harmonized Dark Palette from Your Brand Color

Start with your primary brand color. For this example, we will use #4F46E5, a common indigo used in many modern interfaces. This color works well as an accent or primary button color in dark mode because it has sufficient saturation to stand out against dark backgrounds without being neon.

To build the palette, you need to derive supporting colors. You don't need to guess hex codes. You can use a tool that generates harmonized variations based on perceptual color space. When you input #4F46E5, you want a system that generates a dark background compatible with this accent, along with lighter text colors that remain readable.

Here is how the logic works for this specific example:

  1. Background: Needs to be dark but not black. A deep indigo-tinted gray works well. Result: #1E1B4B.
  2. Surface: Needs to be slightly lighter than the background to show separation. Result: #312E81.
  3. Text: Needs to be light enough to read against the dark background but not pure white. Result: #C7D2FE.
  4. Accent: The original brand color #4F46E5 remains the primary action color.

Using ColorWell allows you to drop in #4F46E5 and immediately see these harmonized variations. It ensures that when you lighten #1E1B4B to create #312E81, the hue stays consistent with the original indigo, avoiding muddy or greenish tints that can happen with standard HSL adjustments.

Verifying Contrast Ratios for Text and UI Elements

Accessibility is critical in dark mode. The Web Content Accessibility Guidelines (WCAG) require specific contrast ratios between text and backgrounds. For standard text, the ratio should be at least 4.5:1. For large text or UI components, 3:1 is often sufficient.

Let's verify the example palette against these standards.

ElementColor HexBackground HexContrast RatioWCAG AA Status
Body Text#C7D2FE#1E1B4BHighPass
Secondary Text#A5B4FC#1E1B4BMedium-HighPass
Button Text#FFFFFF#4F46E5HighPass
Border/Divider#312E81#1E1B4BLowVisual Separation Only

The body text #C7D2FE against #1E1B4B provides strong contrast. If you were to use #4F46E5 as the background for white text, the contrast is also sufficient for buttons. However, if you tried to use #4F46E5 as text color on #1E1B4B, the contrast might be too low for small text, making it better suited for icons or large headings.

Automated checks are faster than manual calculation. When generating the palette, ensure every pair of foreground and background colors is checked instantly. This prevents issues where a beautiful color combination fails accessibility standards.

Exporting Tokens Directly to Figma Styles

Once you have your colors, you need to get them into your design file. Manual copying of hex codes is error-prone. The most efficient workflow is to export the colors as a structured JSON object that Figma can interpret as styles or variables.

Here is the JSON structure for the example palette:

{
  "background": "#1E1B4B",
  "surface": "#312E81",
  "text-primary": "#C7D2FE",
  "text-secondary": "#A5B4FC",
  "accent": "#4F46E5",
  "border": "#4338CA"
}

In Figma, you can create a new Style Collection. Name it "Dark Mode Tokens." Paste the hex values into the respective style fields. If you are using a plugin or a tool that supports direct export, you can copy the entire JSON block and import it. This ensures that every designer on your team uses #1E1B4B instead of #1F1C4C or #1D1A4A.

Consistency in naming is just as important as the colors themselves. Use semantic names like background, surface, and text-primary rather than gray-100 or blue-500. Semantic names describe the role of the color, making it easier to adjust the palette later without breaking the design logic.

Managing Named Tokens for Readable Codebases

Design tokens are not just for designers; they are the bridge to development. If your JSON exports use generic names, developers will struggle to maintain the theme. A good naming convention reflects the hierarchy and purpose of the color.

Instead of naming a color #1E1B4B as "Dark Background," name it bg-base. Name the card background bg-surface. Name the primary text text-primary. This abstraction allows you to change the actual hex values later without changing the code logic. If you decide to make the background slightly lighter, you update the value of bg-base, and every component using that token updates automatically.

When exporting from your palette tool, look for options to auto-name tokens based on the color role. Some tools generate names like indigo-500 for accents and slate-700 for backgrounds. While these are descriptive, semantic names like accent-primary and surface-secondary are often more flexible for long-term maintenance.

You can save these named palettes in your browser or cloud account. This allows you to retrieve the exact same token set months later when you need to update the design. Keeping a single source of truth for your colors prevents drift between design files and codebases.

By following this process—starting with a brand color, generating harmonized variations, verifying contrast, and exporting named tokens—you create a robust dark mode system that is accessible, consistent, and easy to maintain.

Do it in ColorWell

Everything in this guide works in the browser — open the tool and try it on your own input.

Open ColorWell →

Questions people also ask

Does dark mode require different contrast ratios than light mode?

No, the WCAG contrast requirements remain identical for both modes, requiring at least 4.5:1 for standard text and 3:1 for large text or UI components. The difference lies in color selection, where off-white text on dark backgrounds often provides better readability and reduces halation compared to pure white.

How do I keep hue consistent when lightening colors for dark mode?

Use a perceptual color space like Oklch instead of standard HSL to ensure hue stability when adjusting lightness. This prevents the muddy or greenish tints that commonly occur with traditional HSL adjustments when creating surface and hover states.

Can I export these tokens to Tailwind CSS as well?

Yes, the structured JSON format used for Figma tokens is directly compatible with Tailwind CSS configuration files. You can map the JSON keys to Tailwind's theme colors to ensure design consistency across your design tool and codebase.

Do I need to install plugins to use ColorWell in Figma?

No, ColorWell is a standalone web tool that generates harmonized color palettes without requiring a plugin installation. You simply copy the generated hex values or JSON output and paste them directly into Figma's style or variable settings.

More guides