crucıble

Surface

A composable in-view reveal wrapper with fade/slide/scale/blur presets and staggered children. Default melt preset rises and sharpens with a soft white under-glow, like surfacing out of the dark.

motionfree

Installation

CLI

npx shadcn@latest add @crucible/surface

Manual — install dependencies, then copy the source

npm install motion

Props

PropTypeDefaultDescription
childrenReact.ReactNodeContent to reveal. Each top-level child animates as its own staggered item.
preset"melt" | "fade" | "slide" | "scale" | "blur""melt"Named entrance treatment. melt is the Crucible signature: rise + blur + a soft under-glow, like the element is surfacing out of the dark.
direction"up" | "down" | "left" | "right""up"Travel direction for melt/slide.
distancenumber12Travel distance in px for melt/slide.
blurnumber8Starting blur radius in px for melt/blur.
scaleFromnumber0.94Starting scale for scale.
durationnumber0.6Seconds each item takes to settle.
staggernumber0.08Seconds between each top-level child's reveal.
delaynumber0Seconds before the first item starts.
repeatbooleanfalseRe-trigger every time it scrolls into view instead of once.
amountnumber0.4Fraction of the element that must be visible to trigger.
marginNonNullable<HTMLMotionProps<"div">["viewport"]>["margin"]"0px 0px -10% 0px"viewport.margin-style rootMargin, e.g. to trigger before entry.
rootReact.RefObject<Element | null>the viewportScroll container to observe instead of the browser viewport. Pass a ref to an overflow-scrolling ancestor so the reveal triggers as content scrolls within THAT container (e.g. inside a boxed panel).
emberbooleantrueShow the under-glow (only rendered for preset="melt").
emberColorstring"#ffffff" (soft white)Glow color for the melt under-glow.
Also accepts all props of Omit<HTMLMotionProps<"div">, "children" | "initial" | "whileInView" | "viewport" | "transition">they pass through to the underlying element.

Honors prefers-reduced-motion with a designed static fallback, and passes className through.