Foundations

Radius & borders

Radii are named by role rather than by size, so a control cannot end up with a card's corners.

Radius

Three role tokens carry almost everything: --radius-control for chips and small controls, --radius-button for CTAs and inputs, and --radius-card for cards and panels. Reach for a role name, not a size.

--radius-controlChips, small controls
--radius-buttonButtons, inputs
--radius-cardCards, panels
--radius-fullPills and avatars

Borders

Border rules are pre-composed, so a hairline is one token rather than three declarations that can drift apart:

  • --border-default-rule — the standard hairline between surfaces
  • --border-subtle-rule — a quieter division inside a surface
  • --border-strong-rule — hover and emphasis
  • --border-focus-rule— the focused control's edge

Write border: var(--border-default-rule), not 1px solid var(--color-border-default).

Elevation

Cards are borderless and shadowless — they are separated from the page by surface lightness alone. Controls carry no resting shadow. Shadow is reserved for things that genuinely float above the page: Tooltip, DropdownMenu, Popover, Select content and Dialog.

Focus rings are also box-shadow. If you sweep shadows off a surface, do not take the focus ring with them.

Rebinding a radius

When a component draws an inner element from calc(<token> - inset)— a segmented control's pill, a tab indicator — rebind the token on the component rather than setting border-radius directly. Setting the property alone leaves the inner element derived from the old value and visibly nested wrong.

The same trap applies to height, and it has bitten here: a hardcoded height on both a padded track and its item put a 31px label in a 23px box, overhanging the track by 4px. When you re-scale a component that has an inner element, re-derive the inner value; never copy the outer one onto it.