Spacing
1u = 8px. Use the layout grid to group content and a 4px half-step inside compact
components. Spacing is independent of rendered glyph widths.
Scale
| Token | Value | Utility | Usage |
|---|---|---|---|
--oprt-space-0-5 | 4px | 0.5u | Compact cell padding, badge indicator gaps |
--oprt-space-1 | 8px | 1u | Related controls, label padding |
--oprt-space-2 | 16px | 2u | Control groups, cell insets, compact panels |
--oprt-space-3 | 24px | 3u | Pattern sections, regular panel padding |
--oprt-space-4 | 32px | 4u | Larger section gaps |
--oprt-space-5 | 40px | 5u | Large section gaps |
--oprt-space-6 | 48px | 6u | Page-level spacing |
--oprt-space-8 | 64px | 8u | Major section breaks |
Utilities such as gap-1u, px-2u, and py-0.5u resolve to the CSS variables.
The 12px (1.5u) and 20px (2.5u) utilities size control indicators. 12u (96px), 16u
(128px), and 40u (320px) exist for a Select popover height, compact plots, and the
CommandPalette list.
Controls and labels
| Role | Small | Medium | Large |
|---|---|---|---|
| Interactive control height | 24px | 32px | 40px |
| Read-only badge height | 20px | 24px | — |
Control heights come from --oprt-height-sm, --oprt-height-md, and --oprt-height-lg.
In Tailwind they are h-oprt-sm, h-oprt-md, and h-oprt-lg, and the same keys work for
w-, min-h-, min-w-, max-h-, and max-w-. Use min-h-oprt-sm as a target floor on
content that can grow.
Small Button and Select controls use 11px type with a 16px line height. Badges use
8px inline padding and a 4px indicator gap. Their height comes from
--oprt-badge-height-sm and --oprt-badge-height-md.
Slider rails are 3px (--oprt-track-sm), 4px (--oprt-track-md), or 5px (--oprt-track-lg),
about a quarter of the matching thumb. They sit off the 8px grid on purpose: a rail is not
layout spacing.
For WCAG 2.5.8, check both target dimensions and spacing in the composed interface; 24px height alone does not establish conformance. Touch and glove use may require larger targets.
Table density
| Role | Compact (dense) | Standard |
|---|---|---|
| Minimum row height | 32px | 40px |
| Vertical padding per side | 4px | 8px |
| Horizontal cell inset | 16px | 16px |
The corresponding role tokens are --oprt-table-row-dense, --oprt-table-row,
--oprt-table-cell-block-dense, --oprt-table-cell-block, and
--oprt-table-cell-inline. Rows grow with their content. A 24px badge or control
needs at least 4px of clearance above and below it in a compact row.
Headers and values share their inset and alignment. Numeric and timestamp columns align right. A text action inside a cell should avoid adding a second horizontal inset. Explicit fixed-height virtualization clips content to its configured row height; choose that height for the content being rendered.
Borders and radius
--oprt-border-width is 1px and --oprt-border-radius is 0px. OPERATOR has no rounded
corners: the base stylesheet applies the radius token to every element, and in Tailwind every
rounded-* class, including rounded-full, resolves to 0px, so a stray class cannot soften a
control.
Container-relative layout
A component lays itself out from its own width, not the window's, so it works the same in a
sidebar, a split pane, and a full page. Mark the box to measure with @container, then style
its descendants with the container variants.
| Variant | Applies from a container width of |
|---|---|
@oprt-sm: | 320px |
@oprt-md: | 480px |
@oprt-lg: | 640px |
<div className="@container">
<div className="flex flex-col gap-2u @oprt-lg:flex-row">...</div>
</div>
- A container query styles descendants only. A variant on the same element as
@containermeasures that element's parent. @containersetscontainer-type: inline-size, so the box stops sizing to its content. Put it on a block wrapper that has a width of its own, not on a shrink-wrapped item.- The variants are emitted narrowest first, so
@oprt-md:overrides@oprt-sm:when both match. @oprt-lg(640px of container) is the closest equivalent of Tailwind's viewportsm:.- OPERATOR components follow their container, not the window, so the rule is to use the container
variants and not viewport variants (
sm:to2xl:). No component uses a viewport variant: the last six (AppShell, DateRangePicker, DateTimePicker, CoordinateInput, PropertyFilter, and TimeRange) were converted in Stage 1, and a source test keeps it that way.
Wrapping essential values
IDs, measurements, and timestamps wrap; they are never truncated. oprt-wrap-anywhere sets
overflow-wrap: anywhere. Unlike break-words it also shrinks min-content, so a long value
wraps inside a flex or grid item instead of widening it. Keep a number and its unit together.
Pattern composition
- Use 8px between related controls, such as sort field and sort direction.
- Use 16px between distinct control groups and for compact panel padding.
- Use 24px between major sections within a pattern.
- Prefer standard table density for status-rich inspection views: a 24px badge gets 8px of vertical clearance on each side. Reserve compact rows for views where the information volume calls for tighter spacing.
- Let the parent own the spacing between children. Avoid stacking a cell inset with a text button's inset or adding margins to every child.
- Check the composition with real labels, status badges, wrapping text, and a narrow viewport. A valid token value alone does not make a layout balanced.