# Pinned story (goodtabs UI)

A section that pins and walks through its steps as you scroll, a stacked list on phones.

## Install

```bash
npx shadcn@latest add https://ui.goodtabs.co/r/pinned-story.json
```

Or, with the @goodtabs namespace configured in components.json: `npx shadcn@latest add @goodtabs/pinned-story`

## Usage

```tsx
import { PinnedStory, PinnedStoryStep } from "@/components/ui/pinned-story"

<PinnedStory aria-label="How it works">
  <PinnedStoryStep eyebrow="Step 01" title="Collect" description="One line on the step.">
    <img src="/step-one.png" alt="" />
  </PinnedStoryStep>
</PinnedStory>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| pace | `number` | `0.9` | Scroll distance per step on PinnedStory, as a multiple of the viewport height. |
| eyebrow | `string` |  | Short mono label on PinnedStoryStep. |
| title | `ReactNode` |  | The step's heading, required on PinnedStoryStep. |
| description | `ReactNode` |  | One grey line under the title. |
| children | `ReactNode` |  | The visual on the right of the step. |

## When to use

- Explaining a process of three to five steps where order matters
- A product walkthrough with one visual per step
- Once on a landing page, as the section people remember

## When not to use

- For reference content people need to scan: use a list or tabs
- More than once on a page, because two pins back to back feel like a trap
- Inside a scaled or transformed parent, which breaks ScrollTrigger's measuring

## Notes for agents

- GSAP installs from npm under GSAP's own licence. No GSAP code ships in this registry
- It pins against the window, so it must not sit inside an overflow container or a CSS transform
- Below 768px and under reduced motion there is no pin: steps are a plain stacked list
- Give PinnedStory an aria-label, because it renders a section landmark

## The maths

- Total pin distance is (n - 1) × pace × viewport height, so three steps at 0.9 scroll 1.8 screens.
- Each leg rests for 0.4, then copy hands over in sequence while visuals cross-fade for 0.6, so no frame is empty.
- The progress hairline scales from 1 / n to 1 with transform, so it never reflows the steps.

Docs: https://ui.goodtabs.co/components/pinned-story