Foundations

Color palette

Compact and detailed scales coexist as infix tokens. Unscoped aliases and utilities follow data-df-color-scale. Browse the palette, then read the usage guide below.

Palette browser

Toggle compact or detailed to change which steps are shown and which infix names appear in tooltips. Swatch fills use the live CSS variables.

Click any swatch to copy its hex. Token names use an infix density marker (for example --df-neutral-compact-500).

Neutral

Slate

Rose

Red

Coral

Red Orange

Orange

Amber

Yellow Orange

Gold

Yellow

Yellow Green

Lime

Green

Emerald

Jade

Teal

Blue Green

Turquoise

Cyan

Azure

Blue

Indigo

Blue Purple

Violet

Purple

Orchid

Fuchsia

Magenta

Red Purple

Token naming

Every primitive color is a CSS custom property. The density is part of the name so compact and detailed never collide.

  • Detailed: --df-{family}-detailed-{step}, for example --df-neutral-detailed-500.
  • Compact: --df-{family}-compact-{step}, for example --df-neutral-compact-500.
  • Alias: --df-{family}-{step}, for example --df-neutral-500. This follows the active color scale mode.
  • Family is neutral, brand, a wheel hue (red, blue, …), or an extra hue (rose, cyan, …).
  • Step is a lightness stop from 0 (lightest) to 1000 (darkest). Detailed also includes step 25.

Name shape

Token naming

--df-neutral-detailed-500
--df-neutral-compact-500
--df-neutral-500 /* alias → active mode */
--df-blue-detailed-300
--df-blue-compact-300

Three ways to use color

Pick the path that matches how much control you need. You can mix them in one app.

Direct

Reference an infix token. The value never changes when the page mode flips.

Mode switch

Set data-df-color-scale on html (or a subtree). Unscoped aliases and utilities follow it.

Alias

Write --df-neutral-500 or bg-neutral-500. The host mode chooses detailed or compact for you.

Direct infix tokens

Use when a surface must stay on one density, even if the rest of the app switches. Both palettes are always defined on :root.

Inline style

Direct infix CSS

/* Always the detailed mid gray */
background: var(--df-neutral-detailed-500);
/* Always the compact mid gray (same stop name, snapped value) */
background: var(--df-neutral-compact-500);
/* Hue example */
border-color: var(--df-blue-detailed-400);

React

Direct infix React

<div
style={{ backgroundColor: "var(--df-neutral-detailed-40)" }}
/>
<svg>
<rect fill="var(--df-blue-compact-500)" />
</svg>

Mode switch

One attribute chooses which density unscoped aliases resolve to. Default File UI apps usually set detailed on the document root.

Document root

HTML mode attribute

<html data-df-color-scale="detailed">
<!-- aliases → --df-*-detailed-* -->
</html>
<html data-df-color-scale="compact">
<!-- aliases → --df-*-compact-* -->
</html>

Subtree preview

Subtree mode

{/* Compare both densities side by side */}
<div data-df-color-scale="compact">
<Button className="bg-neutral-500" />
</div>
<div data-df-color-scale="detailed">
<Button className="bg-neutral-500" />
</div>
  • Detailed (default): fine ladder. Steps every 10 from 0 to 1000, plus 25.
  • Compact: same token names, values snap to the usual stops (0, 50, 100, 200, … 950, 1000). Step 25 is kept as itself.
  • Infix tokens are not remapped by the attribute. Only aliases and anything that points at aliases move.

Unscoped aliases

Short names for day-to-day UI. They are defined as var() pointers into the active infix palette.

What the CSS does

Alias mapping

:root,
[data-df-color-scale="detailed"] {
--df-neutral-500: var(--df-neutral-detailed-500);
}
[data-df-color-scale="compact"] {
--df-neutral-500: var(--df-neutral-compact-500);
}

Usage

Alias usage

color: var(--df-neutral-900);
background: var(--df-brand-50);
outline-color: var(--df-blue-400);

Utility classes

Generated utilities resolve through unscoped aliases, so they follow data-df-color-scale. Prefer these for layout chrome.

Background, text, border

Utility examples

<div className="bg-neutral-50 text-neutral-900 border border-neutral-100">
Panel
</div>
{/* Compat aliases map to the same DF neutrals */}
<div className="bg-zinc-100 text-gray-900" />
  • bg-neutral-{step}, text-neutral-{step}, border-neutral-{step} use var(--df-neutral-{step}).
  • zinc-* and gray-* are compatibility maps onto the same DF neutral aliases.
  • For an explicit density in a className, use an arbitrary value: bg-[var(--df-neutral-detailed-500)].

Semantic tokens

Kit components and most app chrome speak in roles, not ramp steps. Semantics live in df-tokens.css and point at neutral (or brand) aliases.

Common roles

Semantic tokens

--background
--foreground
--primary / --primary-foreground
--secondary / --secondary-foreground
--muted / --muted-foreground
--accent / --accent-foreground
--destructive
--border / --input / --ring
--card / --popover
--sidebar-*

In markup

Semantic utilities

<main className="bg-background text-foreground">
<button className="bg-primary text-primary-foreground">
Save
</button>
<p className="text-muted-foreground">Supporting copy</p>
</main>
  • Use semantics for product UI so light and dark (and scale mode) stay consistent.
  • Reach for ramp steps when you need a specific stop on a chart, illustration, or custom surface.
  • Compact mode remaps a few semantics that used mid-steps (such as 850) so they still resolve cleanly.

Families and steps

The same rules apply to every family in the palette browser above.

  • neutral: achromatic ramp for surfaces, text, and chrome.
  • brand: lightly tinted slate ramp used where a product accent sits near neutral.
  • Wheel hues: red, red-orange, orange, yellow-orange, yellow, yellow-green, green, blue-green, blue, blue-purple, purple, red-purple.
  • Extra hues: rose, coral, amber, gold, lime, emerald, jade, teal, turquoise, cyan, azure, indigo, violet, orchid, fuchsia, magenta.
  • Detailed steps: 0, 10, 20, …, 1000, plus 25 on every family.
  • Compact steps: same names, values snap to 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950, 1000 (25 kept).

Common recipes

Short patterns you can paste into tools and product UI.

Tool canvas that follows the app mode

Alias canvas

<div
className="min-h-0 flex-1"
style={{ backgroundColor: "var(--df-neutral-40)" }}
/>

Illustration locked to detailed

Detailed illustration

<circle fill="var(--df-cyan-detailed-260)" />
<path stroke="var(--df-neutral-detailed-900)" />

Export from Color Lab

Exported CSS shape

/* palette1 · compact */
:root {
--df-neutral-compact-0: #ffffff;
--df-neutral-compact-50: #f5f5f5;
/* …
}

Need a custom seed scale? Open Color Lab to generate stops, check contrast, and export CSS or JSON with the matching infix density names.