StartFoundationsComponentsContent

Elevation

A shadow shows how high a surface floats. A z-index layer decides what sits on top. They are separate tools.

GuideTokens
shadow-1
shadow-2
shadow-3
<div style="box-shadow: var(--shadow-1); background: var(--surface-raised); padding: var(--space-24); border-radius: var(--radius-12)">shadow-1</div>
<div style="box-shadow: var(--shadow-2); background: var(--surface-raised); padding: var(--space-24); border-radius: var(--radius-16)">shadow-2</div>
<div style="box-shadow: var(--shadow-3); background: var(--surface-raised); padding: var(--space-24); border-radius: var(--radius-16)">shadow-3</div>

Shadow

Three steps, plus shadow-none. The higher the number, the higher the surface floats.

Token Use for In Thykes
shadow-none flat; clears an inherited shadow —
shadow-1 a card, a small lifted part the selected segment, the switch thumb
shadow-2 a panel floating over the page menu, popover, tooltip, toast, date pickers, floating sidebar
shadow-3 a modal surface dialog, sheet

Components set their own shadow; use the tokens for surfaces you build yourself.

Share

Anyone with the link can view this file.

<tk-popover label="Share">
  <tk-button slot="trigger">Share</tk-button>
  <p>Anyone with the link can view this file.</p>
</tk-popover>
  • Each step has a 1px rim in light and dark: a thin edge that keeps a raised surface crisp against a background of the same tone. The rim is black in light and white in dark.
  • Dark theme: the shadow is stronger, and surface/raised is one step lighter than the page. The step is small, so the white rim draws most of the edge.
  • High contrast: the shadow is one faint layer with no rim. Floating panels draw a border instead.

Borders and shadows

The rim lands just outside the element, on top of any border it draws. An element with both a border and a shadow shows two edges.

  • A floating panel you build: let the shadow draw the edge in light and dark, and add a border only in high contrast. Thykes panels work this way.
  • A border that must stay visible in every theme, such as a control's 3:1 edge: keep the border and drop the shadow.
.my-panel { box-shadow: var(--shadow-2); }
[data-theme="high-contrast"] .my-panel { border: 1px solid var(--border-default); }
@media (prefers-contrast: more) {
  :root:not([data-theme]) .my-panel { border: 1px solid var(--border-default); }
}

The rim follows the theme, not the surface. On a dark surface in the light theme, such as a tooltip or a toast, it's invisible, so it never defines a dark surface's edge.

Stacking order

  • Thykes overlays need no z-index. Dialogs, sheets, menus, popovers, tooltips, and the panels of selects and date pickers open in the browser's top layer, above everything on your page.
  • Use a z-* layer for your own elements that float over the page: a sticky header takes z-sticky, a custom dropdown z-dropdown. Toasts sit on z-toast.
  • Inside a component, stack locally. Set isolation: isolate on the component's root and use z-index: 1, 2, 3 inside it. The local values can't leak out and compete with the page's layers.
  • Never write z-index: 9999. Pick the layer by its role.

The layers are on the Z-index card.

Accessibility

  • A shadow is never the only boundary. It is soft and depends on the background, so it can't meet the 3:1 non-text minimum. If an element's edge matters, such as a control's or a field's, give it a border.
  • Elevation doesn't replace focus. A lifted surface still needs a visible focus indicator; see Focus.

Do / Don't

✅ Do ❌ Don't
Take shadows from shadow-* Write a box-shadow by eye
Use shadow-1 for cards, shadow-2 for floating panels, shadow-3 for modals Give a modal the same shadow as a card
Give an element a border when its edge must be seen Rely on a shadow alone as a boundary
Border a floating panel in high contrast only Give it a border and a shadow in every theme
Show hover by changing the surface or border Add a stronger shadow step for hover
Use z-* layers, and isolation: isolate inside a component Write z-index: 9999