Layout
Spacing
Section titled “Spacing”Spacing follows a 4px step scale (--p-space-N). Use the semantic aliases in your own code. They name the intent, so you can retune the rhythm in one place.
Semantic spacing
Section titled “Semantic spacing”| Token | Value | Preview |
|---|---|---|
--s-space-2xs | 0.25rem | |
--s-space-xs | 0.5rem | |
--s-space-sm | 0.75rem | |
--s-space-md | 1rem | |
--s-space-lg | 1.5rem | |
--s-space-xl | 2rem | |
--s-space-inset | 1rem | |
--s-space-stack-sm | 0.5rem | |
--s-space-stack-md | 1rem | |
--s-space-stack-lg | 2rem | |
--s-space-inline-sm | 0.5rem | |
--s-space-inline-md | 1rem |
| Token | Use |
|---|---|
--s-space-2xs |
Hairline gaps, icon nudges |
--s-space-xs |
Tight gaps |
--s-space-sm |
Control padding, gaps |
--s-space-md |
Default gap and padding |
--s-space-lg |
Section padding |
--s-space-xl |
Large separation |
--s-space-inset |
Container padding |
--s-space-stack-sm, -md, -lg |
Vertical rhythm |
--s-space-inline-sm, -md |
Horizontal gaps |
Primitive scale
Section titled “Primitive scale”For reference. The scale steps are 0, 4, 8, 12, 16, 20, 24, 32, 40, 48 and 64px, named by step number (1 to 16).
| Token | Value | Preview |
|---|---|---|
--p-space-0 | 0 | |
--p-space-1 | 0.25rem | |
--p-space-2 | 0.5rem | |
--p-space-3 | 0.75rem | |
--p-space-4 | 1rem | |
--p-space-5 | 1.25rem | |
--p-space-6 | 1.5rem | |
--p-space-8 | 2rem | |
--p-space-10 | 2.5rem | |
--p-space-12 | 3rem | |
--p-space-16 | 4rem |
For layout, prefer the layout components over hand-written CSS: Stack, Grid and Container.
ITCSS layers
Section titled “ITCSS layers”The global stylesheet (packages/ui/src/styles/global.css) imports its layers in order of increasing specificity:
- Settings (
settings/tokens.css): the only place--p-*tokens are defined and--s-*tokens are mapped. - Trumps (
trumps/utilities.css): theu-*helper classes. This is the only layer where!importantis tolerated. See CSS utilities. - Components: each component’s CSS lives beside it (
src/components/holo-*/holo-*.css), scoped by Shadow DOM with:hostand flat class selectors.
Add a new global concern to the matching layer. Do not put tokens in component files or component rules in the utilities.
Container queries
Section titled “Container queries”Components respond to the size of their container, not the viewport. Declare container-type: inline-size on a wrapper and query it with @container.
Reserve @media for user-preference queries such as prefers-reduced-motion and forced-colors. Colour scheme is handled by light-dark() in the tokens.
Drag the bottom-right corner of the frame. Below 28rem the items stack, above it they sit in a row.
.frame { container-type: inline-size;}
.items { display: grid; gap: var(--s-space-sm);}
@container (min-width: 28rem) { .items { grid-template-columns: repeat(3, 1fr); }}The container cannot style itself from its own query, so put the responding rules on a child, as above.
Z-index scale
Section titled “Z-index scale”Use only these layers. Do not invent values.
| Token | Value | Preview |
|---|---|---|
--s-z-index-dropdown | 100 | layer 100 |
--s-z-index-sticky | 200 | layer 200 |
--s-z-index-overlay | 300 | layer 300 |
--s-z-index-modal | 400 | layer 400 |
--s-z-index-popover | 500 | layer 500 |
| Token | Value | Use |
|---|---|---|
--s-z-index-dropdown |
100 | Dropdowns |
--s-z-index-sticky |
200 | Sticky headers |
--s-z-index-overlay |
300 | Overlays |
--s-z-index-modal |
400 | Modals |
--s-z-index-popover |
500 | Popovers, above everything |
The primitives also define --p-z-index-under (-1) and --p-z-index-normal (1). Prefer top-layer features (<dialog>.showModal() and the popover attribute) over z-index where you can.