Skip to content

Foundations

The content-level primitives: section tones, containers, editorial type, prose blocks, flow rhythm, and the small set of utility classes. For tokens see Theming; for structural primitives see Layouts.

Sections

cui-section applies fluid block padding. The default is comfortable; the data-spacing attribute (or the cui-section-* modifier classes) tightens or opens it up. Tones are class modifiers that set background and foreground.

See Theming → Section spacing for the live spacing demo.

Tones

Muted

.cui-section-muted — subdued surface for breaks between primary sections.

Inverse

.cui-section-inverse — full-bleed dark band for promos and footers.

Accent

.cui-section-accent — branded surface, on-accent foreground.

Modifier Effect
data-spacing="compact" / .cui-section-compact Tight block padding
data-spacing="spacious" / .cui-section-spacious Open block padding
data-spacing="hero" / .cui-section-hero Hero-scale block padding
.cui-section-muted Surface-muted background
.cui-section-inverse Inverse surface (dark in light, light in dark)
.cui-section-accent Accent surface with on-accent foreground

Containers

cui-container centers its child with horizontal gutters. Three width modifiers map to the three container tokens. Drop one inside any cui-section.

.cui-container-narrow · 48rem
.cui-container · 72rem (default)
.cui-container-wide · 96rem

For non-section page wrappers (e.g. an app shell page), see Layouts → Page wrappers.

Editorial type

Single-purpose typographic classes. Each one binds a specific role to the right token combination so you don't have to repeat the recipe.

Eyebrow

A display-scale headline.

.cui-display — fluid display size, display weight, balanced wrap.

Lead text introduces a section with extra inline-size and weight. Pair it with a smaller body paragraph below.

.cui-lead — 1.5rem fluid, muted color, capped at 68ch.

Eyebrow / kicker

.cui-eyebrow and .cui-kicker are aliases — small accent label, uppercase, tracked.

Caption — small muted note that sits next to or under primary content.

  • 5 min read
  • March 2026
  • Engineering

.cui-meta — the row form of .cui-metadata: a wrapping list of facts with · separators and list reset baked in. One class replaces the old per-block *-meta rows.

Class Tokens
.cui-display --cui-font-size-display, --cui-font-weight-display, --cui-line-height-display
.cui-lead --cui-font-size-2, --cui-color-muted, --cui-content-measure
.cui-eyebrow / .cui-kicker --cui-color-accent, --cui-font-size-eyebrow, --cui-font-weight-strong
.cui-caption --cui-font-size-caption, --cui-color-muted
.cui-metadata --cui-font-size-metadata, --cui-font-weight-strong, --cui-color-muted

Composing the type primitives

Blocks compose .cui-display and .cui-lead rather than redeclaring their own headline classes — a card title is a .cui-display, a section intro a .cui-lead. Each primitive exposes override vars so a block can retune it in place: --cui-display-size / -weight / -leading / -tracking / -measure on .cui-display, and --cui-lead-size / -leading / -measure on .cui-lead.

Watch the measure. The primitive defaults are hero-scaled: .cui-display ships a 13ch max measure (so a marketing hero wraps to a few punchy lines) and .cui-lead caps at 68ch. Dropped into a card or a section heading, a bare primitive wraps too early or oversizes. So when a block composes a type primitive outside a hero, the contextual retune — almost always --cui-display-measure: none plus a smaller --cui-display-size — is mandatory, not optional polish.

Prose & flow

cui-prose styles long-form mixed HTML — headings, paragraphs, lists, blockquotes — with consistent rhythm and a comfortable measure. cui-flow applies the same rhythm via margin so you can drop it on a wrapper that already has children.

Prose

Section heading

cui-prose caps the inline-size at --cui-prose-measure (72ch) and applies a reading-friendly font size and rhythm to direct children.

Subheading

Headings get tight line-height and balanced wrapping; paragraphs get muted body color so headings retain emphasis.

  • Lists inherit the same muted body color.
  • Spacing is consistent with the body rhythm.

Flow

Block one

Children are spaced with --cui-flow-space via margin, not gap — useful when wrappers like CMS regions can't control their direct children.

Each successive child gets margin-block-start applied automatically.

Utilities

A small set of single-purpose helpers. They're intentionally narrow — for layout reach for a primitive, for tone reach for a section modifier.

Class Effect
.cui-text-muted Apply --cui-color-muted to text.
.cui-text-balance Set text-wrap: balance for short headings.
.cui-visually-hidden Visually hide content while keeping it accessible to screen readers.
.cui-full-bleed Break a child out of its container to span the viewport.
.cui-size-sm / .cui-size-lg Shorthand for --cui-control-scale: 0.88 / 1.16.
.cui-density-compact / .cui-density-comfortable Shorthand for --cui-density: 0 / 1.25.

Responsive visibility

Hide an element at a breakpoint and below (.cui-hidden-{bp}) or at a breakpoint and above (.cui-hidden-{bp}-up). The named breakpoints are the width thresholds where each size begins: xs 36rem, sm 48rem, md 64rem, lg 80rem. The -up form is min-width; the plain form is the complementary max-width side, so .cui-hidden-sm and .cui-hidden-sm-up are exact opposites split at 48rem.

Class Hidden when
.cui-hidden-xs / .cui-hidden-xs-up width < 36rem / width ≥ 36rem
.cui-hidden-sm / .cui-hidden-sm-up width < 48rem / width ≥ 48rem
.cui-hidden-md / .cui-hidden-md-up width < 64rem / width ≥ 64rem
.cui-hidden-lg / .cui-hidden-lg-up width < 80rem / width ≥ 80rem

Hiding from screen readers

These utilities toggle visual visibility only (display: none). CSS cannot hide an element from screen readers alone — display: none and visibility: hidden remove it from everyone, and nothing in CSS drops an element from the accessibility tree while leaving it painted. To render a second, visual-only copy of a nav (for layout convenience) without announcing it twice, reach for HTML attributes: use inert on the duplicate — it removes the subtree from the accessibility tree and takes its links out of the tab order — or aria-hidden="true" for a non-interactive duplicate.