# Theme Flip
URL: https://remocn.dev/docs/media/theme-flip

A cursor clicks a theme toggle in a product window and the whole UI floods from light to dark.

- Install: `npx shadcn@latest add @remocn/theme-flip`
- Vibe: clean
- Natural length: 74f @ 30fps

## Installation

```bash
npx shadcn@latest add @remocn/theme-flip
```

## Usage

```tsx
// src/Root.tsx
import { Composition } from "remotion";
import { ThemeFlip } from "@/components/remocn/theme-flip";

const ThemeFlipScene = () => (
  <ThemeFlip
    fromSrc="/screens/light.png"
    toSrc="/screens/dark.png"
    origin={{ x: 1340, y: 33 }}
  />
);

export const RemotionRoot = () => (
  <Composition
    id="ThemeFlip"
    component={ThemeFlipScene}
    durationInFrames={112}
    fps={30}
    width={1280}
    height={720}
  />
);
```

The camera pushes in on a theme toggle, a cursor clicks it, and the new theme floods out from the click point across the window before the camera pulls back. With `reverse` it clicks again and flips back. Use the built-in mock, or pass `from` and `to` nodes, or `fromSrc` and `toSrc` images, with an `origin` in screenshot pixels. It has two looks built in, set by `startTheme`.

The ground is a live gradients.sh shader (`GshGround`), installed with the component as `@remocn/gsh`. Pick another look with the `ground` preset prop.

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `from` | `React.ReactNode` | — | Custom starting UI as a React node. |
| `to` | `React.ReactNode` | — | Custom final UI as a React node. |
| `fromSrc` | `string` | — | Starting screenshot URL. |
| `toSrc` | `string` | — | Final screenshot URL. |
| `startTheme` | `"light" \| "dark"` | `"light"` | Theme the built-in mock starts in. |
| `origin` | `{ x: number; y: number }` | — | Click point and flood center in screenshot pixels. |
| `showToggle` | `boolean` | `true` | Draw a floating toggle at origin over custom content. |
| `showCursor` | `boolean` | `true` | Show the cursor that clicks the toggle. |
| `reverse` | `boolean` | `false` | Click again after a hold and flip back to the first theme. |
| `screenshotWidth` | `number` | `MOCK_W` | Natural width of the screenshot in pixels. |
| `screenshotHeight` | `number` | `MOCK_H` | Natural height of the screenshot in pixels. |
| `accent` | `string` | `"#3B5BFD"` | Accent color of the mock UI. |
| `speed` | `number` | `1` | Playback speed multiplier for the whole timeline. |
| `zoom` | `number` | `ZOOM` | Camera zoom on the toggle around the click. 1 means no push-in. |
| `ground` | `GshPresetId` | — | Shader preset id for the animated background. |
| `groundParams` | `Partial<GradientParams>` | — | Partial shader parameters that override the ground preset. |

## Use when
- Showing a dark mode or theme switch as a circular reveal flooding out from the toggle.
- A feature beat where the same screen needs to appear in both themes.
- A close camera push on a small control, then a pull back to the full window.

## Don't use when
- The change is a photo being graded rather than a UI theme — use `before-after`.
- The change is the layout adapting to screen sizes — use `device-morph`.
- You want to visit several parts of one screen — use `screenshot-tour`.