Elevation
Five layers from the system's shadow tokens, from the base surface to modals, plus the pop-in and pop-out motion for floating layers.
- elevation-0Base surfaceCards and sections
- elevation-1Resting controlA selected tab, a badge
- elevation-2Dropdown layerMenus, popovers, toolbars
- elevation-3Raised cardFeatured or dragged cards
- elevation-4OverlayToasts and modals
Installation
$ pnpm dlx shadcn@latest add @ssntl/elevationUsage
/* app/globals.css */
@import "../styles/ssntl/shadow-smooth.css";
@import "../styles/ssntl/elevation.css";
<section class="bg-muted elevation-0">…</section>
<div role="menu" class="elevation-2 data-[state=open]:pop-in">…</div>
<div role="dialog" class="elevation-4">…</div>Rules
What this component expects from you, as it ships in styles/ssntl/elevation.md next to the code. The full file adds when to use it, keyboard, the UI foundations it applies and every shared rule.
## Rules for Elevation
- **Base surface.** Static content sits at `elevation-0` and separates by tone, never by shadow.
- **Dropdown layer.** Menus, popovers and toolbars take `elevation-2` (`shadow-float`).
- **Raised card.** A featured or dragged card takes `elevation-3` (float plus lift), above dropdowns.
- **Floating notification and modal depth.** Toasts and dialogs take `elevation-4`, the top layer; a modal adds a scrim.
- `pop-in` grows a layer in from its origin over `--duration-menu` (set `--pop-duration` for modals); `pop-out` leaves faster. Reduced motion keeps the fade only.Code
/* Elevation: how far a layer sits above the page, from the system's own
shadow tokens. Static content stays on the base surface; only what floats
gets a shadow, and the higher it floats, the more it casts.
elevation-0 base surface: cards, sections (tone separates them)
elevation-1 controls resting on a surface (bezel)
elevation-2 dropdowns, popovers, menus, toolbars (float)
elevation-3 raised or dragged cards (float + lift)
elevation-4 toasts and modals, above everything (smooth stack × 3)
pop-in, pop-out enter and exit for floating layers; set --pop-duration
to var(--duration-panel) for modals */
@utility elevation-0 {
box-shadow: none;
}
@utility elevation-1 {
box-shadow: var(--shadow-bezel);
}
@utility elevation-2 {
box-shadow: var(--shadow-float);
}
@utility elevation-3 {
box-shadow: var(--shadow-float), var(--shadow-lift);
}
@utility elevation-4 {
@apply shadow-smooth shadow-intensity-200 shadow-size-3;
}
/* Floating layers grow in from their origin and fade out faster than they
came in. With reduced motion only the opacity changes. */
@utility pop-in {
animation: pop-in var(--pop-duration, var(--duration-menu)) var(--ease-out);
@media (prefers-reduced-motion: reduce) {
animation-name: fade-in;
}
}
@utility pop-out {
animation: pop-out var(--duration-fast) var(--ease-out) forwards;
@media (prefers-reduced-motion: reduce) {
animation-name: fade-out;
}
}
@keyframes pop-in {
from {
opacity: 0;
scale: var(--es-press);
}
}
@keyframes pop-out {
to {
opacity: 0;
scale: 0.98;
}
}
@keyframes fade-in {
from {
opacity: 0;
}
}
@keyframes fade-out {
to {
opacity: 0;
}
}