Kinetic Typography

Launch Title Sequence

A launch-style sequence of title cards, each with its own entrance (blur-in, word stagger, punch, oversized pan, gradient keyword), background flips between cards and an optional HUD, played automatically or on scroll.

This is a WebberUI Pro component

The install command below needs a licence to run; without one it returns 401.

How to install Pro components →See the plans →

The one-card-after-another titles from a product launch video, as a React component. Each card picks one of five entrances — the whole line pulling into focus from a blur, words rising in a stagger, an all-caps punch that lands with a small shake, oversized type panning slowly across the hold, or a keyword filled with a gradient that sweeps once. Between cards the background crossfades, or hard-cuts to a new color for a "color flip". autoplay mode plays on a timer inside a fixed stage and pauses when it leaves the screen; scroll mode gives each card its own section and plays whichever card you scroll to. The corner HUD (counter, blinking dot, timecode, L-shaped brackets) can be turned off.

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add "https://webberui.com/r/launch-title-sequence.en.json?t=<install token>"

New project or installation trouble? Start here →

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

2200
Active edited usageDefault props
<LaunchTitleSequence/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

Installation

npx webberui@latest add "https://webberui.com/r/launch-title-sequence.en.json?t=<install token>"

Or, once registries are configured in components.json, install it as @webberui/launch-title-sequence.

Usage

import {
  LaunchTitleSequence,
  type LaunchTitleCard,
} from "@/components/ui/launch-title-sequence";

const cards: LaunchTitleCard[] = [
  { eyebrow: "Introducing", headline: "Lumen Notes", entrance: "punch", bg: "#0a0a0a", fg: "#fafafa" },
  { headline: "Everything you write, **always findable**.", entrance: "gradient", bg: "#ffffff", fg: "#171717" },
  { headline: "Syncs offline, updates instantly across every device.", entrance: "words", bg: "#262626", fg: "#f5f5f5" },
  { headline: "Start today", sub: "Free download", entrance: "pan", bg: "#2563eb", fg: "#ffffff", transition: "cut" },
];

// Autoplay (fixed 16:9 stage)
<LaunchTitleSequence cards={cards} className="rounded-xl" />

// Switch with the page scroll (each card gets a 100vh section)
<LaunchTitleSequence cards={cards} mode="scroll" />

Props

PropTypeDefaultDescription
cardsLaunchTitleCard[]—Title cards, played in order
mode"autoplay" | "scroll""autoplay"autoplay: a fixed stage played on a timer; scroll: each card takes one section and switches as you scroll
transition"crossfade" | "cut""crossfade"Background transition between cards: crossfade or cut
holdnumber2200Default time per card in ms; falls back to --wb-kts-hold, then 2200
loopbooleantrueWhether autoplay returns to the first card after the last one
pausedbooleanfalsePause autoplay from outside (works alongside the built-in pause button; either one pauses)
hudbooleantrueShow the HUD overlay (counter, blinking dot, timecode, corner brackets)
heightnumber | string—autoplay: stage height (16:9 when omitted); scroll: section height per card (100vh when omitted)
scrollContainerRefObject<HTMLElement | null>—Scroll container for scroll mode; follows the page scroll when omitted
indexnumber—Controlled current card index (autoplay only; in scroll mode the scroll position decides)
defaultIndexnumber0Initial card index in uncontrolled mode
onCardChange(index: number) => void—Called when the current card changes, with the new index
classNamestring—Passed to the outermost container

LaunchTitleCard

FieldTypeDefaultDescription
eyebrowstring—Small line above the headline (e.g. "Introducing"), fades in with wide tracking
headlinestring—Headline; with the gradient entrance, keywords wrapped in **double asterisks** get the gradient
substring—Subline under the headline, fades in 200ms after the headline lands
entrance"blur" | "words" | "punch" | "pan" | "gradient"—How the headline enters
bgstring—Card background (any CSS color or gradient); defaults to a neutral surface that follows dark mode
fgstring—Card text color; pass it alongside a custom bg
holdnumber—How long this card stays, in ms; overrides the sequence-wide hold
transition"crossfade" | "cut"—Background transition used when entering this card; overrides the sequence-wide transition

How it works

  • Five entrances: blur brings the whole line from blur(16px) into focus while opacity and an 8px offset settle; words staggers word by word (whitespace for English, Intl.Segmenter for Chinese with a per-character fallback, punctuation merged into the previous word); punch sets the line in caps and springs it down from 1.3×, shaking the card 2px as it lands; pan moves oversized type linearly from right to left across the hold, clipped by the stage; gradient enters with blur and fills **keywords** with gradient text that sweeps once.
  • Order: the eyebrow fades in first over 300ms with wide tracking, then the headline; the sub fades in 200ms after the headline finishes.
  • Timing variables: --wb-kts-blur-duration (700ms), --wb-kts-stagger (60ms), --wb-kts-hold (2200ms), --wb-kts-crossfade (500ms), --wb-kts-sweep-duration (1200ms), --wb-kts-gradient (a blue → violet → pink linear gradient). Override them on a wrapper or globally.
  • autoplay: timed with requestAnimationFrame and paused while the stage is off screen (IntersectionObserver). With loop off it stops on the last card and the button turns into "Replay". The timecode follows real elapsed time.
  • scroll: the outer height is the card count times the section height and the stage is sticky at the top; scroll progress picks the current card. Entrances play only when scrolling forward — scrolling back shows a card in its final state. The timecode is derived from scroll progress. Inside a fixed-height scroll box, pass that box as scrollContainer.

Accessibility

  • Each card is role="group" with aria-roledescription="title card" and labelled "Card n of N" (the Chinese build uses 字幕卡 and 第 n 張,共 N 張); cards that are not current are aria-hidden
  • All text is real text; when a headline is split into words, screen readers get the full sentence and the split spans are aria-hidden
  • The HUD is purely decorative and aria-hidden as a whole
  • In autoplay a focusable pause/play button sits in the bottom-right corner (WCAG 2.2.2), with an aria-label and a focus-visible ring
  • When the system "reduce motion" setting is on, every entrance becomes a 300ms fade, pan stays still, punch does not shake, the HUD dot stops blinking, and hard cuts become fades