Surface

Runtime-accurate recipes for composing page, base, raised, overlay, and modal surfaces from SquareKit background, border, radius, and shadow utilities.

A surface is a composition

runtime recipes

The current runtime does not expose a separate surface.* token namespace. A surface role is composed from the semantic background, border, radius, and elevation utilities that current components already use.

Channel
Current utilities
What it communicates
Backgroundbg-primary / bg-secondaryFigure and ground, plus the base contrast between containers.
Borderring-secondary / ring-secondary_altEdge definition where background contrast is not enough.
Elevationshadow-xs / shadow-lg / shadow-xlWhether a surface rests inline, responds, floats, or blocks.
Shaperounded-lg / rounded-xl / rounded-2xlComponent-specific shape. The surface role does not choose it.

Surface roles

5 recipes

Choose the role by behavior, then use the current utility recipe as a starting point. The examples render from semantic utilities and adapt under the page theme.

Page

The canvas behind product content. Flat, with no shadow.

Base

Cards, panels, and inline containers. Contrast and a hairline carry the separation.

Raised

A subtle response to hover, selection, or a small lifted control.

Overlay

Dropdowns, popovers, and menus that float above active content.

Modal

Dialogs and drawers that block the current task, paired with the semantic overlay backdrop.

Compose by role

Surface and elevation work together, but they are not interchangeable. Most hierarchy should be legible before a shadow is added.

  • Start with figure and ground: bg-primary on bg-secondary often provides enough separation for a base container.
  • Reserve stronger shadows for transient overlays and blocking modals. A regular card should not look like a dialog.
  • Keep status and interaction state separate from depth. Error, warning, hover, and selected colors can layer onto the same surface role.
  • Avoid stacking several floating surfaces. Overlay inside overlay inside modal usually signals a composition problem, not a need for a larger shadow.
  • Let semantic backgrounds and borders adapt in dark mode. Shadows naturally recede there, so edge and surface contrast do more of the work.

Component evidence

Current SquareKit components follow these recipes: dropdown menus use a primary background with a semantic ring and shadow-lg; modal panels use a primary background with shadow-xl over bg-overlay/70.