# Reeded — Animated UI Component for React

> Architectural reeded glass over an image or video: each vertical flute refracts a compressed, mirrored slice through a convex lens profile, with a slow cool specular line, edge grooves and a faint chromatic split. The pointer fogs the pane with condensation that clears in streaks along the reeds, clicks stack breath blooms, an idle ghost breathes across, and the flutes sweep in from flat glass on first view. Ships a seeded procedural dusk plate when no src is given. OGL, DPR-clamped, offscreen-paused, reduced-motion-safe.

- Page: https://crucibleui.com/components/utility/reeded
- Category: [utility](https://crucibleui.com/components/utility)
- Tier: pro (one-time purchase, see https://crucibleui.com/pricing)
- Engine: ogl
- npm dependencies: ogl

## Install

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

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

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

## Props (`ReededProps`)

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `src?` | `string \| string[]` | — | Image or video URL (or an array of them, which crossfades as a slideshow every `interval` seconds). Videos are detected by extension (mp4, webm, ogv, mov, m4v) and play muted + looped. Media is fetched with `crossOrigin="anonymous"`, so cross-origin hosts must send CORS headers — if one fails to load, the built-in procedural plate stays up. Omit to show the procedural plate: a seeded dusk landscape generated on the client. |
| `alt?` | `string` | — | Accessible description of the media, rendered as visually-hidden text. |
| `flute?` | `number` | `22` | Flute (reed) width in CSS px. |
| `curvature?` | `number` | `0.6` | Lens curvature of each flute, 0–1. 0 = flat clear glass; higher compresses and mirrors a wider slice of the image into every reed. |
| `frost?` | `number` | `0.7` | Strength of the pointer condensation, 0–1. 0 disables frost. |
| `tilt?` | `number` | `1` | Drift speed of the specular line as the pane slowly "tilts". 0 holds it still. |
| `tone?` | `"dark" \| "light"` | — | `"dark"` (default) tunes the frost to a cool smoked gray and the plate to a dusk palette; `"light"` gives milky-white frost and a pale morning plate. |
| `colors?` | `[string, string, string]` | `a cool blue dusk (dark tone) or pale mist (light tone)` | Procedural-plate palette `[deep, haze, light]`: night sky + near hills, horizon haze + far ridges, sun + glints. Ignored when `src` is shown. |
| `seed?` | `number` | `7` | Seed for the procedural plate's layout (sun, ridges, clouds). |
| `interval?` | `number` | `6` | Seconds per slide when `src` is an array. |
| `interactive?` | `boolean` | `true` | Pointer leaves frost; click breathes; idle autoplay ghost. |
| `paused?` | `boolean` | — | Freeze the glass (and pause any video) on the current frame. |
| `children?` | `React.ReactNode` | — | Overlay content, centered above the glass. |
| `ref?` | `React.Ref<ReededHandle>` | — | React 19 ref prop → {@link ReededHandle}. |

Also accepts: `React.ComponentPropsWithoutRef<"div">`.

## Usage example

```tsx
import { Reeded } from "@/components/crucible/reeded";

export default function ReededDemo() {
  return (
    <div className="relative isolate flex h-full min-h-[360px] w-full items-center justify-center overflow-hidden rounded-xl bg-neutral-950">
      <Reeded alt="A dusk landscape seen through fluted glass">
        <div className="pointer-events-none relative z-10 rounded-2xl border border-white/10 bg-neutral-950/45 px-6 py-5 text-center shadow-2xl shadow-black/40 backdrop-blur-md">
          <p className="text-base font-medium tracking-tight text-white/90">Breathe on the glass</p>
          <p className="mt-1.5 text-xs text-white/50">Move to fog it · click to breathe</p>
        </div>
      </Reeded>
    </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.
