Foundations
Surface Elevations
Containers and planes that create depth in the interface. Surfaces split into static planes that form the layout structure and overlays that appear contextually above them.
Every visible container in the interface is a surface. Surfaces combine a fill, a border, and either a shadow or a backdrop blur to express how far they sit from the page plane.
The system has two families: static surfaces that form the layout structure and overlay surfaces that appear on top contextually.
Applying surfaces
A surface is always a token bundle, not a single token. Every surface has a matching set of tokens that share the same name in their group. Pick the surface, then apply its full set together.
Apply the full token bundle of a surface together — fill, border, and shadow must all come from the same surface name.
Mix tokens across surfaces. Using fill-surface-raised
with border-surface-action breaks the elevation
hierarchy.
Use surface-raised for static cards and
surface-action only when the entire surface is
clickable.
Use surface-action for everything just because it
looks more prominent. It signals interactivity — misuse makes the
hierarchy noisy.
Use outline for surface borders when building a
container from scratch. The border renders outside the box and
stays clean against transparent primitives.
Use border for surface containers. The inner
border blends with the fill through its transparency and picks
up the background tint.
Pair surface-sticky with its backdrop blur so the
content below remains visible but softened.
Drop a solid fill on a sticky header. The connection between the header and the scrolling content breaks.
Light and dark mode
Light mode and dark mode use fundamentally different models to express elevation. The same token names produce visually different results — but the hierarchy stays consistent.
Light mode
Surfaces get lighter as they rise. Shadows carry the visual weight of elevation.
Dark mode
Shadows are barely visible. Elevation is expressed by surfaces getting progressively lighter.
A raised card in light mode is white on a light-grey page. In dark
mode, the same card is a lighter grey on a darker grey page. The
visual relationship inverts, but the token names stay the same —
surface-raised always sits above surface-page.
All surface tokens swap automatically between themes. No manual overrides or separate dark-mode code paths are needed — semantic tokens resolve to the correct primitive for each theme.
Page surface
The page surface is the default background of every screen. It is the baseline plane — every other surface is measured relative to it. Page has no border and no shadow.
surface-page Page
The baseline page background. The bottom of the elevation scale.
Apply to the root of the layout. All static surfaces sit above it and all overlays float over it. Page uses only a single fill token — no border, no shadow.
Used by: Page body, Layout root, Screen background
Tokens in bundle
background: var(--color-fill-surface-page); Static surfaces
Static surfaces sit above the page and form the structural backbone of the layout. They do not move, do not float, and do not appear contextually.
surface-sunken Sunken
A recessed plane that sits below the page.
Use for inset areas, grouped list containers, or any region that should feel pushed into the page plane. Has a subtle fill darker than page and a soft border.
Used by: Grouped lists, Code blocks, Inset panels
Tokens in bundle
background: var(--color-fill-surface-sunken);
outline: var(--primitive-border-width-1) solid var(--color-border-surface-sunken); surface-raised Raised
A standard card or panel lifted above the page.
The default choice for cards, content panels, and any container that needs a gentle elevation above the page. Raised surfaces use only fill and border — no shadow.
Used by: Cards, Content panels, Form groups
Tokens in bundle
background: var(--color-fill-surface-raised);
outline: var(--primitive-border-width-1) solid var(--color-border-surface-raised); surface-action Action
An interactive raised surface. A card that responds to hover and press.
Use when the entire surface is clickable — link cards, selectable tiles, or interactive content blocks. Action has its own shadow scale and distinct hover and pressed states.
Used by: Clickable cards, Link tiles, Selectable content blocks
Tokens in bundle
background: var(--color-fill-surface-action);
outline: var(--primitive-border-width-1) solid var(--color-border-surface-action);
box-shadow: var(--shadow-surface-action); Overlay surfaces
Overlay surfaces float above static surfaces. Each overlay is tied to a specific component family — use the one that matches the component you are building. The order below reflects the stacking order, from lowest to highest.
- 1 Sticky Appears on scroll, behind fixed chrome
- 2 Fixed Always-on chrome — navbars, sidebars
- 3 Modeless Popovers, tooltips, toasts — above chrome
- 4 Modal Top of the stack, blocks everything below
surface-sticky Sticky
A dynamic overlay that appears on scroll. Semi-transparent with a backdrop blur.
Does not exist in the default page state — it appears behind sticky headers and scroll-anchored elements when content scrolls underneath. Always paired with a backdrop blur so the content below remains visible but softened.
Used by: Sticky headers, Scroll-anchored toolbars, Anchored sub-navigation
Tokens in bundle
background: var(--color-fill-surface-sticky);
outline: var(--primitive-border-width-1) solid var(--color-border-surface-sticky);
backdrop-filter: blur(var(--blur-surface-sticky)); surface-fixed Fixed
A permanent overlay pinned to the layout. Always visible regardless of scroll.
Use for components with an absolute position in the layout — navbars, sidebars, navigation rails, bottom bars. Fixed surfaces are on the page at all times and may be expanded or minimized, but their position never changes.
Used by: Navbars, Sidebars, Navigation rails, Bottom bars
Tokens in bundle
background: var(--color-fill-surface-fixed);
outline: var(--primitive-border-width-1) solid var(--color-border-surface-fixed);
box-shadow: var(--shadow-surface-fixed); surface-modeless Modeless
Non-blocking overlays that appear near their trigger.
Use for popovers, tooltips, dropdowns, toasts, and alerts. Modeless has colored variants for brand, critical, info, warning, and neutral-dark messaging surfaces.
Used by: Popovers, Tooltips, Dropdowns, Toasts, Alerts
Tokens in bundle
background: var(--color-fill-surface-modeless);
outline: var(--primitive-border-width-1) solid var(--color-border-surface-modeless);
box-shadow: var(--shadow-surface-modeless); surface-modal Modal
The top of the surface stack. Paired with a full-page underlay.
Reserved for modal dialogs. The modal surface floats above everything else while the modal-underlay fill covers the rest of the page behind it, combined with a backdrop blur. Use only for blocking, focused interactions.
Used by: Modal dialogs, Confirmation dialogs, Full-screen prompts
Tokens in bundle
background: var(--color-fill-surface-modal);
outline: var(--primitive-border-width-1) solid var(--color-border-surface-modal);
box-shadow: var(--shadow-surface-modal);
/* underlay */
background: var(--color-fill-surface-modal-underlay);
backdrop-filter: blur(var(--blur-surface-modal-underlay)); Token reference
Every surface fill and border token, flat. Shadows and blurs used
by surfaces live in v2/core/effects.css.
Surface fills
--color-fill-surface-sunken --color-fill-surface-page --color-fill-surface-raised --color-fill-surface-action --color-fill-surface-action-hovered --color-fill-surface-action-pressed --color-fill-surface-sticky --color-fill-surface-fixed --color-fill-surface-modeless --color-fill-surface-modeless-brand --color-fill-surface-modeless-critical --color-fill-surface-modeless-info --color-fill-surface-modeless-warning --color-fill-surface-modeless-neutral-dark --color-fill-surface-modal --color-fill-surface-modal-underlay Surface borders
--color-border-surface-sunken --color-border-surface-raised --color-border-surface-action --color-border-surface-action-hovered --color-border-surface-action-pressed --color-border-surface-sticky --color-border-surface-fixed --color-border-surface-modeless --color-border-surface-modeless-brand --color-border-surface-modeless-critical --color-border-surface-modeless-info --color-border-surface-modeless-warning --color-border-surface-modeless-neutral-dark --color-border-surface-modal