Design tokens: colours, spacing and themes in one source

What design tokens are, three levels from palette to components, how to name them, one card in three themes, kinds of tokens and code — with live examples.

Design systems Updated

In short

Design tokens are named design decisions: colours, spacing, radii, font sizes, shadows and durations stored in one place and used by both the layout and the code. Instead of “#E4FF4E” a button uses “color.accent”, and instead of “24 px” a card uses “space.5”. Tokens are usually built in three levels: primitives — the raw values of the palette and scales; semantic tokens — roles such as background, text and accent; component tokens — the roles applied to a specific button or card. This is what makes a dark theme, a second brand or a redesign a change of values in one file rather than a search through hundreds of styles.

Three levels of tokens

Primitives say what the colour is, roles say what it is for, component tokens say where it is used.

1Primitives

lime-400#E4FF4E
olive-700#9CAF2B
sage-200#E1E3DF
sage-400#BBC0B5
graphite-800#323231
graphite-950#171817

2Semantic

color.bg→ sage-200
color.surface→ white
color.text→ graphite-950
color.accent→ lime-400
color.border→ sage-400

3Component

button.bg→ color.accent
button.text→ color.text
card.bg→ color.surface
card.border→ color.border
Button

The key level is the middle one. Components refer to roles, not to raw colours: a button takes “color.accent”, not “lime-400”. Then a new theme only reassigns roles to other primitives — the components do not notice anything.

How to name tokens

A good name says the role, not the look. The look will change; the role stays.

WhatBad nameGood nameWhy
Main accent green color.accent the accent may stop being green
Page background gray-light color.bg in a dark theme it is dark
Error text red-500 color.danger the role is clear in every component
Card padding padding-24 space.5 the number may change, the step stays
Heading size font-39 font.step-4 fluid sizes have no single number
Button colour button-lime button.bg → color.accent the component refers to a role

One card, three themes

Switch the theme: the card’s code stays the same, only the values of four roles change.

New

Solid oak table

The card’s code does not change — only the values of the roles do: background, surface, text, accent.

DetailsSave
  • color.bg
  • color.surface
  • color.text
  • color.accent

The same mechanism gives a dark theme, a second brand on the same code, a seasonal campaign or an accessible high-contrast version. Without the level of roles each of these is a separate copy of the styles.

Kinds of tokens: not only colours

Everything that repeats in design and has a value becomes a token.

Color

color.accent

Spacing

space.5 = 24px

Radius

radius.sm = 8px

Type

AaAaAa
font.step-3

Shadow

shadow.md

Motion

duration.base = 280ms

Tokens in code: a source and the result

Tokens are kept in JSON — the format with $value and $type that Style Dictionary and Tokens Studio read — and turned into CSS variables.

The source

Roles refer to primitives in curly braces — change the primitive, and every role follows.

tokens.json
{
  "color": {
    "lime-400":     { "$type": "color", "$value": "#E4FF4E" },
    "sage-200":     { "$type": "color", "$value": "#E1E3DF" },
    "graphite-950": { "$type": "color", "$value": "#171817" },

    "bg":        { "$type": "color", "$value": "{color.sage-200}" },
    "text":      { "$type": "color", "$value": "{color.graphite-950}" },
    "accent":    { "$type": "color", "$value": "{color.lime-400}" },
    "on-accent": { "$type": "color", "$value": "{color.graphite-950}" }
  },
  "space": {
    "4": { "$type": "dimension", "$value": "16px" },
    "5": { "$type": "dimension", "$value": "24px" }
  },
  "duration": {
    "base": { "$type": "duration", "$value": "280ms" }
  }
}

CSS variables and a theme

A dark theme reassigns two roles; the button does not change.

tokens.css
/* Built from tokens.json: primitives once, roles for every theme */
:root {
  --lime-400: #E4FF4E;
  --sage-200: #E1E3DF;
  --graphite-950: #171817;

  --color-bg: var(--sage-200);
  --color-text: var(--graphite-950);
  --color-accent: var(--lime-400);
  --color-on-accent: var(--graphite-950);
}

[data-theme="dark"] {
  --color-bg: var(--graphite-950);
  --color-text: #F8F8F8;
}

/* Components use only roles, never primitives */
.button {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

6 rules of a token system

  1. 01

    One source

    Tokens live in one file, and both the layout tool and the code take them from it.

  2. 02

    Components only through roles

    A raw colour inside a component is a future bug of the dark theme.

  3. 03

    Names by role

    “accent”, “danger”, “surface” — not “green”, “red”, “white”.

  4. 04

    A pair for every background

    For every background role there is a text role that is readable on it.

  5. 05

    Few levels

    Three levels are enough; a fourth usually only adds confusion.

  6. 06

    Changes through the source

    Nobody edits the generated CSS by hand; it is rebuilt from tokens.

Common mistakes with design tokens

  1. Tokens only in the layout

    The code keeps its own colours, and after a month they no longer match.

  2. Hundreds of tokens

    A token for every case turns the system into a dictionary nobody reads.

  3. Names by colour

    “blue-button” stays blue in the name after the redesign makes it lime.

  4. Skipping the roles

    Components refer straight to the palette, and a dark theme requires rewriting them.

  5. No text roles

    Text on the accent becomes unreadable in one of the themes.

  6. Manual edits to the result

    The next build overwrites them, and the bug returns.

Questions about design tokens

What are design tokens in simple words?

Named design values — colours, spacing, sizes — that the layout and the code share.

How are tokens different from CSS variables?

Tokens are the source; CSS variables are one of the formats they are turned into, alongside iOS, Android and the layout tool.

Where are tokens stored?

In a JSON file in the repository; Figma variables and Tokens Studio connect it to the layout.

How many tokens does a site need?

Usually a few dozen: a palette, 10–15 roles, scales of spacing and type, radii and durations.

Do I need tokens for a small site?

A short set of CSS variables — yes, it costs nothing; a full pipeline — when there are several products or themes.

What is Style Dictionary?

A tool that turns one set of tokens into CSS, JavaScript, iOS and Android files.

Online form

Tokens
for your brand

I build token systems that connect the layout and the code: palette, roles, themes and component values in one source. Tell me about the project — I answer within one working day.

Or write to [email protected]