Skip to main content

Surfaces

The background/elevation treatment everything else in the system sits on top of. Use to establish depth and visual hierarchy between page background, cards, and floating content. Don't use as a substitute for spacing or container tokens.

Figma Storybook Docs

Description

What it does

Surfaces are the set of background treatments — default, raised, lowered, and inverse — that establish depth and visual hierarchy across the product. Every other component (buttons, inputs, containers, modals) is drawn on top of a surface, and which surface it sits on determines its border, elevation, and contrast requirements.

Where it appears

Everywhere. The page background is a surface. A card floating above the page is a raised surface. A recessed input well or code block is a lowered surface. A tooltip or high-contrast callout may use an inverse surface.

Why it exists

Without a shared surface model, every component ends up hand-rolling its own background/border logic, and elevation stops meaning anything consistent. Surfaces give the system one small, shared vocabulary — four levels, not an open-ended set of custom backgrounds — that every other component's tokens (Component.Base, per-brand aliases) build on top of.

Dependencies

Consumed directly by the Colors token collection (Colors.Light.tokens.json / Colors.Dark.tokens.json, Surface group) — see Style tab for the resolved values in both themes. Every container-like component (Containers, Modal, Card, Popover) should reference these tokens rather than hardcoding a background.

Anatomy

PartRequired?Notes
Surface fill Required The background colour itself — one of Default, Raised, Lowered, or Inverse.
Surface border Optional The paired border colour for that surface level, used when background contrast alone doesn't define the boundary (e.g. Default-on-Default nesting).
On-surface content Required Text, icon, and interactive-element colours are chosen relative to the surface they sit on, not globally — the same text token can fail contrast on Inverse where it passes on Default.

Variants

Default

The baseline page/contained-background surface.

The starting surface for a page or panel. Most content lives here.

Raised

Positioned closest to the user — a surface that sits visually above Default.

Cards, popovers, dropdown panels, anything meant to read as floating above the page.

Lowered

Positioned farthest from the user — a surface that sits visually below Default.

Recessed wells — an input's own background, a code block, a nested "sunken" region within a container.

Inverse

A surface that flips the relationship between foreground and background.

High-emphasis callouts, tooltips, and any moment that needs to visually break from the surrounding surface stack.

States

State Behaviour
Light theme Default and Lowered currently resolve to the same token value in Light — see Style tab. Raised is a step lighter.
Dark theme Default and Raised currently resolve to distinct neutral steps; Inverse flips to a near-white neutral, the mirror of Light's near-black Inverse.

Usage guidelines

When to use

  • Any time a component needs a background — reach for one of the four surface tokens rather than a one-off colour.
  • Establishing depth between a page and the floating content above it (modals, popovers, dropdowns).
  • Recessing a region to read as "inside" or "behind" the surrounding content (input wells, code blocks).

When not to use

  • Don't invent a fifth surface level for a one-off design need — that's exactly the drift this token group exists to prevent. Raise it with the DS Working Group instead.
  • Don't use Inverse purely for visual variety — it changes the entire on-surface contrast contract, so reserve it for moments that genuinely need to break from the surrounding stack.

Do / Don't

Do

Pick a component's background from Surface tokens, not a hardcoded hex value or an unrelated Primitive.

Don't

Don't reference a Primitive colour (e.g. color-neutral-10) directly in component CSS — go through the Surface (or component-level WA-native) token so a future palette change propagates.

Do

Treat Raised/Lowered as relative to their immediate parent surface, not as absolute z-index levels.

Don't

Don't stack Raised-on-Raised-on-Raised expecting each to read as progressively more elevated — the model has four levels, not infinite depth.

Was this page helpful?

Updated 9 September 2026