Semantic Spacing and Layout Rhythm Tokens (CEM × M3)

Status: Canonical (D1 v1.0)

Last updated: August 10, 2026

Audience: Design Systems, Product Design, Front-End Engineering

Taxonomy placement: D1. Space & Rhythm (part of the 7-dimensional CEM token framework)

Companion specs:


Table of Contents

  1. Scope
  2. CEM alignment principles applied to spacing
  3. Token model
  4. Relation to Dimensional Tokens
  5. Reference spacing scale (semantic)
  6. Consumer-semantic spacing taxonomy
  7. Layout rhythm tokens (compositional semantics)
  8. Spacing modes knob (dense / normal / sparse)
  9. Mapping notes: M3 ↔ CEM
  10. Quick adoption checklist

Appendices


1. Scope

This document defines a consumer-semantic spacing and layout rhythm token set that:

This document is D1 (Space & Rhythm). It intentionally does not define interactive minimums; it consumes D2 coupling minimums as hard constraints.


2. CEM alignment principles applied to spacing

2.1 Semantic intent first

Developers should apply tokens like:

…and not value-centric names like space-16 in component code.

2.2 Bounded variation

A small set of distinct, repeatable space steps should cover most UI. Extended values exist but are intentionally "rare".

2.3 Accessibility and operability by construction

Spacing must preserve:


3. Token model

We use three layers:

  1. Reference scale tokens (M3-aligned numeric steps; safe to map to dp/px)
  2. System/semantic tokens (consumer-intent endpoints; what teams apply)
  3. Component mapping (component-specific tokens map to semantic tokens; typically owned in component adapters)

4. Relation to Dimensional Tokens

4.1 Dimensional Tokens: where spacing lives

In CEM, spacing/rhythm is not "just layout." It is a primary subset of Dimensional Tokens (the physical layer: size, distance, bend, stroke, depth).

Use this legend-level dimensional taxonomy to keep token categories coherent:

4.2 Governance rules (cross-category contracts)

These rules prevent spacing changes from degrading operability, accessibility, or visual hierarchy:

  1. Spacing modes are a D1 adjustment; never a D2 coupling regression
  1. Normative layout contract for interactive adjacency

When spacing occurs between two interactive affordances, layout must respect D2 guard:

/* If the gap separates adjacent interactive affordances: */
.cem-gap-interactive {
    gap: max(var(--cem-gap-related), var(--cem-coupling-guard-min));
}
  1. When D1 can't grow, D5 may need to compensate
  1. Elevated/prominent surfaces "earn" breathing room
  1. Bend and inset should harmonize (D1 × D3)
  1. Reading cadence is jointly governed by typography + spacing

5. Reference spacing scale (semantic)

The spacing scale uses semantic size names rather than pixel values, making intent clear while preserving M3 rhythm (4dp increments).

5.1 Primary dimension scale (semantic.css)

Eight steps covering common UI needs:

cem-dim-scale
TokenValueDescriptiontier
--cem-dim-xx-small0.25rem4px — micro gaps, icon paddingrequired
--cem-dim-x-small0.5rem8px — related item gaps, control insetsrequired
--cem-dim-small0.75rem12px — group gaps, inline rhythmrequired
--cem-dim-medium1rem16px — block gaps, container insetsrequired
--cem-dim-large1.5rem24px — section gaps, surface insetsrequired
--cem-dim-x-large2rem32px — page gaps, wide guttersrequired
--cem-dim-xx-large4rem64px — extended layout, hero spacingrequired
--cem-dim-xxx-large8rem128px — maximum breathing roomrequired

Cross-reference: These tokens are consumed by D3 Shape (cem-shape.md) for bend values:

5.2 Mapping to M3 rhythm

Semantic tokenValueM3 dp equivalentTypical use
--cem-dim-xx-small0.25rem4dpMicro gaps, tight padding
--cem-dim-x-small0.5rem8dpRelated items, control insets
--cem-dim-small0.75rem12dpGroup gaps, inline spacing
--cem-dim-medium1rem16dpBlock gaps, container insets
--cem-dim-large1.5rem24dpSection gaps, surface padding
--cem-dim-x-large2rem32dpPage gaps, wide gutters
--cem-dim-xx-large4rem64dpExtended layout spacing
--cem-dim-xxx-large8rem128dpMaximum layout spacing

6. Consumer-semantic spacing taxonomy

The taxonomy is organized by what the space means to the user.

6.1 Relationship gaps (between items)

Use when arranging siblings.

