snapcn
23 components
DocsComponentsTemplatesVideo EditorShowcaseMarketplaceRoadmapChangelog

Getting started

IntroductionInstallationAgent skill
GitHub

Star snapcn

Free, open-source components.

Production-ready Remotion animations, transitions and backgrounds — you own the code.

Star on GitHubXFollow

MIT licensed · own your code.

© 2026 snapcn

DocsComponentsTemplatesVideo EditorShowcaseMarketplaceRoadmapChangelog
Getting startedIntroductionInstallationAgent skill

Answer Stream

The beat after send — a macro shot on the button that cuts hard to the answer building itself, while the camera pulls back to keep up with it

Installation

pnpm
$ pnpm dlx shadcn@latest add @snapcn/answer-stream

Component code

The exact file shadcn add copies into your project.

Usage

It opens where Prompt Zoom leaves you — close on the composer — and carries through the send, the cut, and the answer.

// src/Root.tsx
import { Composition } from "remotion";
import { AnswerStream } from "@/components/snap-cn/answer-stream";

const ReplyScene = () => (
  <AnswerStream
    question="How do I rank higher in AI answers?"
    answer={"Analysing your prompt gaps…\nFound 27 prompts you should rank for and don't yet."}
    headline="Your AI visibility score: 34% — here's how I'd fix it:"
  />
);

export const RemotionRoot = () => (
  <Composition
    id="AnswerStream"
    component={ReplyScene}
    durationInFrames={150}
    fps={30}
    width={1280}
    height={720}
  />
);

Scene to scene, the frame cuts

Read frame by frame, the reference has exactly one grammar for changing shot, and it is a hard cut — one frame wide, no blur, no ramp. What makes the cuts invisible is not a transition. It is what happens either side of them.

Every cut lands on motion. The camera is eight frames into an accelerating push toward the send button when the cut fires. It is moving fastest at the moment it is replaced.

Every cut is followed by a glide, not a stop. The answer page arrives 27px high and settles down over 15 frames on an ease-out. Cut to a static frame and the edit becomes the loudest thing in the shot.

The only moves are inside a shot, and there are two kinds: a slow drift that never quite stops, and one fast blurred push onto whatever is about to happen.

The pull-back is fitted to the content

As the answer grows — paragraph, then headline, then four cards, then the composer sliding up — the camera pulls back and rises to keep the block in frame.

Tracking the column's left and right edges across the move recovers a scale of 1.364× → 1.0 about a fixed point at (0.5, −0.548) of the frame: dead centre horizontally, and 273px above the top edge. Both edges independently agree on that point to within 1px, which is what makes it a measurement rather than a guess. The focal point being above the frame is the whole reason the page appears to rise as it shrinks, instead of collapsing toward its own middle.

Peak velocity sits at 48–52% of the move, which is a cubic in-out and rules out a spring — a spring peaks at a third. Measured back off the rendered frames against the reference's, the two curves start together, end together and part by at most 0.048 of scale near the midpoint.

pullbackFrom is expressed against where the shot settles, not where the pull-back bottoms out. It overshoots its mark by 2.8% and creeps back onto it, and normalising against the bottom of that move instead puts every constant 2.8% out.

The move carries motion blur derived from the camera's own speed — a frame that carries a typical element d px smears it by d/4 — rather than dialled in by eye.

Words arrive hot

Containers land empty and fill: the question pill and each of the four cards appear as a bare surface first, and their text streams in after. Each word lands at accentColor and cools to foreground on a fixed clock, so the lit band at the head of the stream is wordsPerSecond × coolSeconds words wide — six, on the reference — no matter how fast you run it.

Words that have not landed are hidden, not absent. Removing them lets the line reflow underneath and every word already on screen shifts as the next one arrives; on the reference they do not move at all.

Props

propdefault
question—fills the pill, and stays in the composer
answer—\n is a hard break; everything else wraps
headline—lands under the reply, introduces the cards
cardsfour{ title, body, icon? } — icon is an SVG path on a 24×24 box
commitAt1.0when the push into the button starts accelerating
cutAt1.284when the shot cuts. One frame, never a ramp
pullbackAt1.933when the camera starts keeping up
pullbackDuration1.1
pullbackFrom1.364relative to where the shot settles
pullbackUndershoot0.028how far past its mark it goes first
focusX / focusY0.5 / -0.548above the frame, on purpose
macroZoom2.36the opening shot on the send button
wordsPerSecond25
coolSeconds0.23how long a word stays lit
blur3ceiling on the camera's motion blur

Plus accentColor, theme, mode and speed, like every other component.

Notes

The preview above plays a rendered mp4, not a live <Player>. The pull-back re-shapes every line of type on the page at a new size for 33 consecutive frames; a frame that misses its budget in the browser is shown for the wrong length of time, and the eye reads that as the answer sticking as it arrives.

The reference has no button press — its cursor is already down when the shot opens, and the accelerating push does all the work. Synthesised, the cut needs a visible cause, so there is a three-frame dip on commitAt.

The colours and the copy are not measured. The reference is a specific product with its own coral, its own four icon tints and its own marketing lines; none of that belongs in a component that lands next to somebody else's Input. The paint is the shadcn token set, the composer takes its surface from the Input primitive's own style context, and every string is a prop.