Skip to content

Design tokens

A token is a named value, such as --surface-1 or --brand-ink, that holds a color, a shadow or a curve for both themes. Write the name in code and the value follows the theme.

The token files

The tokens come in three files. Link werklist-tokens.css in a web page. Read werklist-tokens.json in a design tool or a script. Use werklist-tokens.print.css for anything printed: it holds the light values only, without glass or shadows.

How the theme switches

In the CSS file, dark values sit on :root and light values on html[data-theme="light"]. Write data-theme on the root element in both themes, because without it the file gives the dark values. WerkOS always writes it and opens in light.

A token that does not change between themes, such as --brand-true, is declared once, on :root. In the JSON file, $value holds the light value, and the com.werklist.mode extension holds the dark value as well.

/* werklist-tokens.css */
:root {
  --surface-1: #191c2c;
  --text: #ffffff;
}
html[data-theme="light"] {
  --surface-1: #ffffff;
  --text: #0d0d12;
}

/* your stylesheet */
.panel {
  background: var(--surface-1);
  color: var(--text);
}
Light#ffffff
Dark#191c2c
Panel--surface-1
Light#0d0d12
Dark#ffffff
Body text--text

Names in code

The tokens a screen is built from are named for their job, not their look: --surface-control, not --light-grey.

Write the token through var(), as in background: var(--surface-1), and the value follows the theme.

Page
background
var(--bg)
Panel
background
var(--surface-1)
Band
background
var(--surface-2)
Nested box
background
var(--surface-strong)
Control fill
background
var(--surface-control)
Scrim
background
var(--overlay)
Body text
color
var(--text)
Supporting text
color
var(--text-muted)
Labels
color
var(--text-label)
Blue text
color
var(--brand-ink)
Edge of a control
border-color
var(--border)
Row rule
border-color
var(--border-rule)
Marks
background
var(--brand-blue)
Button fill
background
var(--brand-true)
Text on the button fill
color
var(--on-brand)
Status fills
background
var(--success), var(--warning), var(--error)
Status inks
color
var(--success-ink), var(--warning-ink), var(--error-ink)

Families

These are the families a screen is built from, and each has its own page with its scale and its rules. The rest of the file holds tokens that belong to one part of the product, such as --chat-bubble-own in chat, and they are used only there.

Color

Surfaces
--bg, --surface-1, --surface-2, --surface-strong, --surface-control, --overlay
Text
--text, --text-label, --text-muted
Lines
--border, --border-rule, --input-border
Brand
--brand-true, --brand-blue, --brand-ink, --on-brand
Status
--success, --warning, --error, --success-ink, --warning-ink, --error-ink
Selection
--nav-fill-active, --track-tint, --seg-selected

Layout

Spacing
--space-1 to --space-32

Shape

Radius
--radius-sm to --radius-full

Elevation and materials

Elevation
--elevation-0 to --elevation-3
Glass
--glass-fill, --glass-shadow-card, --glass-shadow-panel, --glass-shadow-raised
Layers
--layer-sticky to --layer-toast

Motion

Duration
--duration-instant to --duration-slow
Easing
--ease-standard, --ease-soft

Typography

Type
--type-display to --type-product-caption-small

Accessibility

Focus
--focus-ring, --focus-ring-width, --focus-ring-offset

Permitted and not permitted

Permitted

  • Read colors through their token names.

    The value then follows the theme.

  • Write data-theme on the root element, light included.

    Without it the page takes the dark values.

  • Use the print file for anything on paper.

Not permitted

  • Copy a value from the JSON file into code.

    It keeps one value when the theme changes.

  • Name a new token for how it looks, such as --light-grey.

    The name stops being true in the dark theme.

  • Edit your copy of a token file.

    Take the files as they are published, so every screen reads the same values.

Design tokens

Named values for color, shadow, curve and layout that resolve per theme, offered as a CSS file, a JSON file and a print file.

  • Kind: foundation
  • Page: https://design.werklist.com/foundations/tokens
  • Version: 2.1.2

When to use it

  • Style through var(--token), so the value follows the theme.
  • Link werklist-tokens.css in a web page and write data-theme on the root element, light included.
  • Read werklist-tokens.json in a design tool or a script: $value is the light value, and $extensions["com.werklist.mode"] holds the dark value as well.
  • Use werklist-tokens.print.css for anything printed: light values only, no glass, no shadow.