cem-dim-gaps
TokenValueDescriptiontier
--cem-gap-relatedvar(--cem-dim-x-small)Siblings in the same unit (8px)recommended
--cem-gap-groupvar(--cem-dim-small)Items in the same group, distinct (12px)recommended
--cem-gap-blockvar(--cem-dim-medium)Between groups/blocks inside one surface (16px)recommended
--cem-gap-sectionvar(--cem-dim-large)Between major sections (24px)recommended
--cem-gap-pagevar(--cem-dim-x-large)Between page-level regions (32px)recommended

Guideline: if users perceive two things as "one unit," use gap-related. If they perceive "these are separate things," move up to gap-group or gap-block.

Important: for interactive adjacency, apply the D2 guard contract (gap = max(D1 gap, D2 guard)).

6.2 Insets (inside a surface)

Use when padding content within a container.

cem-dim-insets
TokenValueDescriptiontier
--cem-inset-controlvar(--cem-dim-x-small)Smallest safe inset for tight controls (8px)recommended
--cem-inset-containervar(--cem-dim-medium)Default inset for common containers (16px)recommended
--cem-inset-surfacevar(--cem-dim-large)Comfortable inset for reading surfaces and prominent cards (24px)recommended

Cross-reference: When combining insets with bend (D3), ensure inset is large enough to prevent content crowding in rounded corners. See cem-shape.md §8.5 for guidance.

6.3 Coupling and interaction safety (D2 cross-reference)

These tokens are defined and governed in D2 (cem-coupling.md). They are listed here as a * normative constraint* because they bound how far D1 spacing modes can compress interactive adjacency. Do not set or tune these in D1; treat them as sourced from the D2 theme.

:root {
    /* Minimum distancing between adjacent operable zones (prevents interference). */
    --cem-coupling-guard-min: 0.5rem; /* nominally 8px */

    /* Minimum operable zone (layout-level). Keep invariant across modes. */
    --cem-coupling-zone-min: 3rem; /* nominally 48px @ 16px root */

    /* Invisible expansion beyond visuals (halo). */
    --cem-coupling-halo: 0.25rem; /* nominally 4px */

    /* Legacy aliases (deprecated): keep only while migrating older code */
    --cem-touch-separation-min: var(--cem-coupling-guard-min);
    --cem-touch-target-min: var(--cem-coupling-zone-min);
}

Interpretation (summary):

6.4 Reading rhythm (vertical cadence for prose)

This is distinct from UI rhythm.

cem-dim-rhythm-reading
TokenValueDescriptiontier
--cem-rhythm-reading-paragraph0.75emDefault paragraph spacing for proserecommended
--cem-rhythm-reading-sectionvar(--cem-dim-large)Space between reading sections within one surface (24px)recommended

Cross-reference: Reading rhythm must be validated against typography tokens. See cem-voice-fonts-typography.md.

6.5 Data/scan rhythm (dense but legible)

Optimized for scan/compare flows (tables, metrics).

cem-dim-rhythm-data
TokenValueDescriptiontier
--cem-rhythm-data-rowvar(--cem-dim-x-small)Table-like, scan-first row padding (8px)recommended
--cem-rhythm-data-groupvar(--cem-dim-medium)Scan grouping — subtotals, row groups, metric clusters (16px)recommended

7. Layout rhythm tokens (compositional semantics)

These describe layout structures without baking in specific components.

7.1 Stack rhythm (vertical composition)

Default vertical stack gap for general UI stacks. Optional tight/loose variants for systems that need explicit range.

7.2 Cluster rhythm (horizontal groups)

Default cluster gap for inline groups (icons + text, toolbars, button clusters). The legacy --cem-layout-inline-* aliases are deprecated — use --cem-gap-* instead.

7.3 Page gutters (responsive breathing room)

These are responsive and should be treated as semantics, not fixed numbers.

7.4 Layout token table

cem-dim-layout
TokenValueDescriptiontier
--cem-layout-stack-gapvar(--cem-gap-block)Default vertical stack gap for general UI stacksrequired
--cem-layout-cluster-gapvar(--cem-gap-related)Default cluster gap for inline groupsrequired
--cem-layout-guttervar(--cem-dim-medium)Default content gutter (16px)required
--cem-layout-gutter-widevar(--cem-dim-x-large)Wide-screen gutter (32px)recommended
--cem-layout-gutter-maxvar(--cem-dim-xx-large)Maximum gutter (64px)recommended
--cem-layout-stack-tightvar(--cem-gap-related)Tight stack variant — rare, use only when explicitly tighter than defaultoptional
--cem-layout-stack-loosevar(--cem-gap-section)Loose stack variant — rare, use only when explicitly looser than defaultoptional
--cem-layout-inline-tightvar(--cem-dim-x-small)Deprecated — use --cem-gap-relateddeprecated
--cem-layout-inlinevar(--cem-dim-small)Deprecated — use --cem-gap-groupdeprecated
--cem-layout-inline-loosevar(--cem-dim-medium)Deprecated — use --cem-gap-blockdeprecated

