Utilities
Utilities overview
Utilities are small, single-purpose classes that map directly to a design token. Use utilities to adjust defaults. Use components and layouts as the primary building blocks.
Usage
Utilities reduce repetitive inline styles and project CSS. Instead of writing style="--gap: var(--space-l)", write class="gap-l". Instead of opening a project CSS file to set one padding value, use p-m.
Every utility is bounded to a token. There is no gap-37px. For an arbitrary one-off value, use style="--var: ...". For a repeated pattern, define a project class in @layer project and name it by intent.
As a guideline, consider defining a project class when an element needs four or more utilities.
Spacing
Spacing utilities draw from the --space-* scale: 3xs, 2xs, xs, s, m, l, xl, 2xl, 3xl. Margin and padding utilities support every size in the scale and a -0 reset.
Gap utilities apply to any flex or grid container, including all layout primitives:
.gap-0 { gap: 0 }
.gap-3xs { gap: var(--space-3xs) }
.gap-2xs { gap: var(--space-2xs) }
.gap-xs { gap: var(--space-xs) }
.gap-s { gap: var(--space-s) }
.gap-m { gap: var(--space-m) }
.gap-l { gap: var(--space-l) }
.gap-xl { gap: var(--space-xl) }
.gap-2xl { gap: var(--space-2xl) }
.gap-3xl { gap: var(--space-3xl) }
Margin utilities cover all sides, the inline axis, and the block axis:
.m-s { margin: var(--space-s) }
.mx-l { margin-inline: var(--space-l) }
.my-xs { margin-block: var(--space-xs) }
.mx-auto { margin-inline: auto }
Padding follows the same pattern:
.p-m { padding: var(--space-m) }
.px-s { padding-inline: var(--space-s) }
.py-l { padding-block: var(--space-l) }
Color
Use surface background utilities for neutral surfaces:
Use semantic background utilities for tinted blocks. Each utility maps to a subtle *-fill color:
Text color utilities map to readable *-text variants:
Typography
Use typography utilities to apply the available text-size and font-weight tokens:
.size-h1 { font-size: var(--size-h1) }
.size-h2 { font-size: var(--size-h2) }
.size-h3 { font-size: var(--size-h3) }
.size-h4 { font-size: var(--size-h4) }
.size-body { font-size: var(--size-body) }
.size-small { font-size: var(--size-small) }
.size-tiny { font-size: var(--size-tiny) }
.weight-normal { font-weight: var(--font-weight) }
.weight-bold { font-weight: var(--font-weight-bold) }
Borders and radius
Borders share --border-width and one of the role colors:
.border-none { border: none }
.border-weak { border: var(--border-width) solid var(--color-border-weak) }
.border-strong { border: var(--border-width) solid var(--color-border-strong) }
Border radius covers the full scale:
.radius-0 { border-radius: 0 }
.radius-s { border-radius: var(--border-radius-s) }
.radius-m { border-radius: var(--border-radius-m) }
.radius-l { border-radius: var(--border-radius-l) }
.radius-f { border-radius: var(--border-radius-f) }
.rounded { border-radius: var(--border-radius-f) }
Shadow
Use shadow utilities to apply the predefined elevation levels:
.shadow-none { box-shadow: none }
.shadow-s { border-bottom: var(--border-width) solid color-mix(in oklab, var(--border-color, var(--color-border-weak)), var(--shadow-small)) }
.shadow-m { box-shadow: var(--shadow-medium) }
.shadow-l { box-shadow: var(--shadow-large) }
.shadow-inner { box-shadow: var(--shadow-inner) }
Flow space
Override vertical rhythm in .flow, .card, or classless main, article, and section containers:
.flow-glue > * + * { margin-block-start: var(--flow-space-glue) }
.flow-tight > * + * { margin-block-start: var(--flow-space-tight) }
.flow-loose > * + * { margin-block-start: var(--flow-space-loose) }
.flow-none > * + * { margin-block-start: 0 }
Sizing
Use full-width to fill the container's inline size. This utility is useful for tables, figures, inline-block elements, and flex or grid children:
.full-width { inline-size: 100% }
Use full-height to fill the dynamic viewport height. Apply it to hero sections, splash sections, full-screen drawers, or as the opt-in trigger for a full-height side menu:
.full-height { block-size: 100dvh }
Overflow
Use overflow-x or overflow-y to make overflowing content scroll on one axis. For example, wrap a wide table with overflow-x to preserve the table's display: table behavior:
.overflow-x { overflow-x: auto }
.overflow-y { overflow-y: auto }
<div class="overflow-x">
<table>...</table>
</div>