# Echo Stack
URL: https://remocn.dev/docs/typography/echo-stack

A word focuses in at the center while outline copies of it unfold above and below and keep drifting, like the one clear line on a spinning drum

- Install: `npx shadcn@latest add @remocn/echo-stack`
- Vibe: premium
- Natural length: 26f @ 30fps

## Installation

```bash
npx shadcn@latest add @remocn/echo-stack
```

## Usage

```tsx
// src/Root.tsx
import { AbsoluteFill, Composition } from "remotion";
import { EchoStack } from "@/components/remocn/echo-stack";

const Beat = () => (
  <AbsoluteFill style={{ backgroundColor: "#0a0a0a" }}>
    <EchoStack text="Bold." />
  </AbsoluteFill>
);

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

The word focuses in over 14 frames. From frame 8 the echoes unfold out of it:
the column starts compressed and opens to its full pitch by frame 26. After
that the column keeps scrolling one row every `cycle` frames in `direction`,
and loops without a seam. Echoes are hidden while they pass behind the word
and fade out toward the edges, so only about `echoes` rows show on each side.

The echo outline is built from the filled glyphs with an SVG filter rather than
a text stroke. Variable fonts keep overlapping contours inside letters like M
and K, and a text stroke draws them. The component paints no background and
centers the word in its parent. Sizes scale with `height / 720`.

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `text` | `string` | `"Bold."` | The word at the center |
| `fontSize` | `number` | `170` | Font size in reference px at 720p |
| `fontWeight` | `number` | `800` | Font weight |
| `fontFamily` | `string` | `Inter` | Font family |
| `color` | `string` | `"#fafafa"` | Color of the main word |
| `echoColor` | `string` | `same as color` | Outline color of the echoes |
| `echoes` | `number` | `3` | Echo rows on each side before they fade out |
| `echoOpacity` | `number` | `0.35` | Opacity of the nearest echo |
| `strokeWidth` | `number` | `1.5` | Echo outline width in reference px |
| `direction` | `"up" \| "down"` | `"up"` | Which way the column drifts |
| `cycle` | `number` | `60` | Frames for the column to move one row |
| `speed` | `number` | `1` | Timeline speed multiplier |
| `className` | `string` | — | Optional className passed to the wrapper |

## Use when
- A one-word statement (a value, a promise) should hold the screen for a while and still feel alive.
- You want repetition to add weight to a word without adding any other text.
- A beat in a sequence of single words, where each word gets the same treatment and only the text changes.

## Don't use when
- The word should just appear and stay still — use `focus-blur-resolve`.
- The repeats should run sideways as a strip of text — use `infinite-marquee`.
- The screen should fill with rows of text rather than a column around one word — use `type-wall`.