Skip to content
← components

Dark Elevation

new

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.

DM-ELEVATION-5
Floating · Sticky / 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

1
Resting
2
Raised
3
Overlay
4
Modal
5
Floating

Usage

example.tsx
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.

elevation.css
/* 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

proptypedefaultdescription
level1 | 2 | 3 | 4 | 51Elevation step, resting → floating.
childrenReactNodeSurface contents.
…propsHTMLAttributesAny native div prop (className, style, …).

The 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, …).

components/elevation/elevation.tsx
import { cn } from "~/lib/utils";
export type ElevationLevel = 1 | 2 | 3 | 4 | 5;
export interface ElevationProps
extends 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} />
);
}
app/styles/app.css
/* ─── Dark-mode elevation scale ────────────────────────────────────── */
/* Every level shares a surface treatment — a top light line, an inner
hairline, and an outer ring — then stacks ambient shadows whose offset and
blur double while the negative spread keeps each layer tight. Level 5 is the
floating-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);
}