Tokens & Utilities
Backpack ships with a Radix-inspired token system defined under app/assets/stylesheets/tokens. Import app/assets/stylesheets/application.css (or cherry-pick the token files you need) to make everything below available app-wide. Each section features a value table for every token file plus a short usage snippet.
Color System (tokens/_colors.css)
- Import Radix scales – keep only the palettes you really use.
- Paste your custom accent scale – grab it from Radix Colors / Custom and drop it into the
:root, .light, .light-themeblock (the repo ships with placeholder--example-*values). - Map the accent – alias the shades to
--accent-*variables so components can stay palette-agnostic.
| Token | Description | Default |
|---|---|---|
--white |
Plain white | #fff |
--black |
Plain black | #000 |
--accent-1 → --accent-12 |
Accent ramp (background → text) | var(--example-1) → var(--example-12) |
--accent-a1 → --accent-a12 |
Accent alpha ramp | var(--example-a1) → var(--example-a12) |
--accent-contrast |
Text color for accent backgrounds | #fff |
--accent-surface |
Subtle accent surface | var(--example-surface) |
--accent-indicator / --accent-track |
Decorative helpers | From palette |
Example:
.CallToAction { background: var(--accent-9); color: var(--accent-contrast); border-color: var(--accent-11);}.CallToAction[data-accent-color='red'] { box-shadow: 0 0 0 1px var(--accent-indicator);}Spacing Scale (tokens/_spacing.css)
--space-base is the atomic unit; the remaining tokens are multiples of it.
| Token | Value |
|---|---|
--space-base |
0.2rem |
--space-1 |
0.2rem |
--space-2 |
0.4rem |
--space-3 |
0.6rem |
--space-4 |
0.8rem |
--space-5 |
1.2rem |
--space-6 |
1.6rem |
--space-7 |
2.4rem |
--space-8 |
3.2rem |
--space-9 |
4.8rem |
--space-10 |
6.4rem |
.Card { padding: var(--space-6); gap: var(--space-4);}Typography (tokens/_typography.css)
Font families
| Type | Token | Default |
|---|---|---|
| System fallback | --font-system |
system-ui, "Arial", "Helvetica", sans-serif |
| Body | --font-body |
Proxima Nova |
| Headings | --font-headings |
Roc Grotesk |
Font weights
| Weight | Token | Default value |
|---|---|---|
| Light | --light |
300 |
| Regular | --regular |
400 |
| Medium | --medium |
500 |
| Semibold | --semibold |
600 |
| Bold | --bold |
700 |
Font sizes
| Token | Size |
|---|---|
--font-base |
1.6rem |
--font-1 |
1.2rem |
--font-2 |
1.4rem |
--font-3 |
1.6rem |
--font-4 |
1.8rem |
--font-5 |
2rem |
--font-6 |
2.4rem |
--font-7 |
2.8rem |
--font-8 |
3.5rem |
--font-9 |
6rem |
Line heights
| Token | Size |
|---|---|
--height-1 |
1.6rem |
--height-2 |
2rem |
--height-3 |
2.4rem |
--height-4 |
2.6rem |
--height-5 |
2.8rem |
--height-6 |
3rem |
--height-7 |
3.6rem |
--height-8 |
4rem |
--height-9 |
6rem |
.Heading-2 { font-family: var(--font-headings); font-size: var(--font-6); line-height: var(--height-7); font-weight: var(--bold);}Radius Tokens (tokens/_radius.css)
| Token | Value |
|---|---|
--radius-1 |
0.2rem |
--radius-2 |
0.4rem |
--radius-3 |
0.6rem |
--radius-4 |
0.8rem |
--radius-5 |
1.2rem |
--radius-6 |
1.6rem |
--radius-7 |
2.4rem |
--radius-full |
999.9rem |
.Tag { border-radius: var(--radius-4);}Layout & Breakpoints (tokens/_layout.css)
| Token | Value |
|---|---|
--breakpoint-xs |
0px |
--breakpoint-sm |
576px |
--breakpoint-md |
768px |
--breakpoint-lg |
992px |
--breakpoint-xl |
1248px |
--breakpoint-xxl |
1640px |
--container-width |
128rem |
Custom properties can't be used in media queries, so tokens/_media_queries.css defines a custom media query for each breakpoint (compiled by postcss-preset-env): --sm-up → --xxl-up match from the breakpoint (width >= 576px…), --sm-down → --xxl-down match below it (width < 576px…). backpack sync keeps their values in line with the breakpoint tokens. The file only holds @custom-media rules (no CSS output): import it at the top of any stylesheet compiled on its own, like component stylesheets.
@media (--lg-up) { .Page { max-width: var(--container-width); margin-inline: auto; }}Focus Tokens & Utilities (tokens/_focus.css, utilities/_focus.css)
| Token | Value |
|---|---|
--outline-focus |
0.2rem solid var(--accent) |
--outline-offset-focus |
0.3rem |
utilities/_focus.css applies those tokens to every focusable element via :focus-visible so you instantly get WCAG-friendly focus outlines.
.Button:focus-visible { outline: var(--outline-focus); outline-offset: var(--outline-offset-focus);}Screen Reader Utility (utilities/_sr-only.css)
The .sr-only class hides content visually while keeping it available to assistive tech.
If the element needs to be focusable, use .sr-only-focusable instead.
<button class="IconButton"> <svg aria-hidden="true">…</svg> <span class="sr-only">Open menu</span></button>Putting It Together
Components inherit the full token set automatically—application.css imports every token and utility file. To customise the system:
- Edit the token files (they’re plain CSS, no build step required).
- Consume variables instead of hard-coding values.
- Reuse the utilities (
.sr-only, focus styles) to keep accessibility consistent.
Radix Themes style, Backpack flavour: adjust the tokens once and every component follows.