When not to use it

  • Copying a value from the JSON file into code: it keeps one value when the theme changes.
  • Naming a new token for how it looks, such as --light-grey: the name stops being true in the dark theme.
  • Editing your copy of a token file: take the files as they are published, so every screen reads the same values.
  • Using a token that belongs to one part of the product, such as --chat-bubble-own, anywhere else.

Rules

  • In the CSS file, dark values stand on :root and light values on html[data-theme="light"]. Without data-theme the file gives the dark values. WerkOS always writes the attribute and opens in light.
  • A token that is the same in both themes, such as --brand-true, is declared once, on :root.
  • The tokens a screen is built from are named for their job, not their look: --surface-control, not --light-grey.
  • Page: background takes var(--bg).
  • Panel: background takes var(--surface-1).
  • Band: background takes var(--surface-2).
  • Nested box: background takes var(--surface-strong).
  • Control fill: background takes var(--surface-control).
  • Scrim: background takes var(--overlay).
  • Body text: color takes var(--text).
  • Supporting text: color takes var(--text-muted).
  • Labels: color takes var(--text-label).
  • Blue text: color takes var(--brand-ink).
  • Edge of a control: border-color takes var(--border).
  • Row rule: border-color takes var(--border-rule).
  • Marks: background takes var(--brand-blue).
  • Button fill: background takes var(--brand-true).
  • Text on the button fill: color takes var(--on-brand).
  • Status fills: background takes var(--success), var(--warning) or var(--error).
  • Status inks: color takes var(--success-ink), var(--warning-ink) or var(--error-ink).

Tokens

  • --bg
  • --surface-1
  • --text
  • --brand-true
  • --brand-ink

JSON

{
  "title": "Design tokens",
  "path": "/foundations/tokens",
  "url": "https://design.werklist.com/foundations/tokens",
  "text": "https://design.werklist.com/agent/foundations/tokens",
  "summary": "The three token files, how they switch between light and dark, and how to write a token in code.",
  "version": "2.1.2",
  "kind": "foundation",
  "name": "Design tokens",
  "purpose": "Named values for color, shadow, curve and layout that resolve per theme, offered as a CSS file, a JSON file and a print file.",
  "use": [
    "Style through var(--token), so the value follows the theme.",
    "Link werklist-tokens.css in a web page and write data-theme on the root element, light included.",
    "Read werklist-tokens.json in a design tool or a script: $value is the light value, and $extensions[\"com.werklist.mode\"] holds the dark value as well.",
    "Use werklist-tokens.print.css for anything printed: light values only, no glass, no shadow."
  ],
  "avoid": [
    "Copying a value from the JSON file into code: it keeps one value when the theme changes.",
    "Naming a new token for how it looks, such as --light-grey: the name stops being true in the dark theme.",
    "Editing your copy of a token file: take the files as they are published, so every screen reads the same values.",
    "Using a token that belongs to one part of the product, such as --chat-bubble-own, anywhere else."
  ],
  "tokens": [
    "--bg",
    "--surface-1",
    "--text",
    "--brand-true",
    "--brand-ink"
  ],
  "rules": [
    "In the CSS file, dark values stand on :root and light values on html[data-theme=\"light\"]. Without data-theme the file gives the dark values. WerkOS always writes the attribute and opens in light.",
    "A token that is the same in both themes, such as --brand-true, is declared once, on :root.",
    "The tokens a screen is built from are named for their job, not their look: --surface-control, not --light-grey.",
    "Page: background takes var(--bg).",
    "Panel: background takes var(--surface-1).",
    "Band: background takes var(--surface-2).",
    "Nested box: background takes var(--surface-strong).",
    "Control fill: background takes var(--surface-control).",
    "Scrim: background takes var(--overlay).",
    "Body text: color takes var(--text).",
    "Supporting text: color takes var(--text-muted).",
    "Labels: color takes var(--text-label).",
    "Blue text: color takes var(--brand-ink).",
    "Edge of a control: border-color takes var(--border).",
    "Row rule: border-color takes var(--border-rule).",
    "Marks: background takes var(--brand-blue).",
    "Button fill: background takes var(--brand-true).",
    "Text on the button fill: color takes var(--on-brand).",
    "Status fills: background takes var(--success), var(--warning) or var(--error).",
    "Status inks: color takes var(--success-ink), var(--warning-ink) or var(--error-ink)."
  ]
}

Raw file: https://design.werklist.com/agent/foundations/tokens