---
title: "Classes"
subtitle: "The utility layer, and what each class is allowed to do"
description: "The general-purpose utility classes: text size and colour, spacing, containers, layout primitives and helpers, with the token each one resolves through."
author: "Studio"
section: "Website"
subsection: "Foundations"
order: 4
status: "published"
---
Utilities apply a token to an element without writing CSS. Most modify a single concern — a size, a colour, a gap — so they compose rather than compete, and none of them carries a raw value of its own. A few set a pair that always travels together: the text-size classes set line height alongside font size, and `.label` and `.eyebrow` set a whole small type treatment. Where a class resolves through a token, the token's value is on the [Tokens](/website/tokens.html) page.
## Text size
The two spellings are aliases of one rule, not two scales: `.text-size-l` and `.text-size-large` are the same declaration. Use whichever reads better and stay consistent within a page.
| Class | Alias | Resolves to | Value |
| --- | --- | --- | --- |
| `.text-size-xl` | `.text-size-xlarge` | `var(--text-size-xl)` | 28px, stepping to 24px below 960px |
| `.text-size-l` | `.text-size-large` | `var(--text-size-l)` | 20px |
| `.text-size-m` | `.text-size-medium` | `var(--text-size-m)` | 16px — body size |
| `.text-size-s` | `.text-size-small` | `var(--text-size-s)` | 14px |
| `.text-size-xs` | `.text-size-xsmall` | `var(--text-size-xs)` | 14px |
.text-size-xl
Where Culture Meets Care
.text-size-l
Where Culture Meets Care
.text-size-m — body
Where Culture Meets Care
.text-size-s
Where Culture Meets Care
.text-size-xs — identical to small today
Where Culture Meets Care
- **Do not reach for `.text-size-xs` expecting something smaller than small.** Both steps resolve to 14px today, so the two are visually identical; the distinction exists in the token layer, not on screen.
## Font size
The text-size classes above are the default. These apply a step of the primitive scale directly, for the cases where the semantic scale has no rung in the right place.
| Class | Value | Class | Value |
| --- | --- | --- | --- |
| `.font-2xs` | 12px | `.font-4xl` | 32px |
| `.font-xs` | 14px | `.font-5xl` | 36px |
| `.font-s` | 16px | `.font-6xl` | 40px |
| `.font-m` | 18px | `.font-7xl` | 48px |
| `.font-l` | 20px | `.font-8xl` | 56px |
| `.font-xl` | 22px | `.font-9xl` | 64px |
| `.font-2xl` | 24px | `.font-10xl` | 72px |
| `.font-3xl` | 28px | | |
`--font-3xs` (10px) exists as a token but ships no utility. Two family classes sit alongside these: `.font-primary` sets Inter and `.font-secondary` sets Erode.
- **Prefer the semantic scale.** `.text-size-m` keeps following the system if the body size is ever re-stepped; `.font-s` is pinned to 16px whatever happens around it.
## Text colour
| Class | Token |
| --- | --- |
| `.text-primary` | `var(--text-primary)` |
| `.text-secondary` | `var(--text-secondary)` |
| `.text-faded` | `var(--text-faded)` |
| `.text-accent` | `var(--text-accent)` |
| `.text-plain` | `var(--text-plain)` |
| `.text-link` | `var(--text-link)` |
What each token means and its value in both themes are on the [Colour](/website/color.html) page; this table is only the mapping from class to token.
## Background
| Class | Token |
| --- | --- |
| `.bg-primary` | `var(--background-primary)` |
| `.bg-secondary` | `var(--background-secondary)` |
| `.bg-plain` | `var(--background-plain)` |
| `.bg-faded` | `var(--background-faded)` |
## Text alignment
`.text-left` · `.text-center` · `.text-right`
## Section spacing
`.top-small` · `.top-medium` · `.top-large` · `.top-xl` and the matching `.bottom-*` set the vertical space between bands of a page. The values and the token chain behind them are on the [Spacing](/website/spacing.html) page.
## Gap
Micro spacing inside a block, and the only source of vertical rhythm there — the [Spacing](/website/spacing.html) page explains why a margin cannot be used instead.
| Class | Value | Class | Value |
| --- | --- | --- | --- |
| `.gap-none` | 0 — but see below | `.gap-l` | 16px |
| `.gap-xs` | 4px | `.gap-xl` | 24px |
| `.gap-s` | 8px | `.gap-2xl` | 32px |
| `.gap-m` | 12px — the default | `.gap-3xl` | 40px |
- **`.gap-none` does not work on a `.grid`.** It is the only gap utility without `!important`, and `.grid` sets its own 12px gap later in the stylesheet at equal specificity, so `class="grid gap-none"` still renders 12px. On a `.block` it behaves as written.
## Padding
| Class | Value | Class | Value |
| --- | --- | --- | --- |
| `.padding-s` | 8px | `.padding-xl` | 24px |
| `.padding-m` | 12px | `.padding-2xl` | 32px |
| `.padding-l` | 16px | `.padding-3xl` | 40px |
`.padding-global` sets the horizontal page gutter at 24px on both sides, and is the class that keeps every section's content aligned to the same edge.
## Containers and max-widths
`.container-xs` through `.container-xl` cap width and centre; `.max-width-xs` through `.max-width-xl` cap width and leave the element where it is. `.max-width-full` releases a constraint set further up. The five widths and what each suits are on the [Layout](/website/layout.html) page.
## Layout primitives
| Class | What it does |
| --- | --- |
| `.block` | A flex column with a 12px gap. The workhorse — almost every stack of content is one |
| `.grid` | A grid, two columns by default, with a 12px gap |
| `.cols-2` · `.cols-3` · `.cols-4` | Column count on a grid |
| `.row` · `.row-reverse` | Lays a block out horizontally instead |
## Alignment modifiers
`.align-start` · `.align-center` · `.align-end` · `.align-stretch` set cross-axis alignment; `.justify-center` and `.justify-end` set main-axis. `[data-align="center"]` centres a block itself rather than its contents.
## Helpers
| Class | What it does |
| --- | --- |
| `.eyebrow` | The small tracked label above a heading |
| `.label` | A form or metadata label |
| `.fit-content` | Shrinks an element to its content width |
| `.visually-hidden` | Removes an element visually while leaving it in the accessibility tree — the correct way to label an icon-only control |
| `.is-hidden` | Removes it from both |
| `.overflow-hidden` | Clips overflowing children |
## Elsewhere
| Utilities | Documented on |
| --- | --- |
| `.border`, `.border-*` — position, width, style and colour | [Border](/website/border.html) |
| `.img`, `.img-1x1` and the other aspect ratios | [Image](/website/image.html) |
## Rules
- **Never mix layout responsibilities.** Sections carry macro spacing with `.top-*` and `.bottom-*`, blocks carry micro spacing with `.gap-*`, and containers carry width. A container that sets its own padding has taken on a job that is not its own.
- **Never put a margin inside a block.** Gap is the single source of spacing there, and a margin adds to it rather than collapsing with it.
- **Ignore `.padding-section`.** It ships as `display: block` and applies no padding at all, despite the name; section spacing comes from `.top-*` and `.bottom-*`.
- **Never write a utility that carries a literal value.** If a class needs a value the tokens do not cover, the token scale is missing a step — add the step.