Skip to main content
Shadow tokens compose across three layers. Start with the top-level preset for a quick lift, redefine the elevation scale to repaint the palette, and reach for per-element overrides when a single element needs different chrome.

Layer 1: appearance.shadowSize

Top-level preset. One knob lifts every input and the submit button onto a step of the elevation scale.
Independent of appearance.size; { size: 'large', shadowSize: 'sm' } is a valid combo.

Layer 2: elevation scale

shadowSm, shadowMd, and shadowLg variables define what the 'sm', 'md', and 'lg' steps mean. Override them to repaint the entire palette; every consumer (the shadowSize preset, per-element tokens, utility classes) picks up the new values automatically. Each accepts a full CSS box-shadow string (one or more comma-separated layers) or a var(--your-css-var) reference.

Layer 3: per-element overrides

Tune shadows on inputs and buttons independently. Each accepts:
Per-element overrides win over the shadowSize preset. Use this to opt a single element out of a global preset, or to ramp the CTA on hover:

Element-scoped shadows

Each element’s appearance layers on top of the instance-level shadow configuration for free. See Element-scoped overrides.

Focus and error rings

Every input applies box-shadow: var(--input-shadow) at rest. Focus and error states use comma-composed multi-shadow: the ambient elevation stacks under the focus or error ring, so both layers render cleanly. When inputShadow resolves to none, only the ring renders.

See also

Last modified on July 17, 2026