Axon 911 Frontend Docs
    Loading navigation…
U
User
Switch to light mode
  1. Foundations
  2. Elevation

Elevation

Role-based shadow tokens and how Box, Card, and popup surfaces apply them.

Elevation communicates stacking role: how a surface sits relative to the page and to other layers. Components bind to a role (sunken, raised, overlay, modal, or floating tray), not to a decorative “heavier shadow.” Pick the role from what the surface does; two surfaces with the same job use the same token everywhere. Shipped values live in @prepared911/ui/styles.css as --elevation-* custom properties (vendored from Chroma). React exposes the five Box roles through Elevation on Box and FlexBox. Card uses CardElevation for its optional resting shadow. After the Chroma elevation flip, each role token aliases a level stack (xs through xl, plus inset and drawer edges). Visual depth changes; names stay stable so reverting Chroma restores the prior computed values through --elevation-legacy-*.
Role tokens
Role tokens resolve to multi-layer stacks in system.css. The table lists the alias each role uses today and typical consumers.
RoleElevationTokenResolves toTypical useConsumers in @prepared911/ui
FlatNone—noneList rows, dense tables, chrome with no liftDefault Box / Card
SunkenSunken--elevation-sunken-shadow--elevation-inset-shadowInset wells and recessed tracksBox / FlexBox elevation only
RaisedRaised--elevation-raised-shadow--elevation-sm-shadowCards and panels resting on the pageBox, Card (CardElevation.Raised), Accordion, ChannelList (raised chip)
OverlayOverlay--elevation-overlay-shadow--elevation-md-shadowTooltips, popovers, compact popups, chat chromeBox, Popover, Tooltip, ChatInput, ChannelList (overlay panel), ChartFrame tooltip, popup-surface-overlay recipe
ModalModal--elevation-modal-shadow--elevation-xl-shadowBlocking dialogs and modal shellsBox, Dialog (modal-surface recipe), popup-surface-modal recipe
Floating tray and toast shadows
Portaled menus and toolbars use --elevation-floating-shadow (aliases --elevation-md-shadow). Toasts use --elevation-toast-shadow (aliases --elevation-lg-shadow). Neither is a Box Elevation value; components reference them in CSS.
TokenResolves toTypical useConsumers
--elevation-floating-shadow--elevation-md-shadowMenus, listboxes, floating toolbarsMenu, Listbox, Toolbar (floating variant), ChatScroll jump control, Select / Combobox list surfaces
--elevation-toast-shadow--elevation-lg-shadowToast stack above page chromeToast
Part and control shadows
TokenPurposeConsumers
--elevation-resting-shadowSelected pill in segmented controlsSelectionPill (used by SegmentedControl, ToggleGroup)
--elevation-thumb-shadowSwitch and slider thumbsSwitchTrack, Switch, Slider
--elevation-bubble-shadowSlider value bubble (dark theme region)SliderBubble
Layer and edge tokens
Level stacks bind shadow layers to --elevation-layer-{xs,sm,md,lg,xl,drawer,inset} (per-mode rgba). --elevation-edge-color and --elevation-edge-inset-color paint flat rings and inset borders; --elevation-hairline-border composes the default hairline. Do not compose ad hoc shadows from removed --elevation-{xs..xl}-color ramp names; request a token upstream instead.
TokenLight (default)Dark ([data-theme='dark'])
--elevation-layer-xsrgba(17,17,20,0.06)rgba(0,0,0,0.12)
--elevation-layer-smrgba(17,17,20,0.05)rgba(0,0,0,0.10)
--elevation-layer-mdrgba(17,17,20,0.04)rgba(0,0,0,0.08)
--elevation-layer-lgrgba(17,17,20,0.035)rgba(0,0,0,0.07)
--elevation-layer-xlrgba(17,17,20,0.03)rgba(0,0,0,0.06)
--elevation-edge-colorrgba(17,17,20,0.05)rgba(255,255,255,0.08)
--elevation-edge-inset-colorrgba(17,17,20,0.06)rgba(255,255,255,0.10)
Additional --elevation-soft-color-* steps in system.css still back resting, thumb, and bubble tokens until a later Chroma cleanup removes unused steps.
How to apply elevation
Box and FlexBox
Pass elevation={Elevation.<Role>}. Background stays on background; elevation only sets box-shadow.
Card
CardElevation.None (default) keeps a Surface card flat. CardElevation.Raised adds --elevation-raised-shadow on CardVariant.Surface only; Ghost accepts None at the type level.
Popup and modal recipes
Portaled shells apply shared Tailwind recipes from tailwind/recipes/popup-surface.css and modal-surface.css. Use @apply in colocated component CSS, not ad hoc utility strings in className (see Portal usage).
  • popup-surface-shell: border, radius, overlay fill, motion hooks; under forced-colors: active, border color becomes CanvasText.
  • popup-surface-overlay: shell + --elevation-overlay-shadow.
  • popup-surface-modal: shell + --elevation-modal-shadow.
  • modal-surface: shell + modal motion + --elevation-modal-shadow (Dialog).
