remocn ✕ Shadcn UI Kit — New sponsor
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/sponsor-shadcn-ui-kitRender it locally
Renders the MP4 on your machine with the Remotion CLI.
$ pnpm dlx remotion render sponsor-shadcn-ui-kit out/sponsor-shadcn-ui-kit.mp4 --scale=2 --crf=15 --x264-preset=slower --jpeg-quality=95 --gl=angleThe prompt
The prompt this video was generated from.
Make a partner-level sponsor video for Shadcn UI Kit (shadcnuikit.com) — pull their style, logo, and fonts from the site: dark #0a0a0a canvas, #fafafa ink, the indigo #6366f1 accent from the hero gradient, the rounded-square mark with its five diagonal round-cap strokes redrawn in code (measure the stroke centerlines off the shipped logo), Cal Sans headings over Inter body. Keep the family grammar of the other sponsor spots. Backdrop is the paper.design warp shader preset (edge shape, swirl 0.86 with 7 iterations, distortion 0.2, proportion 0.64, shapeScale 0.6, scale 0.9, rotation 160, speed 10) as its own component in this repo, recolored into the kit's indigo family a5b4fc/312e81/0a0a0a and pushed back by a vignette. Open with "Say hello to my new sponsor" in a soft blur-in, reveal the mark drawing its strokes on beside the ink Shadcn UI Kit wordmark with "Launch your projects faster" settling beneath, cut the kit's three pillars into stations — Dashboards / Blocks / Theme generator — each acted out inside a tiny code-drawn fragment of the kit (a mini admin dashboard assembling with counting stat cards, growing chart bars and a self-drawing donut ring, a bento of blocks snapping tile by tile, the same surface re-tinting live as the accent flips indigo to emerald to amber), land "Copy, paste, ship" via kinetic-center-build, stack four value lines line by line, count up to 780 components (plain number, no plus), land "Your next dashboard is already built", and close on the Remocn ✕ Shadcn UI Kit lockup alone, centered, no URL on screen. No letter-spacing, no uppercase, no pills, no badges, no pulsing, compact spacing, no trailing periods, no em-dashes. Dynamic text via soft-blur-in, kinetic-center-build and line-by-line-slide. Push-through and focus-pull between scenes.
The code
The exact source the AI wrote — the same files the install command puts in your project.
import React from "react";
import { AbsoluteFill, Easing, interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion";
import { TransitionSeries, linearTiming, type TransitionPresentation, type TransitionPresentationComponentProps } from "@remotion/transitions";
import { loadFont as loadCalSans } from "@remotion/google-fonts/CalSans";
import { loadFont as loadInter } from "@remotion/google-fonts/Inter";
import { ShadcnUiKitWarp } from "./shadcn-ui-kit-warp";
import { SoftBlurIn } from "@/components/remocn/soft-blur-in";
import { LineByLineSlide } from "@/components/remocn/line-by-line-slide";
import { KineticCenterBuild } from "@/components/remocn/kinetic-center-build";
import { pushThrough } from "@/components/remocn/push-through";
import { focusPull } from "@/components/remocn/focus-pull";
// Shadcn UI Kit speaks in the two voices its own CSS ships: Cal Sans for the
// headings, Inter for the body. Cal Sans ships one weight only — 400
// everywhere.
const { fontFamily: HEADING_FAMILY } = loadCalSans("normal", {
subsets: ["latin"],
weights: ["400"],
});
const { fontFamily: BODY_FAMILY } = loadInter("normal", {
subsets: ["latin"],
weights: ["400", "500", "600"],
});
const HEADING = `${HEADING_FAMILY}, -apple-system, BlinkMacSystemFont, sans-serif`;
const BODY = `${BODY_FAMILY}, -apple-system, BlinkMacSystemFont, sans-serif`;
// Palette lifted from shadcnuikit.com itself: #0a0a0a dark canvas, #fafafa
// ink, #a1a1a1 muted copy, and the indigo #6366f1 that fills the site's hero
// gradient and colors "Shadcn" in its own title art. The theme-generator
// station borrows two of the kit's preset accents.
const BG = "#0a0a0a";
const INK = "#fafafa";
const MUTED = "rgba(250,250,250,0.62)";
const FAINT = "rgba(250,250,250,0.4)";
const INDIGO = "#6366f1";
const EMERALD = "#10b981";
const AMBER = "#f59e0b";
const clampOpts = {
extrapolateLeft: "clamp" as const,
extrapolateRight: "clamp" as const,
};
// ---------------------------------------------------------------------------
// Scene timings (frames @ 30fps). Transitions overlap.
// ---------------------------------------------------------------------------
const S_HOOK = 66; // "Say hello to my new sponsor"
const S_REVEAL = 108; // mark draws on + Shadcn UI Kit wordmark + tagline
const S_KINETIC = 62; // "Copy, paste, ship" center build
const S_STACK = 92; // line-by-line value stack
const S_COUNT = 70; // 780 components count-up
const S_CTA = 70; // "Your next dashboard is already built"
const S_LOCKUP = 120; // Remocn ✕ Shadcn UI Kit + shadcnuikit.com
// What's inside — the kit's three pillars, cut into hard beats.
const STATIONS = [
{ name: "Dashboards", blurb: "12 admin panels, CRM to crypto" },
{ name: "Blocks", blurb: "225 ready sections for marketing and apps" },
{ name: "Theme generator", blurb: "Your brand in one click" },
];
const STATION_DURS = [56, 56, 66];
const S_STATIONS = STATION_DURS.reduce((a, b) => a + b, 0);
const T_PT = 16; // push-through
const T_FP = 16; // focus-pull
const T_X = 14; // crossfade
export const SPONSOR_SHADCN_UI_KIT_DURATION =
S_HOOK +
S_REVEAL +
S_STATIONS +
S_KINETIC +
S_STACK +
S_COUNT +
S_CTA +
S_LOCKUP -
(T_PT + T_FP + T_X + T_X + T_FP + T_X + T_PT);
// ---------------------------------------------------------------------------
// Slow camera drift — every scene rides a barely-there push-in so no frame
// is ever static. durationInFrames is Sequence-scoped inside TransitionSeries.
// ---------------------------------------------------------------------------
const Drift: React.FC<{ children: React.ReactNode; grow?: number }> = ({
children,
grow = 0.035,
}) => {
const frame = useCurrentFrame();
const { durationInFrames } = useVideoConfig();
const scale = interpolate(frame, [0, durationInFrames], [1, 1 + grow]);
return (
<AbsoluteFill style={{ transform: `scale(${scale})` }}>
{children}
</AbsoluteFill>
);
};
// ---------------------------------------------------------------------------
// Per-word rise — each word resolves out of blur while rising onto the
// baseline. The body voice of the spot, in Inter.
// ---------------------------------------------------------------------------
const WordsRise: React.FC<{
text: string;
fontSize: number;
color?: string;
delay?: number;
stagger?: number;
fontFamily?: string;
}> = ({
text,
fontSize,
color = INK,
delay = 0,
stagger = 3,
fontFamily = BODY,
}) => {
const frame = useCurrentFrame();
const ease = Easing.bezier(0.2, 0.8, 0.2, 1);
const words = text.split(" ");
return (
<span
style={{
fontFamily,
fontWeight: 400,
fontSize,
color,
lineHeight: 1.3,
}}
>
{words.map((word, i) => {
const local = frame - delay - i * stagger;
const p = interpolate(local, [0, 24], [0, 1], {
...clampOpts,
easing: ease,
});
// Travel lands at ~60% — the eased tail clicks the word down the pixel
// grid one pixel every few frames; opacity/blur keep the full curve.
const py = interpolate(local, [0, 14], [0, 1], {
...clampOpts,
easing: ease,
});
return (
<span
key={i}
style={{
display: "inline-block",
whiteSpace: "pre",
opacity: p,
transform: `translateY(${(1 - py) * 24}px)`,
filter: p < 1 ? `blur(${(1 - p) * 9}px)` : undefined,
}}
>
{word}
{i < words.length - 1 ? " " : ""}
</span>
);
})}
</span>
);
};
// ---------------------------------------------------------------------------
// The Shadcn UI Kit mark, redrawn in code from the site's logo.png: a rounded
// square carrying five diagonal round-cap strokes — one full center diagonal,
// two mediums flanking it, two short dots in the opposite corners, 180 degree
// symmetric. Centerline endpoints measured off the shipped 1876px logo
// (connected-component analysis), snapped to exact 45 degrees. Inverted to
// ink-on-dark for this canvas. The strokes draw themselves on via pathLength.
// ---------------------------------------------------------------------------
const MARK_STROKES = [
"M25.3 24.8 L75.7 75.2",
"M48.5 24.8 L75.8 52.1",
"M25.2 47.9 L52.5 75.2",
"M71.7 24.6 L75.8 28.7",
"M25.2 71.3 L29.3 75.4",
];
const KitMark: React.FC<{
size: number;
/** Local frame the square starts entering */
enterAt?: number;
/** When true the mark renders fully drawn, no animation */
still?: boolean;
}> = ({ size, enterAt = 0, still = false }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const squareS = still
? 1
: spring({
frame: frame - enterAt,
fps,
config: { damping: 13, stiffness: 160, mass: 0.8 },
});
const squareO = still
? 1
: interpolate(frame, [enterAt, enterAt + 8], [0, 1], clampOpts);
return (
<svg
width={size}
height={size}
viewBox="0 0 100 100"
style={{
opacity: squareO,
transform: `scale(${interpolate(squareS, [0, 1], [0.72, 1])})`,
}}
>
<rect x="2" y="2" width="96" height="96" rx="22" fill={INK} />
{MARK_STROKES.map((d, i) => {
const p = still
? 1
: interpolate(frame, [enterAt + 8 + i * 4, enterAt + 20 + i * 4], [0, 1], {
...clampOpts,
easing: Easing.out(Easing.cubic),
});
return (
<path
key={i}
d={d}
pathLength={1}
stroke={BG}
strokeWidth="8.3"
strokeLinecap="round"
fill="none"
strokeDasharray="1"
strokeDashoffset={1 - p}
/>
);
})}
</svg>
);
};
// The wordmark, plain ink on the dark canvas, Cal Sans throughout.
const KitWordmark: React.FC<{ fontSize: number }> = ({ fontSize }) => (
<span
style={{
fontFamily: HEADING,
fontWeight: 400,
fontSize,
lineHeight: 1,
whiteSpace: "nowrap",
color: INK,
}}
>
Shadcn UI Kit
</span>
);
// ===========================================================================
// Scene 1 — Hook. The family line resolves out of a soft blur.
// ===========================================================================
const HookScene: React.FC = () => (
<Drift>
<AbsoluteFill style={{ padding: "0 90px" }}>
<SoftBlurIn
text="Say hello to my new sponsor"
fontSize={54}
fontWeight={400}
color={INK}
blur={14}
/>
</AbsoluteFill>
</Drift>
);
// ===========================================================================
// Scene 2 — Reveal. The mark draws its strokes on while the wordmark resolves
// out of depth beside it, tagline settling tight beneath.
// ===========================================================================
const RevealScene: React.FC = () => {
const frame = useCurrentFrame();
const p = interpolate(frame, [8, 38], [0, 1], {
...clampOpts,
easing: Easing.out(Easing.cubic),
});
const scale = interpolate(p, [0, 1], [1.1, 1]);
return (
<Drift>
<AbsoluteFill
style={{ alignItems: "center", justifyContent: "center", gap: 14 }}
>
<div style={{ display: "flex", alignItems: "center", gap: 26 }}>
<KitMark size={88} enterAt={2} />
<span
style={{
display: "inline-block",
opacity: p,
transform: `scale(${scale})`,
filter: p < 1 ? `blur(${(1 - p) * 18}px)` : undefined,
}}
>
<KitWordmark fontSize={92} />
</span>
</div>
<WordsRise
text="Launch your projects faster"
fontSize={26}
color={MUTED}
delay={44}
/>
</AbsoluteFill>
</Drift>
);
};
// ===========================================================================
// Scene 3 — What's inside. Three hard-cut stations, each acted out inside a
// tiny code-drawn fragment of the kit itself: a dashboard assembling, a bento
// of blocks snapping in, the theme generator re-tinting the surface live.
// shadcnuikit.com sells real UI, so the spot rebuilds its surfaces in code.
// ===========================================================================
const STATION_STARTS = STATION_DURS.map((_, i) =>
STATION_DURS.slice(0, i).reduce((a, b) => a + b, 0),
);
const PANEL_W = 500;
const PANEL_H = 210;
const panelStyle: React.CSSProperties = {
position: "relative",
width: PANEL_W,
height: PANEL_H,
borderRadius: 14,
border: "1px solid rgba(250,250,250,0.12)",
background: "rgba(20,20,23,0.6)",
overflow: "hidden",
};
// 01 Dashboards — the kit's core surface assembles: sidebar rows slide in,
// stat cards pop with counting figures, chart bars grow, a donut ring draws.
const DashboardIllustration: React.FC<{ frame: number }> = ({ frame }) => {
const { fps } = useVideoConfig();
const ease = Easing.out(Easing.cubic);
const STAT_VALUES = [12480, 3842, 96];
const BAR_HEIGHTS = [30, 46, 36, 60, 44, 70, 52, 80];
const donutP = interpolate(frame, [22, 48], [0, 0.72], {
...clampOpts,
easing: Easing.inOut(Easing.cubic),
});
return (
<div style={panelStyle}>
{/* Sidebar */}
<div
style={{
position: "absolute",
left: 0,
top: 0,
bottom: 0,
width: 88,
borderRight: "1px solid rgba(250,250,250,0.1)",
}}
>
{[0, 1, 2, 3, 4, 5].map((i) => {
const rp = interpolate(frame, [4 + i * 3, 12 + i * 3], [0, 1], {
...clampOpts,
easing: ease,
});
return (
<div
key={i}
style={{
position: "absolute",
left: 14,
top: 18 + i * 28,
width: i === 0 ? 44 : 58,
height: 10,
borderRadius: 5,
background:
i === 1 ? "rgba(99,102,241,0.85)" : "rgba(250,250,250,0.22)",
opacity: rp,
transform: `translateX(${(1 - rp) * -10}px)`,
}}
/>
);
})}
</div>
{/* Stat cards with counting figures */}
{STAT_VALUES.map((value, i) => {
const s = spring({
frame: frame - (8 + i * 4),
fps,
config: { damping: 13, stiffness: 180, mass: 0.7 },
});
const o = interpolate(frame, [8 + i * 4, 14 + i * 4], [0, 1], clampOpts);
const count = interpolate(frame, [12 + i * 4, 36 + i * 4], [0, value], {
...clampOpts,
easing: Easing.out(Easing.poly(3)),
});
return (
<div
key={i}
style={{
position: "absolute",Showing the first 400 of 1160 lines. View the full file on GitHub.