Reference · Design systems

Design tokensValues with a purpose.

A color is a value. A token gives it a job. Connect your palette to the surfaces, text and actions people use, check every pairing in every mode, then carry the same decisions into each framework you ship.

Tokens
177
Layers
3
Modes
2–4
Export formats
10
One brand decision, every mode. The brand ramp feeds four action roles; four components read the roles. Switch the mode and the same names point at other steps.
brand-50brand-100brand-200brand-300brand-400brand-500brand-600brand-700brand-800brand-900brand-950neutral-0neutral-1000color-primarycolor-primary-hovercolor-on-primarycolor-ringbutton-primary-bgbutton-primary-hoverbutton-primary-labelinput-focus
Primary action7.90:1 · AAA

Design token studio

A system you can shape.

Pick a brand color and the studio builds ramps, roles and components for every mode. Trace any alias through the graph, read every pairing in a contrast matrix, review what you changed, then export the same source to your stack.

Start with the interface

A workflow you can repeat.

Build the smallest useful system first. A card, a text field and a primary button reveal more missing decisions than a long list of colors.

  1. 01

    Collect the decisions

    Inventory repeated colors, type sizes, spacing and radii. Separate brand values from the jobs they perform.

  2. 02

    Name the roles

    Give surfaces, text, actions and focus indicators stable names. Map each role to a primitive in each mode.

  3. 03

    Test real pairings

    Check labels on buttons, text on every surface, hover states and focus rings in every mode, and under simulated color vision.

  4. 04

    Review and export

    Fix what the health check finds, read the diff, then generate framework files from the same source.

The architecture

Three layers, three jobs.

A small system can begin with primitives and roles. Add component aliases when a component needs its own contract.

Primitive

The available values

color-brand-700: #4338ca and space-4: 16px define the inventory. They say what exists without promising where it belongs.

Semantic

The intent of a value

color-primary → color-brand-700 means “primary action.” In a dark mode it can point to color-brand-300 while its consumers keep the same name.

Component

A local contract

button-primary-bg → color-primary lets the button evolve independently. Keep the alias when the role is shared; add a component value only when its behavior differs.

Aliases are references to other tokens. Resolve every reference, preserve its type and reject circular chains before generating code. The studio only lets a token point down a layer, so a cycle cannot form.

A shared vocabulary

Name the job.

Use a predictable order: category, role, variant, state. Keep a ramp step for a primitive, and an intent for a role.

Names that survive a redesign
Instead ofUseWhy
blue-buttonbutton-primary-bgThe action can change color.
light-textcolor-text-mutedThe hierarchy holds in every mode.
padding-bigspace-6A scale has a defined value.
redcolor-danger-textStatus and usage are explicit.

Choose kebab-case, camelCase, snake_case or PascalCase for your codebase. Use a prefix such as acme when several systems share a page. Document units, supported modes and the background each text role belongs on.

Treat a token name as an API. Renaming or removing one breaks consumers; changing a value still needs visual and contrast checks. Deprecate old names through aliases during a migration, and keep the changelog with the commit.

Change values, keep intent

Modes are role maps.

A dark mode is a second set of decisions about hierarchy, surfaces and emphasis. A high-contrast mode is a third.

Keep primitives available to every mode. Reassign semantic roles inside a mode, then have components read those roles. The studio chooses ramp references for each mode from measured contrast; if you edit a value or an alias, the matrix and the health check show the result.

Lightsurface → neutral 0
text → neutral 950
primary → a dark brand step
Darksurface → neutral 950
text → neutral 0
primary → a light brand step
Light high contrastsurface → neutral 0
text → neutral 1000
borders → 4.5:1 or more
Dark high contrastsurface → neutral 1000
text → neutral 0
borders → 4.5:1 or more

Set data-theme on a wrapper with the CSS export: light, dark, light-hc or dark-hc. Declare component aliases in each scope too, or inherited custom properties keep the value resolved on an ancestor. The light-dark() export follows the reader’s color scheme with no script, and its high-contrast roles follow prefers-contrast: more.

  • Pair action fills with on-action labels; test default and hover together, and keep hover visibly different.
  • Check muted text on every surface where it appears.
  • Test focus rings and necessary control boundaries against adjacent colors.
  • Use labels or icons alongside status colors, and check them under simulated color vision.

Use the contrast workflow for checks beyond the studio, the dark UI theme and the light UI theme for a measured example of each mode, and accessible UI patterns for keyboard and screen reader behavior.

One source, several consumers

Export for the code you ship.

The studio exports full foundations and mode-aware adapters. The engine adds native targets. Keep the source tokens under version control and regenerate the files when decisions change.

Choosing an export
TargetUse it forMode handoff
CSS / SCSSCustom properties consumed with var().One scope per mode on data-theme, components redeclared in each.
CSS light-dark()Sites that follow the reader’s color scheme. light-dark() on MDNColor roles switch with color-scheme; data-theme forces one. High contrast follows prefers-contrast or data-contrast="more".
Tailwind v3Extend colors, spacing, type, radii and shadows in theme.extend. v3 configurationUtilities map to role variables; load the CSS export too.
Tailwind v4Define utilities with @theme. v4 theme variablesUses @theme inline with the scoped roles.
JSON / TypeScriptConsume values in applications, build scripts or documentation.Pick a mode’s role map in your application; an object does not switch a mode by itself.
DTCGExchange typed tokens and aliases across a compatible token pipeline.DTCG 2025.10 types; one group per mode. Confirm your importer accepts that version.
Figma variablesCreate the system in a Figma file through the Variables REST API.Two collections: primitives, and a theme collection with one mode per mode. Needs an Enterprise plan.
Workspace JSONKeep the editable source, settings and custom tokens.Import back into the studio, or share a link containing the workspace.
Native platformsThe engine exports Android XML, SwiftUI, Flutter and Jetpack Compose.Wire the generated values into platform theme handling and verify units and resolved colors.

The engine’s “Figma / W3C” target uses an older token shape with hex color strings. Check your importer’s expected format; it is different from the typed DTCG 2025.10 export and from the Figma variables request here.

Put it to work

From brief to commit.

Carry your seed and naming into the design engine for a different brief or native exports.

  1. Set the brief

    Choose a seed, a contrast target and whether you ship high-contrast modes. The studio generates ramps, typography, spacing, radii, shadows and motion.

  2. Choose token naming

    Set case and prefix before exporting. Trace the important roles in the graph and test the preview in every mode.

  3. Inspect the matrix

    Check each foreground on each surface, including muted text and controls, and look again under simulated color vision. Recheck actual pages after integrating the tokens.

  4. Review and export

    Clear the health check, read the changes, copy the changelog, then copy or download your format and save the share link with the source.

  5. Review what changed

    Diff names, values and aliases against the last release with a snapshot. Keep mode behavior in one source so framework outputs stay consistent.

References

Go to the source.

The DTCG format is a Community Group specification. Check the exact version your tools support.