Dark Elevation
A dark-mode elevation scale — five layered box-shadow tokens with a top light line, inner hairline, edge ring, and doubling ambient shadows. From resting card to floating bar.
inset 0 1px 0 0 rgba(255,255,255,0.08)inset 0 0 0 1px rgba(255,255,255,0.04)0 0 0 1px rgba(0,0,0,0.16)0 1px 1px -0.5px rgba(0,0,0,0.18)0 3px 3px -1.5px rgba(0,0,0,0.18)0 6px 6px -3px rgba(0,0,0,0.18)0 12px 12px -6px rgba(0,0,0,0.18)The scale
Usage
import { Elevation } from "~/components/elevation/elevation";<Elevation level={3} className="p-6"><Dropdown /></Elevation>
How the depth works
In dark mode a single drop shadow barely shows — there's no white background for it to darken. So depth comes from three surface cues plus stacked ambient shadows.
Every level shares a surface treatment: an inset top light line (as if lit from above), an inset hairline to define the inner edge, and a 0 0 0 1px dark ring to separate it from the background. Then each step adds one more ambient shadow whose offset and blur double (1 → 3 → 6 → 12) while a negative spread (−0.5 → −1.5 → −3 → −6) pulls each layer in, so the penumbra stays soft instead of muddy. More layers reads as floating further off the page.
/* Shared surface: top light line + inner hairline + outer ring */.dm-elev {--dm-surface:inset 0 1px 0 0 rgba(255, 255, 255, 0.08),inset 0 0 0 1px rgba(255, 255, 255, 0.04),0 0 0 1px rgba(0, 0, 0, 0.16);border-radius: 22px;background: #232327;}/* Each level appends one more ambient layer — offset & blur double,negative spread keeps it tight. */.dm-elev-1 { box-shadow: var(--dm-surface); }.dm-elev-2 { box-shadow: var(--dm-surface),0 1px 1px -0.5px rgba(0,0,0,.18); }.dm-elev-3 { box-shadow: var(--dm-surface),0 1px 1px -0.5px rgba(0,0,0,.18), 0 3px 3px -1.5px rgba(0,0,0,.18); }.dm-elev-4 { box-shadow: var(--dm-surface),0 1px 1px -0.5px rgba(0,0,0,.18), 0 3px 3px -1.5px rgba(0,0,0,.18),0 6px 6px -3px rgba(0,0,0,.18); }.dm-elev-5 { box-shadow: var(--dm-surface),0 1px 1px -0.5px rgba(0,0,0,.18), 0 3px 3px -1.5px rgba(0,0,0,.18),0 6px 6px -3px rgba(0,0,0,.18), 0 12px 12px -6px rgba(0,0,0,.18); }
Props
| prop | type | default | description |
|---|---|---|---|
| level | 1 | 2 | 3 | 4 | 5 | 1 | Elevation step, resting → floating. |
| children | ReactNode | — | Surface contents. |
| …props | HTMLAttributes | — | Any native div prop (className, style, …). |
Source
download .zipThe full implementation, across 2 files. Copy it in or grab the zip. It leans on a cn() class helper and the theme tokens (--primary, --border, …).
import { cn } from "~/lib/utils";export type ElevationLevel = 1 | 2 | 3 | 4 | 5;export interface ElevationPropsextends React.HTMLAttributes<HTMLDivElement> {/** Elevation step, 1 (resting) → 5 (floating). */level?: ElevationLevel;}/** Metadata for each step — name, use-case, and the exact box-shadow stack. */export const ELEVATIONS: {level: ElevationLevel;name: string;use: string;layers: string[];}[] = [{level: 1,name: "Resting",use: "Base card / surface",layers: ["inset 0 1px 0 0 rgba(255,255,255,0.08)","inset 0 0 0 1px rgba(255,255,255,0.04)","0 0 0 1px rgba(0,0,0,0.16)",],},{level: 2,name: "Raised",use: "Buttons / list items",layers: ["inset 0 1px 0 0 rgba(255,255,255,0.08)","inset 0 0 0 1px rgba(255,255,255,0.04)","0 0 0 1px rgba(0,0,0,0.16)","0 1px 1px -0.5px rgba(0,0,0,0.18)",],},{level: 3,name: "Overlay",use: "Dropdown / popover",layers: ["inset 0 1px 0 0 rgba(255,255,255,0.08)","inset 0 0 0 1px rgba(255,255,255,0.04)","0 0 0 1px rgba(0,0,0,0.16)","0 1px 1px -0.5px rgba(0,0,0,0.18)","0 3px 3px -1.5px rgba(0,0,0,0.18)",],},{level: 4,name: "Modal",use: "Dialog / sheet",layers: ["inset 0 1px 0 0 rgba(255,255,255,0.08)","inset 0 0 0 1px rgba(255,255,255,0.04)","0 0 0 1px rgba(0,0,0,0.16)","0 1px 1px -0.5px rgba(0,0,0,0.18)","0 3px 3px -1.5px rgba(0,0,0,0.18)","0 6px 6px -3px rgba(0,0,0,0.18)",],},{level: 5,name: "Floating",use: "Sticky / floating bar",layers: ["inset 0 1px 0 0 rgba(255,255,255,0.08)","inset 0 0 0 1px rgba(255,255,255,0.04)","0 0 0 1px rgba(0,0,0,0.16)","0 1px 1px -0.5px rgba(0,0,0,0.18)","0 3px 3px -1.5px rgba(0,0,0,0.18)","0 6px 6px -3px rgba(0,0,0,0.18)","0 12px 12px -6px rgba(0,0,0,0.18)",],},];/*** A dark-mode elevated surface. Each `level` layers a shared surface treatment* (top light line + inner hairline + outer ring) with a stack of ambient* shadows that double in offset/blur while a negative spread keeps them tight —* so higher levels read as floating further off the page. Styling lives in* `.dm-elev-*` (app.css); no Tailwind required.*/export function Elevation({level = 1,className,...props}: ElevationProps) {return (<div className={cn("dm-elev", `dm-elev-${level}`, className)} {...props} />);}
/* ─── Dark-mode elevation scale ────────────────────────────────────── *//* Every level shares a surface treatment — a top light line, an innerhairline, and an outer ring — then stacks ambient shadows whose offset andblur double while the negative spread keeps each layer tight. Level 5 is thefloating-bar recipe from the reference. */.dm-elev {--dm-surface:inset 0 1px 0 0 rgba(255, 255, 255, 0.08),inset 0 0 0 1px rgba(255, 255, 255, 0.04),0 0 0 1px rgba(0, 0, 0, 0.16);border-radius: 22px;background: #232327;}.dm-elev-1 {box-shadow: var(--dm-surface);}.dm-elev-2 {box-shadow: var(--dm-surface), 0 1px 1px -0.5px rgba(0, 0, 0, 0.18);}.dm-elev-3 {box-shadow:var(--dm-surface),0 1px 1px -0.5px rgba(0, 0, 0, 0.18),0 3px 3px -1.5px rgba(0, 0, 0, 0.18);}.dm-elev-4 {box-shadow:var(--dm-surface),0 1px 1px -0.5px rgba(0, 0, 0, 0.18),0 3px 3px -1.5px rgba(0, 0, 0, 0.18),0 6px 6px -3px rgba(0, 0, 0, 0.18);}.dm-elev-5 {box-shadow:var(--dm-surface),0 1px 1px -0.5px rgba(0, 0, 0, 0.18),0 3px 3px -1.5px rgba(0, 0, 0, 0.18),0 6px 6px -3px rgba(0, 0, 0, 0.18),0 12px 12px -6px rgba(0, 0, 0, 0.18);}