A tactile React component library
State is depth.
Pressed things depress. Active things rise. Inputs are recessed wells — and every shadow on this page is cast by one movable light. 35 components, machined for the web, installed straight into your codebase.
npx shadcn@latest add @emboss/buttonThe grammar of depth
Raised = available
Things you can press rest off the surface.
Latched = selected
Chosen things sit pressed into the chassis.
Recessed = receives
Wells take input; focus brightens the floor.
One rule, everywhere: the z-axis is the state machine.
The signature trick
One light. Every shadow.
Components don't ship hardcoded shadows — they derive them from two CSS variables: the light's position. Drag the bulb and everything on this page re-lights, instantly, in pure CSS.
A floating plate — its penumbra stretches away from the bulb.
--light-x: -0.45 · --light-y: -0.89
The full bench
Every component. Live, in place.
Nothing below is a screenshot. Press, drag, type, and open everything — then install the ones you keep.
Actions
Things you press. Momentary physics, machined returns.
Forms
Wells that receive input and controls that latch.
AI
Streaming-native primitives with the same physics.
Tune the machine
Make it yours.
Five variables theme the entire system. Tune them here — the whole page obeys — then copy the block into your stylesheet.
:root {
--light-x: -0.45;
--light-y: -0.89;
--depth: 1;
--accent-h: 45;
--radius-scale: 1;
}Paste into your stylesheet's :root — or keep tuning; this page remembers.
Own the source
Installed into your codebase, not around it.
No package to depend on, no version to chase. The TypeScript lands in your repo — restyle it, fork it, own it.
Point your project at the registry
components.json { "registries": { "@emboss": "https://embossui.vercel.app/r/{name}.json" } }Add components
pnpm dlx shadcn@latest add @emboss/button @emboss/knobShip
page.tsx import { Button } from "@/components/ui/button"; export default function Page() { return <Button variant="accent">Engage</Button>; }
Prefer copy-paste? Every docs page carries the full source with consumer-ready import paths.