8. Spacing modes knob (dense / normal / sparse)

Material often frames this as "density." In CEM, treat this explicitly as a D1 spacing mode that shifts Space & Rhythm while preserving D2 coupling invariants.

:root {
    /* dense | normal | sparse */
    --cem-layout-spacing: normal;
}

8.1 Adjustment policy

Mode intent summary:

D1 spacing modePrimary goalWhat changesWhat must not change
denseIncrease information densityStep down gaps/insets/gutters ~1 step where safeD2 coupling invariants (zone/guard), and any gap that separates interactive affordances must still satisfy gap = max(D1 gap, D2 guard)
normalBaselineUse canonical endpoints as definedSame invariants
sparseIncrease calm/readabilityStep up gaps/insets/gutters ~1 stepSame invariants

Hard constraints (never override):

normal mode uses the baseline values defined in §6–7. dense steps gaps down ~1 scale step; sparse steps them up ~1 step. Tokens not in this table are unaffected by spacing mode.

cem-dim-spacing-overrides
Tokendensesparse
--cem-gap-relatedvar(--cem-dim-x-small)var(--cem-dim-small)
--cem-gap-groupvar(--cem-dim-x-small)var(--cem-dim-medium)
--cem-gap-blockvar(--cem-dim-small)var(--cem-dim-large)
--cem-gap-sectionvar(--cem-dim-medium)var(--cem-dim-x-large)
--cem-gap-pagevar(--cem-dim-large)var(--cem-dim-xx-large)
--cem-inset-controlvar(--cem-dim-x-small)var(--cem-dim-small)
--cem-inset-containervar(--cem-dim-small)var(--cem-dim-large)
--cem-inset-surfacevar(--cem-dim-medium)var(--cem-dim-x-large)
--cem-layout-guttervar(--cem-dim-small)var(--cem-dim-large)
--cem-layout-gutter-widevar(--cem-dim-large)var(--cem-dim-xx-large)
--cem-layout-gutter-maxvar(--cem-dim-x-large)var(--cem-dim-xxx-large)
--cem-rhythm-reading-paragraph0.6em1em
--cem-rhythm-reading-sectionvar(--cem-dim-medium)var(--cem-dim-x-large)
--cem-rhythm-data-rowvar(--cem-dim-xx-small)var(--cem-dim-small)
--cem-rhythm-data-groupvar(--cem-dim-small)var(--cem-dim-large)

8.3 Notes on component mapping

8.4 Layout mapping checklist (how to apply)

Use these patterns so teams can implement screens without inventing spacing semantics.

Stacks (vertical composition)

Clusters (horizontal composition)

Cards / panels / surfaces

Sections and page regions

Gutters (responsive framing)

Reading and data cadence


9. Mapping notes: M3 ↔ CEM

9.1 Where this matches Material 3

9.2 Where this differs (intentionally)


10. Quick adoption checklist

  1. Use the dimension scale (--cem-dim-*) as the foundation.
  2. Map semantic endpoints (gap-*, inset-*, rhythm-*) to dimension tokens.
  3. Treat D2 coupling (zone/guard/halo) as hard constraints for interactive adjacency — see cem-coupling.md.
  4. Update component tokens to use semantic endpoints.
  5. Add optional data-cem-spacing="dense|normal|sparse" only if product needs spacing modes.
  6. Validate on representative surfaces:
  7. Validate bend-inset harmony on rounded surfaces — see cem-shape.md §8.5.

Appendix A. D2 Coupling Mode Matrix (excerpt)

This excerpt is provided for convenience when working in D1. The canonical safety definitions and governance live in D2. Coupling & Compactness (cem-coupling.md); visual geometry values live in D2c. Controls (cem-controls.md).

Coupling modeProduct intentD2c Controls visual geometry trendD2 halo (--cem-coupling-halo) trendTypical surfaces
forgivingMinimize mis-coupling for imprecise inputLarger controls/rows; more internal paddingSmaller (visuals already meet zone)mobile-first, kiosks, accessibility-first, gaze/dwell
balancedDefault across modalitiesBaseline control heights/rowsBaselinemixed pointer + touch, general app UI
compactIncrease information density without breaking operabilitySmaller visuals; reduced chromeLarger (use halo to preserve zone)data grids, admin tools, scan-heavy panels

