Tokens
Colours, type and spacing as theme tokens.
Tokens are the design decisions of a file: colours, fonts, radii and other values that repeat. They are Tailwind v4 theme variables in the @theme block of the style element. Each token makes classes: --color-accent makes bg-accent, text-accent, border-accent and more.
@theme {
--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
--font-display: 'Inter', ui-sans-serif, system-ui, sans-serif;
--color-background: #f8fafc;
--color-foreground: #0f172a;
--color-accent: #2563eb;
--color-accent-foreground: #ffffff;
--radius-lg: 12px;
}
Names
The first part of the name sets the classes that the token makes:
| Name | Classes | Example |
|---|---|---|
--color-* |
bg-*, text-*, border-*, ring-*, fill-*, stroke-*, outline-*, from-*, to-* |
--color-accent gives bg-accent |
--font-* |
font-* (family) |
--font-display gives font-display |
--text-* |
text-* (size) |
--text-display: 72px gives text-display |
--font-weight-* |
font-* (weight) |
--font-weight-heavy: 850 |
--leading-* |
leading-* |
--leading-display: 1.05 |
--tracking-* |
tracking-* |
--tracking-display: -0.03em |
--radius-* |
rounded-* |
--radius-lg: 12px gives rounded-lg |
--shadow-* |
shadow-* |
--shadow-card: 0 1px 2px rgb(0 0 0 / 0.06) |
--spacing-* |
p-*, m-*, gap-*, w-*, h-* |
--spacing-gutter: 24px gives px-gutter |
--container-* |
@*: container variants and max-w-* |
--container-8xl: 96rem |
- A type scale is a set of
--text-*tokens:--text-body: 10ptgivestext-body, and--text-caption: 8ptgivestext-caption. A value can use any unit (px,rem,pt). Do not write--font-size-*: Tailwind does not read it, soSetTokenschanges it to--text-*. - A size token can carry its line height, letter spacing and weight:
--text-display--line-height: 1.05,--text-display--letter-spacing: -0.03em,--text-display--font-weight: 700. - Do not change
--spacing. It is the base step of all spacing classes. - Do not add
--breakpoint-*tokens. Viewport variants do not work in frames.
The standard tokens
GetStyle writes these tokens, and the examples in this skill use them. Use the same names in a new design, so that styles and examples fit.
| Token | Class | Use |
|---|---|---|
--color-background |
bg-background |
The page behind everything |
--color-foreground |
text-foreground |
Main text on the background and on surfaces |
--color-surface |
bg-surface |
Cards, panels, inputs, sidebars |
--color-muted |
bg-muted |
Subtle fills: chips, table heads, image placeholders |
--color-muted-foreground |
text-muted-foreground |
Secondary text: captions, labels, hints |
--color-border |
border-border, ring-border, divide-border |
Hairlines and dividers |
--color-accent |
bg-accent, text-accent |
Main actions, links, the selected state |
--color-accent-foreground |
text-accent-foreground |
Text and icons on the accent colour |
--font-sans |
none | The default font of all text |
--font-display |
font-display |
Headings |
--font-mono |
font-mono |
Code, numbers in tables, small labels |
--radius-sm to --radius-xl |
rounded-sm to rounded-xl |
Radii from small controls to large cards |
--font-sans is the default font of all text, also when the font is a serif. Put the body font in it.
Add other tokens when a design needs them:
- Status colours:
--color-danger,--color-successand--color-warning, each with a-foregroundtoken. - Brand colours:
--color-brand-1,--color-brand-2. - Display type:
--text-displaywith its line height and letter spacing.
Colour pairs
A background token and a text token make a pair. Use them together, so that the text has enough contrast in each mode:
| Background | Text on it |
|---|---|
bg-background |
text-foreground, text-muted-foreground |
bg-surface |
text-foreground, text-muted-foreground |
bg-muted |
text-foreground, text-muted-foreground |
bg-accent |
text-accent-foreground |
bg-danger |
text-danger-foreground |
Keep the contrast of text at 4.5:1 or more, and of large text and icons at 3:1 or more.
When to use a token
- Use a token for each colour, font and radius that the design uses more than one time.
- Use a token when the user chose one. Knighn writes a token class only when the value is a token that someone chose.
- A colour that shows only one time, such as the colour of one illustration, can stay literal:
bg-[#ffd23f]. - Do not copy the value of a token into a class. Write
bg-accent, notbg-[#2563eb].
Modes
A mode set is a data attribute that changes tokens. The base values are in @theme. A mode block changes some of them:
@theme {
--color-background: #ffffff;
--color-foreground: #0a0a0a;
--color-surface: #f5f5f5;
}
[data-theme='dark'] {
--color-background: #0a0a0a;
--color-foreground: #fafafa;
--color-surface: #1c1c1e;
}
[data-brand='rose'] {
--color-accent: #e11d48;
}
- The
themeset has the modes of light and dark. The base values are the light mode. - Other sets use their own attribute, such as
data-brandordata-density. - In a mode block, change only the tokens that are different in that mode.
- A frame takes a mode with
modes: { theme: 'dark' }on its canvas item. An element takes a mode withdata-theme="dark". - Tokens change with the mode. Literal colours do not change.
Write mode blocks with SetTokens:
SetTokens({ '--color-background': '#0a0a0a', '--color-foreground': '#fafafa' }, { mode: 'dark' })
SetTokens({ '--color-accent': '#e11d48' }, { mode: { brand: 'rose' } })
Aliases in mode blocks
A token can refer to another token: --color-ring: var(--color-accent). The browser resolves the reference where the token is declared, which is the root. So when a mode block changes --color-accent, --color-ring keeps the old colour.
Declare the alias again in each mode block that changes its source:
@theme {
--color-accent: #2563eb;
--color-ring: var(--color-accent);
}
[data-theme='dark'] {
--color-accent: #60a5fa;
--color-ring: var(--color-accent);
}
Read and write tokens
GetTokens()returns{ tokens, modes }. Read it before you add tokens, and do not overwrite tokens that the design uses.SetTokens(map, { mode })merges tokens into the@themeblock or into a mode block. A value ofnullremoves a token.ImportTokens(css)reads the tokens of a project's CSS (the text of aglobals.css) throughSetTokens: the custom properties of:root,htmland@themebecome base tokens, and those of.dark,[data-theme="dark"]and@media (prefers-color-scheme: dark)become thedarkmode. Eachvar()is resolved in each mode, so--color-background: var(--background)gets the light and the dark value. It returns{ tokens, dark }.GetStyle(name)returns a full set of standard tokens for a style, with its dark mode.
const { tokens } = GetTokens()
if (!tokens['--color-danger']) {
SetTokens({ '--color-danger': '#dc2626', '--color-danger-foreground': '#ffffff' })
SetTokens(
{ '--color-danger': '#f87171', '--color-danger-foreground': '#1f0a0a' },
{ mode: 'dark' }
)
}