This component no longer exists. It was in remotionui’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-11 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
end-card
remotionui/end-cardRemovedBlock
Outro built in the order a viewer acts on it: title, button assembling under its label, address typing, channels, one pulse
Live preview
live · rendered by the registry
Rendered by remotionui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://remotionui.com/r/end-card.jsonSource
1import { loadFont } from "@remotion/google-fonts/Inter";2import { Img, interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion";3import { CODE_THEMES } from "@/remotion/lib/code-syntax";4import { getSafeAreaPadding } from "@/remotion/lib/layout";5import { EASING } from "@/remotion/lib/motion-tokens";67const { fontFamily } = loadFont("normal", {8 weights: ["400", "500", "600", "700"],9 subsets: ["latin"],10});1112export type EndCardProps = {13 title: string;14 /** Line under the title. */15 subtitle?: string;16 /** Chip above the title. */17 eyebrow?: string;18 /** Button label. Omit to end on the title alone. */19 cta?: string;20 /** Address typed under the button. */21 url?: string;22 /** Handles or channels listed along the foot. */23 handles?: string[];24 logoSrc?: string;25 logoSize?: number;26 backgroundColor?: string;27 accentColor?: string;28 theme?: "dark" | "light";29 /** Animation speed multiplier. */30 speed?: number;31};3233/** Beat plan in seconds. */34const T = {35 logo: 0,36 eyebrow: 0.14,37 title: 0.26,38 subtitle: 0.6,39 /** The button assembles, then its label rises out of it. */40 button: 0.82,41 buttonLabel: 0.98,42 /** Address types under the button. */43 url: 1.24,44 handles: 1.6,45 /** Attention pulse once everything is standing. */46 pulse: 2.05,47} as const;4849/** Characters per second the address types at. */50const URL_CPS = 26;5152const clamp = {53 extrapolateLeft: "clamp",54 extrapolateRight: "clamp",55} as const;5657/**58 * The outro built in the order a viewer acts on it: the title lands, the button59 * assembles and its label rises out of it, the address types underneath, the60 * channels list, and a single ring pulses off the button — rather than a stack61 * of text fading in together.62 */63export const EndCard: React.FC<EndCardProps> = ({64 title,65 subtitle,66 eyebrow,67 cta,68 url,69 handles,70 logoSrc,71 logoSize,72 backgroundColor,73 accentColor = "#E8B86D",74 theme = "dark",75 speed = 1,76}) => {77 const frame = useCurrentFrame();78 const { fps, width, height } = useVideoConfig();79 const palette = CODE_THEMES[theme];80 const safe = getSafeAreaPadding({ width, height });8182 const now = (frame / fps) * speed;83 const at = (seconds: number) => (seconds * fps) / speed;84 const ease = (from: number, to: number, easing = EASING.enter) =>85 interpolate(frame, [at(from), at(to)], [0, 1], { easing, ...clamp });8687 const stage = {88 w: width - safe.paddingLeft - safe.paddingRight,89// … truncated
