Vercel — Introducing Vercel
Install this video
Adds the full composition, its remocn dependencies, and the prompt to your Remotion project via the shadcn registry.
$ pnpm dlx shadcn@latest add kapishdima/remocn-demo/introducing-vercelRender it locally
Renders the MP4 on your machine with the Remotion CLI.
$ pnpm dlx remotion render introducing-vercel out/introducing-vercel.mp4 --scale=2 --crf=15 --x264-preset=slower --jpeg-quality=95 --gl=angleThe prompt
Reconstructed draftA reconstruction of the prompt this video was generated from.
The code
The exact source the AI wrote — the same files the install command puts in your project.
import React, { useMemo } from "react";
import {
AbsoluteFill,
Easing,
Sequence,
interpolate,
spring,
useCurrentFrame,
useVideoConfig,
} from "remotion";
import {
TransitionSeries,
linearTiming,
type TransitionPresentation,
type TransitionPresentationComponentProps,
} from "@remotion/transitions";
import { fade } from "@remotion/transitions/fade";
import { loadFont as loadSans } from "@remotion/google-fonts/Geist";
import { loadFont as loadMono } from "@remotion/google-fonts/GeistMono";
import { ShaderGrainGradient } from "@/components/remocn/shader-grain-gradient";
import { ShaderGodRays } from "@/components/remocn/shader-god-rays";
import { ScaleDownFade } from "@/components/remocn/scale-down-fade";
import { trianglePortal } from "./triangle-portal";
import { seamlessZoom, type ZoomRect } from "./seamless-zoom";
import { PrismSpin } from "./prism-spin";
// Vercel speaks Geist: 400–600 for everything spoken, Geist Mono 400 only for
// shell commands and URLs-as-chrome.
const { fontFamily: SANS_FAMILY } = loadSans("normal", {
subsets: ["latin"],
weights: ["400", "500", "600"],
});
const { fontFamily: MONO_FAMILY } = loadMono("normal", {
subsets: ["latin"],
weights: ["400"],
});
const SANS = `${SANS_FAMILY}, -apple-system, BlinkMacSystemFont, sans-serif`;
const MONO = `${MONO_FAMILY}, ui-monospace, SFMono-Regular, monospace`;
// Register sampled from vercel.com + the official OG hero. The spec allows
// Vercel blue #0070f3 in at most two moments IF verifiable against their live
// design-system tokens — it was not verifiable at build time (only a hover
// #0B7BFE surfaces; token definitions aren't exposed), so per the spec's own
// fallback this cut ships fully monochrome.
const BG = "#000000";
const INK = "#ededed";
const BRIGHT = "#fafafa";
const MUTED = "#a1a1a1";
const CARD = "#111111";
const HAIRLINE = "rgba(237,237,237,0.14)";
const clampOpts = {
extrapolateLeft: "clamp" as const,
extrapolateRight: "clamp" as const,
};
const easeOut = Easing.out(Easing.cubic);
const easeSoft = Easing.bezier(0.2, 0.8, 0.2, 1);
// ---------------------------------------------------------------------------
// Scene timings (frames @ 30fps). ONE continuous camera flight — there are no
// hard cuts anywhere; every transition below is a camera move. The flight:
// eclipse → through the triangle (portal) → terminal → into the cursor
// (match-cut) → preview browser → into the favicon (portal) → edge field →
// pull-back onto a prism face → creed → the void carries two crossfades →
// drift back out to the eclipse we started at.
// ---------------------------------------------------------------------------
const S_ECLIPSE = 92; // the OG hero rebuilt live + the pain line
const S_DEVELOP = 140; // terminal alone in space, git push types itself
const S_PREVIEW = 146; // browser card, preview URL, comment pin
const S_SHIP = 148; // the page multiplying across the edge field
const S_CREED = 136; // prism spin + Develop. Preview. Ship.
const S_AGENTS = 108; // AI SDK / Sandbox / Gateway block
const S_PROOF = 112; // Zapier + Notion receipts
const S_RETURN = 152; // back at the eclipse; the lockup settles
const T_PORTAL_1 = 26; // fly through the triangle
const T_CURSOR = 26; // match-cut into the block cursor
const T_PORTAL_2 = 26; // fly through the favicon
const T_PULLBACK = 28; // the Ship world recedes onto its prism face
const T_FADE_1 = 16; // the void is one world
const T_FADE_2 = 14;
const T_DRIFT = 30; // the monolith was behind us all along
export const INTRODUCING_VERCEL_DURATION =
S_ECLIPSE +
S_DEVELOP +
S_PREVIEW +
S_SHIP +
S_CREED +
S_AGENTS +
S_PROOF +
S_RETURN -
(T_PORTAL_1 +
T_CURSOR +
T_PORTAL_2 +
T_PULLBACK +
T_FADE_1 +
T_FADE_2 +
T_DRIFT);
// ---------------------------------------------------------------------------
// Shared flight geometry. The transitions ARE the camera moves, so the rects
// they dive into are named constants, not magic numbers.
// ---------------------------------------------------------------------------
// The terminal window (frame 2) and its block cursor after "git push ".
const TERM = { x: 190, y: 120, w: 900, h: 480, chrome: 40, pad: 24, fs: 22 };
const TERM_CHAR_W = TERM.fs * 0.6;
const TERM_LINE_H = 34;
const TERM_PROMPT = "$";
const TERM_CMD = "git push";
const CURSOR_W = TERM_CHAR_W;
const CURSOR_H = TERM.fs * 1.2;
const CURSOR_X =
TERM.x +
TERM.pad +
(TERM_PROMPT.length + 1 + TERM_CMD.length) * TERM_CHAR_W +
3;
const CURSOR_Y =
TERM.y + TERM.chrome + TERM.pad + (TERM_LINE_H - CURSOR_H) / 2;
const CURSOR_RECT: ZoomRect = {
x: CURSOR_X,
y: CURSOR_Y,
width: CURSOR_W,
height: CURSOR_H,
};
// The browser card (frame 3): tab strip, address bar, then the light page —
// the page IS the surface the cursor match-cuts into, so they share a color.
const BROW = { x: 170, y: 64, w: 940, h: 530, tab: 36, address: 40 };
const PAGE_RECT: ZoomRect = {
x: BROW.x,
y: BROW.y + BROW.tab + BROW.address,
width: BROW.w,
height: BROW.h - BROW.tab - BROW.address,
};
const PAGE_BG = INK; // must equal the cursor ink for the invisible crossover
const FAVICON_CX = BROW.x + 8 + 14 + 7;
const FAVICON_CY = BROW.y + BROW.tab / 2;
// The prism (frame 5): the Ship world recedes onto its front face.
const PRISM_W = 520;
const PRISM_H = 300;
const PRISM_CX = 640;
const PRISM_CY = 302;
// ---------------------------------------------------------------------------
// Small shared pieces
// ---------------------------------------------------------------------------
// Barely-there push-in so no frame is ever static — the camera never rests.
const Drift: React.FC<{ children: React.ReactNode; grow?: number }> = ({
children,
grow = 0.03,
}) => {
const frame = useCurrentFrame();
const { durationInFrames } = useVideoConfig();
const scale = interpolate(frame, [0, durationInFrames], [1, 1 + grow]);
return (
<AbsoluteFill style={{ transform: `scale(${scale})` }}>
{children}
</AbsoluteFill>
);
};
// The narration line for a beat — words rise out of blur, muted, beneath the
// visual that acts them out.
const CaptionRise: React.FC<{
text: string;
y: number;
delay?: number;
fontSize?: number;
color?: string;
}> = ({ text, y, delay = 0, fontSize = 26, color = MUTED }) => {
const frame = useCurrentFrame();
const words = text.split(" ");
return (
<div
style={{
position: "absolute",
left: 0,
right: 0,
top: y,
display: "flex",
justifyContent: "center",
whiteSpace: "pre",
}}
>
<span
style={{
fontFamily: SANS,
fontWeight: 400,
fontSize,
color,
lineHeight: 1.3,
}}
>
{words.map((word, i) => {
const p = interpolate(frame - delay - i * 3, [0, 20], [0, 1], {
...clampOpts,
easing: easeSoft,
});
return (
<span
key={i}
style={{
display: "inline-block",
whiteSpace: "pre",
opacity: p,
transform: `translateY(${(1 - p) * 16}px)`,
filter: p < 1 ? `blur(${(1 - p) * 6}px)` : undefined,
}}
>
{word}
{i < words.length - 1 ? " " : ""}
</span>
);
})}
</span>
</div>
);
};
// Odometer digits in Geist Mono — the register's own figures. Each column
// travels its own magnitude and lands EXACTLY on its final digit (the
// registry rolling-number math) — a naive `(current / pow) % 10` leaves
// higher columns resting between digits when the final value isn't a
// multiple of their place (38 would rest with its tens at 3.8).
const wrap10 = (v: number) => ((v % 10) + 10) % 10;
const RollDigits: React.FC<{
from: number;
to: number;
progress: number;
fontSize: number;
color?: string;
}> = ({ from, to, progress, fontSize, color = BRIGHT }) => {
const current = from + (to - from) * progress;
const up = to >= from;
const diff = Math.abs(to - from);
const places = String(Math.max(1, Math.round(Math.max(from, to)))).length;
const cellH = fontSize * 1.08;
const cols: React.ReactNode[] = [];
for (let place = places - 1; place >= 0; place--) {
const pow = 10 ** place;
const startDigit = Math.floor(from / pow) % 10;
const finalDigit = Math.floor(to / pow) % 10;
const fullTurns = Math.floor(diff / (pow * 10));
const step = up
? (finalDigit - startDigit + 10) % 10
: (startDigit - finalDigit + 10) % 10;
const travel = (fullTurns * 10 + step) * (up ? 1 : -1);
const pos = wrap10(startDigit + progress * travel);
const reveal =
place === 0
? 1
: interpolate(current, [pow * 0.92, pow], [0, 1], clampOpts);
cols.push(
<span
key={place}
style={{
display: "inline-block",
overflow: "hidden",
height: cellH,
width: reveal > 0.02 ? "0.62em" : 0,
opacity: reveal,
verticalAlign: "bottom",
textAlign: "center",
}}
>
<span
style={{
display: "flex",
flexDirection: "column",
transform: `translateY(${-pos * cellH}px)`,
}}
>
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((d, i) => (
<span key={i} style={{ height: cellH, lineHeight: `${cellH}px` }}>
{d}
</span>
))}
</span>
</span>,
);
}
return (
<span
style={{
display: "inline-flex",
fontFamily: MONO,
fontWeight: 400,
fontSize,
color,
fontVariantNumeric: "tabular-nums",
lineHeight: 1.08,
}}
>
{cols}
</span>
);
};
// The ▲ — one SVG triangle, filled.
const Triangle: React.FC<{
size: number;
color: string;
style?: React.CSSProperties;
}> = ({ size, color, style }) => (
<svg
width={size}
height={size * 0.882}
viewBox="0 0 100 88.2"
style={{ display: "block", ...style }}
>
<path d="M50 0 L100 88.2 L0 88.2 Z" fill={color} />
</svg>
);
// ---------------------------------------------------------------------------
// The eclipse — the OG hero rebuilt live from shaders: god-rays behind a
// black triangle occluder over the grain. The rim light exists ONLY behind
// the occluder (the sanctioned lighting event); type is never backlit.
// ---------------------------------------------------------------------------
const Eclipse: React.FC<{
/** triangle height in px */
size: number;
cx: number;
cy: number;
raysOpacity: number;
glow: number;
scale?: number;
}> = ({ size, cx, cy, raysOpacity, glow, scale = 1 }) => {
const w = size / 0.882;
return (
<>
<AbsoluteFill style={{ opacity: raysOpacity }}>
<ShaderGodRays
speed={0.3}
colorBack={BG}
colorBloom="#26262b"
colors={["#3c3c44", "#55555e", "#e9e9ee", "#2b2b31"]}
intensity={0.6}
density={0.26}
bloom={0.42}
/>
{/* Keep the light an edge event — pull the field back to black. */}
<AbsoluteFill
style={{
background:
"radial-gradient(90% 90% at 50% 50%, rgba(0,0,0,0.28) 0%, rgba(0,0,0,0.92) 74%)",
}}
/>
</AbsoluteFill>
<div
style={{
position: "absolute",
left: cx,
top: cy,
transform: `translate(-50%, -50%) scale(${scale})`,
}}
>
{/* Rim light hugging the edges — a blurred white copy just behind. */}
<div
style={{
position: "absolute",
left: "50%",
top: "50%",
transform: "translate(-50%, -50%) scale(1.045)",
filter: `blur(${Math.max(6, size * 0.055)}px)`,
opacity: glow,
}}
>
<Triangle size={w} color="#f3f3f5" />
</div>
<div
style={{
position: "relative",
transform: "translate(0, 0)",
}}
>
<Triangle size={w} color="#000000" />
</div>
</div>
</>
);
};
// ===========================================================================
// Frame 1 — The eclipse. Black void, film grain, the backlit triangle, and
// one line landing solo beneath it.
// ===========================================================================
const ECLIPSE_CY = 308;
const EclipseScene: React.FC = () => {
const frame = useCurrentFrame();
const raysIn = interpolate(frame, [0, 20], [0, 1], {Showing the first 400 of 1821 lines. View the full file on GitHub.