Casebook
B2B customer-stories section block: a strip of original customer wordmarks acts as a tablist with a sliding accent underline and auto-advance progress line; the featured story crossfades in with a word-staggered pull quote, seeded avatar attribution and a metric rail rolling on Tally digit drums; below, an industry-filtered (Detent) story grid re-flows with layout springs, each card carrying seeded procedural cover art, cursor tilt and a hover-revealed read link.
The preview is live. The source is Pro.
One purchase, lifetime access: every pro component's source, CLI install with your own registry token, and all future drops.
Installation
CLI
npx shadcn@latest add @crucible/casebookManual — install dependencies, then copy the source
npm install motionProps
| Prop | Type | Default | Description |
|---|---|---|---|
| featured | CasebookStory[] | six seeded sample stories | Stories in the featured strip (4–6 reads best). Pass [] to hide the featured strip. |
| stories | CasebookStory[] | eight seeded sample stories | Stories in the filterable grid below. Pass [] to hide the grid. |
| industries | string[] | Industry filter tabs, in order. Omit to derive from stories. Pass [] to hide the filter. | |
| autoplay | boolean | true | Auto-advance the featured story (pauses on hover/focus, offscreen, hidden tab; off under reduced motion). |
| interval | number | 7000 | Milliseconds each featured story is shown while autoplaying. |
| index | number | Controlled featured index. | |
| defaultIndex | number | 0 | Initial featured index when uncontrolled. |
| onIndexChange | (index: number) => void | Fires whenever the featured index changes (click, keyboard, autoplay, goTo). | |
| onSelect | (story: CasebookStory, source: "featured" | "grid") => void | Fires when a "Read story" link/button or grid card is activated. | |
| eyebrow | React.ReactNode | "Customer stories" | Small label above the headline. null hides it. |
| title | React.ReactNode | "Results our customers can measure" | Section headline (<h2>). null hides the header. |
| description | React.ReactNode | Supporting copy under the headline. null hides it. | |
| gridTitle | React.ReactNode | "More stories" | Heading above the story grid. null hides it. |
| readLabel | string | "Read the story" | Label of the featured "read" link. |
| allLabel | string | "All" | Label of the "show everything" filter tab. |
| accentColor | string | "#f5d0a9" | Signature accent hex: active underline, progress line, metric rules, focus rings. |
| coverTone | "seeded" | "accent" | "seeded" | Grid cover-art palette. "seeded" gives every card its own hue from the company name; "accent" keeps the seeded composition but draws both glows from accentColor's hue family so covers match the brand. |
| ref | React.Ref<CasebookHandle> | Imperative handle (replay(), goTo(i)). React 19 ref-as-prop. | |
| className | string | Extra classes for the <section> root. | |
Also accepts all props of Omit<React.ComponentPropsWithoutRef<"section">, "children" | "title" | "onSelect"> — they pass through to the underlying element. | |||
Honors prefers-reduced-motion with a designed static fallback, and passes className through.