# Oxide — Animated Card for React

> Image carousel that transitions through a spreading temper-color front: from the click point a noise-roughened edge creeps across the card like heat through steel, washing the outgoing picture in luminance-modulated straw, bronze, purple and blue oxide film before the next image cools in. Stacking clicks, autoplay, next/prev/goTo handle, scroll scrub, seeded procedural plates. Original OGL shader, DPR-clamped, offscreen-paused, reduced-motion crossfade.

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

## Install

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

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

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

## Props (`OxideProps`)

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `ref?` | `React.Ref<OxideHandle>` | — | React 19 ref-as-prop → {@link OxideHandle}. |
| `images?` | `string[]` | — | Image URLs to cycle through (loaded with `crossOrigin="anonymous"`, so cross-origin hosts must send CORS headers). Cover-fit to the card. Omit for three built-in seeded procedural plates. |
| `alts?` | `string[]` | — | Accessible descriptions, one per image — announced on change. |
| `index?` | `number` | — | Controlled current image index. Changing it tempers to that image. |
| `defaultIndex?` | `number` | `0` | Initial image index when uncontrolled. |
| `onIndexChange?` | `(index: number) => void` | — | Fired whenever a transition toward a new image begins. |
| `duration?` | `number` | `1400` | Length of one temper transition, in milliseconds. |
| `autoplay?` | `number \| false` | `4200` | Auto-advance interval in milliseconds (counted while idle and on-screen), or `false` to disable. Pauses offscreen, on hidden tabs, while keyboard focus is inside, and under reduced motion. |
| `origin?` | `"pointer" \| "center"` | `"pointer"` | Where each front starts: `"pointer"` — the click point (autoplay picks a seeded wandering point); `"center"` — always the card center. |
| `bandWidth?` | `number` | `0.24` | Width of the temper-color band, as a fraction of card height, 0.05–0.6. |
| `noiseScale?` | `number` | `2.4` | Scale of the fbm that roughens the front, 0.5–8. Higher = finer lobes. |
| `palette?` | `string[]` | `is the metallurgical sequence straw → bronze → purple → blue → pale grey-blue` | Override the temper stops (2–6 hex colors), ordered from the leading edge inward. |
| `scrollProgress?` | `number` | — | Controlled scrub, 0–1, across the whole image sequence (e.g. scroll progress). When set, clicks and autoplay are disabled and the front is driven directly by this value. |
| `controls?` | `boolean` | `false` | Render real prev/next buttons over the card. |
| `seed?` | `number` | `7` | Seed for the front noise and the autoplay origins. |
| `paused?` | `boolean` | `false` | Freeze all animation at the current frame. |

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

## Usage example

```tsx
import { Oxide } from "@/components/crucible/oxide";

export default function OxideDemo() {
  return (
    <div className="relative isolate flex h-full min-h-[360px] w-full items-center justify-center overflow-hidden rounded-xl bg-neutral-950 p-6">
      <div className="relative z-10 flex w-full max-w-2xl flex-col items-center gap-4">
        <Oxide
          controls
          alts={["Dusk over layered ridges", "Alpine morning over a still lake", "Moonlit dunes"]}
          className="w-full shadow-2xl shadow-black/60 ring-1 ring-white/10"
        />
        <p className="pointer-events-none text-sm text-neutral-500">
          Click anywhere to temper to the next image.
        </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.