Normative invariants (do not override in D1):


Appendix B. Governance and versioning

This D1 spec is a contract. Changes must be intentional, reviewable, and versioned.

B.1 What counts as breaking

Treat as major (breaking) if you:

B.2 What is non-breaking

Treat as minor/patch if you:

B.3 Versioning guidance

B.4 Canonical cross-spec invariants

D1 is subordinate to D2 for operability. The following must hold in every release:


11. Acceptance criteria

Interactive-adjacency contract (non-normative for generator): any consumer using D1 gaps between interactive affordances must resolve the effective gap as:

gap:

max
(
var
(
--cem-gap-related

)
,
var
(
--cem-coupling-guard-min

)
)
;

The generator does not enforce this — it is component-author responsibility, documented in the manifest notes above.

Reading-rhythm validation is deferred to D6 cross-check (Phase 12 in the implementation plan). D1 cannot validate rhythm in isolation.

12. Token manifest index

Token tier is encoded in the tier column of each source table. The manifest validator derives expected token names from these tables using the same XPath pattern as cem-dimension.html.

Source table h6 idTokens coveredValidator derivation
cem-dim-scale--cem-dim-* (8 tokens)one token per row
cem-dim-gaps--cem-gap-* (5 tokens)one token per row
cem-dim-insets--cem-inset-* (3 tokens)one token per row
cem-dim-rhythm-reading--cem-rhythm-reading-* (2 tokens)one token per row
cem-dim-rhythm-data--cem-rhythm-data-* (2 tokens)one token per row
cem-dim-layout--cem-layout-* (10 tokens; deprecated tier omitted from default output)one token per row

Spacing mode overrides (cem-dim-spacing-overrides) produce no new token names — they override existing tokens within :root[data-cem-spacing="dense"] and :root[data-cem-spacing="sparse"] selectors.


References

Local CEM documentation

Decision: optional component dimensions and compact hit areas

Control size belongs to D2c Controls, while D2 Coupling owns operability and D1 owns layout spacing. Do not map control size="large" to the D1 spacing token --cem-dim-large.

The 3rem target is CEM policy, not a claim of automatic ADA conformance. At a 16px root it is 48 CSS pixels; consumers must assess actual computed dimensions.

Size roles and composition

Size expresses available space and prominence. Content type suggests useful examples, but does not select size automatically. Keep medium as the API spelling for an ordinary standalone action; normal is not an additional value.

ProfileTypical useMinimum visible height
OmittedContent-sized or container-sized action; inherits theme geometryInherited
smallInline action, table-row control, compact toolbar icon2.5rem
mediumStandalone text action, text with icon, ordinary icon action3rem
largeProminent confirmation or large playback control4rem
x-largeOne choice represented by an image and title6rem
xx-largeFeatured choice or CMS hero composition with one action8rem

An icon-only action can use any profile. Glyph size, content layout, intent, coupling and control height remain independent. The xx-large baseline continues the 4/6/8rem progression for large controls; it is a starting minimum, not a fixed hero height or a reuse of the D1 --cem-dim-xx-large spacing token. Images, wrapping text and responsive container layout determine the final size. Only requested geometry below the coupling minimum adds the transparent hit border. Medium and larger default profiles add none, including tiles and heroes. An overridden profile below that minimum still receives the safety inset.

Compose image/title content through the default slot using noninteractive phrasing content, such as spans, images and strong text. The action permits label wrapping; the author owns stacked or responsive layouts inside the projected content. Size never silently changes row/column layout, font scale or image size. Keep content readable under zoom and narrow containers rather than clipping it to a preset height. A small profile stretched by layout retains its reserved compact inset; this policy follows requested geometry, not DOM measurement.

Semantics follow behavior at every size: a command uses a native button and a destination uses a native link. The current cem-action owns a native button; the image and hero playground samples therefore choose content, not navigate. Adding native-link support is a separate component contract change. A card with an interactive preview or several actions keeps those controls separate; do not nest them inside one action. The legacy material demo-list-card follows this composition: the preview is a sibling of a title/description link with a 6rem minimum height.

This decision draws on Angular Material buttons, Material 3 Expressive button sizes, icon button sizes, and Angular Material card composition. Material offers size choices for both text and icon buttons; CEM retains its own theme scale and coupling minimum.