--- title: "Tokens" subtitle: "The primitive layer everything else resolves through" description: "The design system's primitive tokens: the unit scale, the type scale, line heights, weights and tracking, and where every other token family is documented." author: "Studio" section: "Website" subsection: "Foundations" order: 3 status: "published" --- Tokens come in two layers. Primitives are raw values with no opinion about where they are used — `--l` is 16px, `--font-m` is 18px, and neither knows what it is for. Semantic tokens name an intent and resolve through a primitive, so `--text-primary` is the colour body text takes, whatever that colour turns out to be. Page and component code uses the semantic layer; this page documents the primitive layer beneath it. ## Why the split exists Reaching past a semantic token to a primitive is the mistake this architecture is built to prevent. `--neutral-800` is a grey; `--text-secondary` is *the colour supporting text takes*, which today happens to be that grey. Write the primitive and the element stops following the theme — it will not invert in dark mode, and a palette change leaves it behind. - **Use a semantic token in page and component code.** If no semantic token fits, the semantic layer is missing one, and the fix is to add it rather than to reach past it. - **Use a primitive only when defining a semantic token.** That is the one place the raw value belongs. ## The unit scale Every spacing and sizing token resolves through this scale, so the whole system moves together if it is re-stepped. Values are rem, which means they track the reader's browser zoom and root font-size preference rather than pinning to device pixels. | Token | Value | Token | Value | | --- | --- | --- | --- | | `var(--none)` | 0 | `var(--5xl)` | 3.5rem · 56px | | `var(--2xs)` | 0.125rem · 2px | `var(--6xl)` | 4rem · 64px | | `var(--xs)` | 0.25rem · 4px | `var(--7xl)` | 4.5rem · 72px | | `var(--s)` | 0.5rem · 8px | `var(--8xl)` | 5rem · 80px | | `var(--m)` | 0.75rem · 12px | `var(--9xl)` | 5.5rem · 88px | | `var(--l)` | 1rem · 16px | `var(--10xl)` | 6rem · 96px | | `var(--xl)` | 1.5rem · 24px | `var(--11xl)` | 6.5rem · 104px | | `var(--2xl)` | 2rem · 32px | `var(--12xl)` | 7rem · 112px | | `var(--3xl)` | 2.5rem · 40px | `var(--13xl)` | 7.5rem · 120px | | `var(--4xl)` | 3rem · 48px | `var(--14xl)` | 10rem · 160px | The `--space-*` tokens are aliases onto this scale — `--space-l` is `var(--l)` — and they are what layout code actually uses. The [Spacing](/website/spacing.html) page covers them and the utilities that apply them. ## Type scale Font sizes are primitives. Nothing here says which element takes which step; that mapping is the [web hierarchy](/website/typography.html) on the Typography page. | Token | Value | Token | Value | | --- | --- | --- | --- | | `var(--font-3xs)` | 0.625rem · 10px | `var(--font-3xl)` | 1.75rem · 28px | | `var(--font-2xs)` | 0.75rem · 12px | `var(--font-4xl)` | 2rem · 32px | | `var(--font-xs)` | 0.875rem · 14px | `var(--font-5xl)` | 2.25rem · 36px | | `var(--font-s)` | 1rem · 16px | `var(--font-6xl)` | 2.5rem · 40px | | `var(--font-m)` | 1.125rem · 18px | `var(--font-7xl)` | 3rem · 48px | | `var(--font-l)` | 1.25rem · 20px | `var(--font-8xl)` | 3.5rem · 56px | | `var(--font-xl)` | 1.375rem · 22px | `var(--font-9xl)` | 4rem · 64px | | `var(--font-2xl)` | 1.5rem · 24px | `var(--font-10xl)` | 4.5rem · 72px |
--font-10xl · 72px
Where Culture Meets Care
--font-9xl · 64px
Where Culture Meets Care
--font-8xl · 56px
Where Culture Meets Care
--font-7xl · 48px
Where Culture Meets Care
--font-6xl · 40px
Where Culture Meets Care
--font-5xl · 36px
Where Culture Meets Care
--font-4xl · 32px
Where Culture Meets Care
--font-3xl · 28px
Where Culture Meets Care
--font-2xl · 24px
Where Culture Meets Care
--font-xl · 22px
Where Culture Meets Care
--font-l · 20px
Where Culture Meets Care
--font-m · 18px
Where Culture Meets Care
--font-s · 16px
Where Culture Meets Care
--font-xs · 14px
Where Culture Meets Care
--font-2xs · 12px
Where Culture Meets Care
--font-3xs · 10px
Where Culture Meets Care