# Scree — Animated Text Effect for React

> A paragraph that holds its typographic line until triggered, then every word becomes a matter-js rigid body that drops, tumbles, collides, and piles at the floor — grab a fallen word and fling it. Highlight words carry the lone accent and settle atop the neutral heap.

- Page: https://crucibleui.com/components/text/scree
- Category: [text](https://crucibleui.com/components/text)
- Tier: pro (one-time purchase, see https://crucibleui.com/pricing)
- Engine: canvas
- npm dependencies: matter-js

## Install

```bash
npx shadcn@latest add @crucible/scree
```

Pro install requires adding the token-bearing `@crucible` registry to components.json (issued at https://crucibleui.com/account after purchase).

Import from `@/components/crucible/scree`.

## Props (`ScreeProps`)

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `text?` | `string` | `a short line` | The body text. Every word becomes a falling rigid body. |
| `highlightWords?` | `string[]` | `[]` | Words rendered in the accent color — they settle atop the neutral pile. Matched case-insensitively, ignoring surrounding punctuation. |
| `accent?` | `string` | `warm amber` | The single accent hue reserved for {@link highlightWords}. |
| `wordColor?` | `string` | `near-white` | Color of the ordinary words. |
| `trigger?` | `ScreeTrigger` | `"hover"` | What fires the collapse. |
| `gravity?` | `number` | `1` | Gravity strength — higher drops faster/heavier. |
| `speed?` | `number` | `1` | Simulation-rate multiplier (matter timeScale). |
| `restitution?` | `number` | `0.24` | Bounciness of the words (0 = dead, ~0.6 = lively). |
| `mouseStiffness?` | `number` | `0.2` | Grab strength of the pointer constraint when flinging a word. |
| `fontSize?` | `number` | `22` | Word font size in px. |
| `wordSpacing?` | `number` | `6` | Extra horizontal/vertical spacing between words in px. |
| `resetOnLeave?` | `boolean` | `true` | For the `hover` and `scroll` triggers: rebuild the paragraph when the pointer leaves / the block scrolls away, so the effect replays. |
| `paused?` | `boolean` | `false` | Freeze the simulation in place. |
| `seed?` | `number` | `7` | Deterministic seed for tumble bias + the settling shuffle. |

Also accepts: `Omit<React.ComponentPropsWithoutRef<"div">, "children" | "color">`.

## Usage example

```tsx
import { Scree } from "@/components/crucible/scree";

export default function ScreeDemo() {
  return (
    <div className="relative isolate flex h-full min-h-[360px] w-full items-center justify-center overflow-hidden rounded-xl bg-neutral-950">
      <div className="relative z-10 flex w-full max-w-2xl flex-col items-center gap-5 px-6 py-8">
        <Scree
          text="Every word here is a rigid body waiting to fall and pile up."
          highlightWords={["fall", "pile"]}
          className="h-56 min-h-0 w-full"
        />
        <p className="text-sm text-neutral-500">
          Hover to drop these words — then grab one and fling it.
        </p>
      </div>
    </div>
  );
}
```

## Accessibility & performance

Honors `prefers-reduced-motion` with a designed static frame or fade (never a blank box) and passes `className` through. Pauses offscreen and on hidden tabs, clamps device pixel ratio, and tears down its GL/canvas context on unmount.
