---
title: "Space tokens"
description: "The generated reference for the root spacing value, the numeric steps derived from it, the named roles, the target floor and the four mode thresholds."
url: "https://opsinjs.pensievelabs.org/foundations/space/tokens"
source: "https://opsinjs.pensievelabs.org/foundations/space/tokens.md"
section: "Foundations"
kind: "foundation"
reviewed: "2026-09-20"
reviewer: "engineering"
aliases: ["spacing tokens", "space token reference"]
---

> Elements written as `<PascalCase … />` below are opsinjs documentation
> components. Their attributes are the content: the values they render are
> generated from `tokens/*.json` and `registry/catalogue.ts` and are
> published separately at https://opsinjs.pensievelabs.org/r/index.json and under the Reference
> section.
> Nothing is missing from this page. The data simply does not live in
> the prose.

<PageTemplate kind="foundation" />

## Overview [#overview]

Everything the space system knows, in one generated table: the root value, the
steps, the named roles that map onto them, the touch-target floor, the minimum
separation between adjacent targets, and the four container thresholds that
define the responsive modes. Generated from `tokens/space.json` by
`scripts/build-tokens.mts`.

This is the table most often opened while building rather than while reading,
because the `Used by` column answers the question that actually comes up. That
question is not "how big is `section`" but "what else assumes `section`, and will
I break it".

## How it works [#how-it-works]

`tokens/space.json` holds four groups.

**The root.** A single value from which Tailwind derives its whole spacing scale.
The product theme sets it above the default; the docs chrome leaves it there.
Everything in the steps group is a multiple of it, and the generated table shows
the multiple as well as the resolved value.

**The named roles.** `hairline` through `page`, each mapped to a step. Components
consume roles; the numeric steps exist underneath them. See
[Spacing scale](./spacing-scale.mdx).

**The floors.** `--opsin-target-minimum`, the minimum touch target, and the
minimum separation between adjacent interactive elements. These are the only
values in the space system that are not multiples of the root. They are absolute
physical minimums and they do not move when the product's density is retuned.
That is the point of them.

**The mode thresholds.** The container widths at which `compact`, `medium`,
`expanded` and `wide` begin, plus the per-mode gutter and the line-measure cap.
These are consumed by container queries, not media queries, everywhere except the
shell. See [Responsive modes](./responsive-modes.mdx).

## Using it [#using-it]

**Look up the role, not the number.** The resolved value changes with the root;
the role does not.

**Check `Used by` before changing anything.** Space is the most widely consumed
token family in the system, and it is arithmetically coupled to
[radius](../shape/radius-scale.mdx) through the nesting rule. Changing a padding
changes a corner.

**Notice which rows are absolute.** The two floors are deliberately not derived.
If you are theming density and a floor moved with it, something is wrong: a
product cannot make its own touch targets smaller by choosing a tighter density.

**Read the thresholds as container widths.** They are not device sizes and not
viewport breakpoints. A component in a 300-point pane on a 1600-point display is
in `compact`, and the table is describing the pane.

## Tokens [#tokens]

<TokenTable scope="space" />

<SpaceSpecimen step="section" />

## Accessibility impact [#accessibility-impact]

* **Publishing the floors as tokens is what makes them auditable.** A target
  minimum that lives in one component's stylesheet cannot be checked; one that
  lives in a generated table can be, and a regression against it fails the build.
* **The mode thresholds are the reflow contract.** SC 1.4.10 is tested at 320 CSS
  pixels, which is inside `compact`; publishing the threshold makes it possible to
  say exactly which layout a reader at 400% zoom gets.
* **Derived spacing scales with text; absolute floors do not need to.** Both
  behaviours are correct and the table distinguishes them, which is the only way
  a reviewer can tell a bug from a decision.
* **The table is a real table**, with a header row and navigable cells, as every
  generated table on this site is.

## Related [#related]

* [Spacing scale](./spacing-scale.mdx) says what each role is for.
* [Density and touch](./density-and-touch.mdx) covers where the two absolute
  floors come from and how they are measured.
* [Reference → Tokens](../../reference/generated/tokens.mdx) has the same rows
  alongside every other family.