Drawer edge shadows
Drawer paints one of four edge tokens on the sliding panel. Drawer stacks use --elevation-layer-drawer (same geometry as the lg level, anchored per edge):
TokenApplied on
--elevation-drawer-inline-start-shadowinlineStart panel (leading inline edge)
--elevation-drawer-inline-end-shadowinlineEnd panel
--elevation-drawer-block-start-shadowblockStart panel
--elevation-drawer-block-end-shadowblockEnd panel
Every edge token casts toward the page content, away from the edge the panel is anchored to: the inline pair casts across the page, block-start casts down from a top-anchored panel and block-end casts up from a bottom-anchored panel. Listbox paints --elevation-drawer-block-end-shadow on a pinned footer divider when footerShadow is enabled.
Dark mode and accessibility
On the default dark theme, shadows are subtle against --color-bg-default; pair raised surfaces with BorderColor.Subtle or BorderColor.Default when fill and page are close in value. Under forced-colors: active, system colors replace token fills and shadows no longer carry the edge. Shared popup shells keep a 1px border-style: solid edge (popup-surface-shell uses var(--border-width-default) and var(--color-border-default); forced colors switch the border to CanvasText). Surfaces that normally rely on shadow alone should still expose a border in that mode (Toast clears box-shadow and keeps a CanvasText border; Tooltip adds a CanvasText border). Elevation is not a focus indicator. Pair interactive surfaces with the focus-ring recipes.
Stacking with z-index
Elevation does not replace z-index. Portaled chrome still uses --z-index-* tokens. Band order for overlays (bottom → top): overlay → modal → popover → tooltip. .pr-tooltip sits at calc(var(--z-index-tooltip) + 100) so tooltips paint above popovers when those tokens share a numeric value.
Do and don't
Do
  • Choose Elevation from the surface role (sunken well, raised card, overlay menu, modal dialog).
  • Use CardElevation.Raised only on CardVariant.Surface.
  • Apply popup/modal shadows through popup-surface-* and modal-surface recipes in component CSS.
  • Add a visible border when shadow contrast is weak (especially on dark default).
Don't
  • Reference legacy ui-core --shadow-1…--shadow-5 or Elevation.Low / Medium / High; they are removed.
  • Stack multiple box-shadows or mix role tokens with hand-written shadows.
  • Use elevation on dense lists or tiny controls; spacing and borders separate them.
  • Depend on a drawer shadow alone for separation in forced-colors mode; keep the border.
Previous
Spacing
Next
Semantics
On this page
Role tokens
Floating tray and toast shadows
Part and control shadows
Layer and edge tokens
How to apply elevation
Box and FlexBox
Card
Popup and modal recipes
Drawer edge shadows
Dark mode and accessibility
Stacking with z-index
Do and don't