All demos

shieldcn — Introducing shieldcn Plus

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/shieldcn-plus

Render it locally

Renders the MP4 on your machine with the Remotion CLI.

$ pnpm dlx remotion render shieldcn-plus out/shieldcn-plus.mp4 --scale=2 --crf=15 --x264-preset=slower --jpeg-quality=95 --gl=angle

The prompt

Reconstructed draft

A 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, { useEffect, useMemo, useState, type ReactNode } from "react";
import {
  AbsoluteFill,
  Easing,
  Img,
  Sequence,
  Series,
  continueRender,
  delayRender,
  interpolate,
  interpolateColors,
  spring,
  useCurrentFrame,
  useVideoConfig,
} from "remotion";
import { demoAsset } from "@/lib/demo-assets";
import {
  TransitionSeries,
  linearTiming,
  type TransitionPresentation,
  type TransitionPresentationComponentProps,
} from "@remotion/transitions";
import { loadFont as loadSora } from "@remotion/google-fonts/Sora";

import { RemocnUIProvider } from "@/lib/remocn-ui";
import { ShortSlideRight } from "@/components/remocn/short-slide-right";
import { ClaudeChat } from "@/components/remocn/claude-chat";
import { ShimmerSweep } from "@/components/remocn/shimmer-sweep";
import { LineByLineSlide } from "@/components/remocn/line-by-line-slide";
import { RGBGlitchText } from "@/components/remocn/rgb-glitch-text";
import { RollingNumber } from "@/components/remocn/rolling-number";
import { BlurIn } from "@/components/remocn/blur-in";
import { useBlurInTransition } from "@/components/remocn/use-blur-in-transition";
import { ShaderWarp } from "@/components/remocn/shader-warp";

// The whole video is set in Sora — one family for headlines, URLs, params and
// repo names alike. Nothing goes above weight 500 (reserved for the lockups
// and the rolling stat); everything else is regular 400. The remocn text
// components read var(--font-geist-sans), so feeding Sora into that variable
// re-fonts them without touching library files.
const { fontFamily: SORA_FAMILY } = loadSora("normal", {
  subsets: ["latin"],
  weights: ["400", "500"],
});

const SANS =
  "var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif";
const MONO = "var(--font-geist-mono), ui-monospace, SFMono-Regular, monospace";

// The shieldcn register: zinc canvas, ink, and the badge-value green. The
// violet and amber accents exist ONLY inside the brand-morph scene, and only
// as real renders fetched from shieldcn.dev with color= params.
const BG = "#09090b";
const INK = "#fafafa";
const MUTED = "#a1a1aa";
const FAINT = "rgba(250,250,250,0.45)";
const BORDER = "rgba(255,255,255,0.10)";
// Card surfaces are OPAQUE — the warp backdrop must never bleed through a
// card, only live between them.
const CARD = "#101014";
const GREEN = "#22c55e";
const GREEN_SOFT = "#4ade80";
const VIOLET = "#8b5cf6";
const AMBER = "#f59e0b";

const clampOpts = {
  extrapolateLeft: "clamp" as const,
  extrapolateRight: "clamp" as const,
};

// ---------------------------------------------------------------------------
// Scene timings (frames @ 30fps), one per beat. Transitions overlap.
// ---------------------------------------------------------------------------
const S_FRONTDOOR = 150; // the README assembles itself under a camera glide
// "This is shieldcn." then the category montage — Badges / Charts / Headers,
// each label backed by a REAL shieldcn render, hard-cut one into the next.
const WHAT_INTRO = 54;
const CAT_BADGES = 62;
const CAT_CHARTS = 58;
const CAT_HEADERS = 60;
const S_WHAT = WHAT_INTRO + CAT_BADGES + CAT_CHARTS + CAT_HEADERS;
const S_NEWS = 96; //      now it has accounts — with sync
const S_MEET = 132; //     Meet shieldcn Plus (shield draws on)
const S_SYNC = 138; //     75 saved READMEs, synced
const S_LIBRARY = 126; //  the saved badges library
const S_MIGRATE = 132; //  mass migration PR cascade
// The kinetic build itself takes ~81f (6 words: 10f first + 5 × 13f pushes,
// entering at frame 6) — the beat holds the assembled line for ~20f before
// the squeeze takes it, so the cut never lands mid-build.
const S_AI_TITLE = 118; // "AI generates and polishes your READMEs" (kinetic build + hold)
// AI writes the README — the dark Claude chat types the prompt, then a
// parallax hand-off pushes the chat DOWN while "Thinking" flies UP out of
// it (a gentle initial kick, long deceleration), and the result lands.
const AI_PUSH_AT = 88; //  the chat is pushed away right after typing settles
const AI_PUSH_DUR = 18;
const AI_THINK = 56;
const AI_XFADE = 12; //    thinking → result cross-dissolve overlap
const AI_RESULT = 88;
const S_AI = AI_PUSH_AT + AI_THINK + AI_RESULT;
const S_BRAND = 240; //    one managed brand — the crown
const S_OFFER = 84; //     20% off your first 6 months (line-by-line)
const S_CTA = 170; //      the closing shieldcn lockup
// Post-credits stinger — a hard cut after the lockup (the shared warp
// backdrop carries through, so it reads as a beat after the credits), then
// the promo code catches signal.
const STING_IN = 10; //     black beat before the code flickers on
const STING_CAPTION = 34; // "promo code" label settles after the burst
const STING_EXIT = 96; //   glitch-out burst + upward throw
const S_STINGER = 122;

const T_X = 14; //    crossfade
const T_SQ = 16; //   squeeze — mechanical collapse hidden under a blur envelope
const T_ZOOM = 18; // zoom-blur at section turns
const T_IRIS = 22; // pill-shaped iris reveal into the CTA

export const SHIELDCN_PLUS_DURATION =
  S_FRONTDOOR +
  S_WHAT +
  S_NEWS +
  S_MEET +
  S_SYNC +
  S_LIBRARY +
  S_MIGRATE +
  S_AI_TITLE +
  S_AI +
  S_BRAND +
  S_OFFER +
  S_CTA +
  S_STINGER -
  (T_SQ +
    T_ZOOM +
    T_ZOOM +
    T_SQ +
    T_X +
    T_SQ +
    T_X +
    T_SQ +
    T_ZOOM +
    T_X +
    T_IRIS);

// ---------------------------------------------------------------------------
// Reveal — blur-in wrapper driven by useBlurInTransition.
// ---------------------------------------------------------------------------
const Reveal: React.FC<{
  children: ReactNode;
  delay?: number;
  distance?: number;
  blur?: number;
  duration?: number;
  display?: React.CSSProperties["display"];
}> = ({
  children,
  delay = 0,
  distance = 16,
  blur = 10,
  duration = 20,
  display = "block",
}) => {
  const style = useBlurInTransition(
    [{ at: delay, state: "revealed", duration }],
    { direction: "up", distance, blur },
  );
  return (
    <BlurIn style={style} display={display}>
      {children}
    </BlurIn>
  );
};

// ---------------------------------------------------------------------------
// SlideLine — a short-slide-right line stacked inside a flex column.
// SlideRich — the same motion for rich content (marker highlights etc.).
// ---------------------------------------------------------------------------
const SlideLine: React.FC<{
  text: string;
  at: number;
  fontSize: number;
  color?: string;
  fontWeight?: number;
}> = ({ text, at, fontSize, color = INK, fontWeight = 400 }) => (
  <div
    style={{
      position: "relative",
      width: "100%",
      height: Math.round(fontSize * 1.35),
    }}
  >
    <Sequence from={at} layout="none">
      <ShortSlideRight
        text={text}
        fontSize={fontSize}
        color={color}
        fontWeight={fontWeight}
      />
    </Sequence>
  </div>
);

const SlideRich: React.FC<{ at: number; children: ReactNode }> = ({
  at,
  children,
}) => {
  const frame = useCurrentFrame();
  const easing = Easing.bezier(0.2, 0.8, 0.2, 1);
  const t = frame - at;
  const x = interpolate(t, [0, 16], [-24, 0], { ...clampOpts, easing });
  const opacity = interpolate(t, [0, 10], [0, 1], { ...clampOpts, easing });
  const blurVal = interpolate(t, [0, 16], [1.2, 0], { ...clampOpts, easing });
  return (
    <div
      style={{
        transform: `translateX(${x}px)`,
        opacity,
        filter: `blur(${blurVal}px)`,
      }}
    >
      {children}
    </div>
  );
};

// ---------------------------------------------------------------------------
// ShieldMark — the REAL shieldcn icon path from the repo
// (packages/core/src/icons/shieldcn.svg), stroke-drawing itself on before the
// fill settles in.
// ---------------------------------------------------------------------------
const SHIELD_PATH_A =
  "M148.02,363.76c-4.48,0-8.64-2.42-10.86-6.32l-54.29-95.68c-2.15-3.8-2.15-8.52,0-12.32l54.29-95.68c2.21-3.9,6.37-6.32,10.86-6.32h18.51c4.44,0,8.45,2.28,10.73,6.09,2.27,3.82,2.37,8.43.25,12.33l-42.23,77.99c-3.98,7.36-3.98,16.14,0,23.49l22.22,41.02c4.25,7.85,12.43,12.8,21.36,12.92,0,0,45.08.61,45.11.61,8.68,0,16.83-4.64,21.26-12.12l24.87-41.99c2.23-3.77,6.34-6.11,10.72-6.12l19.47-.04c4.48,0,8.49,2.29,10.76,6.12,2.27,3.83,2.35,8.45.21,12.35l-42.2,77.17c-2.19,4-6.39,6.49-10.95,6.49h-110.08Z";
const SHIELD_PATH_B =
  "M346.7,363.69c-4.44,0-8.45-2.28-10.73-6.09-2.27-3.82-2.37-8.43-.25-12.33l42.23-77.99c3.98-7.35,3.98-16.14,0-23.49l-22.22-41.02c-4.25-7.85-12.44-12.8-21.36-12.92,0,0-46.51-.63-46.53-.63-8.88,0-17.12,4.81-21.48,12.54l-23.35,41.36c-2.2,3.9-6.36,6.34-10.84,6.35l-19.21.04c-4.48,0-8.49-2.29-10.76-6.12-2.27-3.83-2.35-8.45-.22-12.36l42.2-77.17c2.19-4.01,6.39-6.5,10.95-6.5h110.08c4.48,0,8.64,2.42,10.86,6.32l54.29,95.68c2.16,3.8,2.16,8.52,0,12.32l-54.29,95.68c-2.21,3.9-6.37,6.32-10.86,6.32h-18.51Z";

const ShieldMark: React.FC<{ size: number; at?: number }> = ({
  size,
  at = 0,
}) => {
  const frame = useCurrentFrame();
  const draw = (start: number) =>
    interpolate(frame, [at + start, at + start + 26], [1, 0], {
      ...clampOpts,
      easing: Easing.inOut(Easing.cubic),
    });
  const fillOpacity = interpolate(frame, [at + 20, at + 38], [0, 1], {
    ...clampOpts,
    easing: Easing.inOut(Easing.quad),
  });
  const strokeOpacity = interpolate(
    frame,
    [at + 30, at + 44],
    [1, 0],
    clampOpts,
  );
  return (
    <svg width={size} height={size} viewBox="0 0 512 512">
      {[SHIELD_PATH_A, SHIELD_PATH_B].map((d, i) => (
        <path
          key={i}
          d={d}
          pathLength={1}
          strokeDasharray={1}
          strokeDashoffset={draw(i * 6)}
          stroke={INK}
          strokeWidth={10}
          strokeOpacity={strokeOpacity}
          fill={INK}
          fillOpacity={fillOpacity}
        />
      ))}
    </svg>
  );
};

// ===========================================================================
// Scene 1 — The front door, alive. A README assembles itself from REAL
// shieldcn renders while the camera pushes in and glides down the page.
// ===========================================================================
const PAGE_W = 720;
const PAGE_INNER = PAGE_W - 64;

const ProseLine: React.FC<{ width: string; at: number }> = ({ width, at }) => {
  const frame = useCurrentFrame();
  const p = interpolate(frame, [at, at + 12], [0, 1], {
    ...clampOpts,
    easing: Easing.out(Easing.cubic),
  });
  return (
    <div
      style={{
        width,
        height: 10,
        borderRadius: 5,
        background: "rgba(255,255,255,0.08)",
        transform: `scaleX(${p})`,
        transformOrigin: "left center",
      }}
    />
  );
};

const FrontDoorScene: React.FC = () => {
  const frame = useCurrentFrame();
  const { durationInFrames } = useVideoConfig();
  // One continuous camera move: push in while gliding down the page.
  const glide = interpolate(frame, [0, durationInFrames], [26, -470], {
    ...clampOpts,
    easing: Easing.inOut(Easing.quad),
  });
  const zoom = interpolate(frame, [0, durationInFrames], [1.04, 1.17], {
    ...clampOpts,
    easing: Easing.inOut(Easing.quad),
  });
  // The page itself materializes first; the content assembles onto it.
  const pageIn = interpolate(frame, [0, 16], [0, 1], {
    ...clampOpts,
    easing: Easing.out(Easing.cubic),
  });
  return (
    <AbsoluteFill style={{ alignItems: "center" }}>
      <div style={{ transform: `scale(${zoom}) translateY(${glide}px)` }}>
        <div
          style={{
            width: PAGE_W,
            borderRadius: 16,
            border: `1px solid ${BORDER}`,
            background: "#0c0c0e",
            padding: 32,
            display: "flex",
            flexDirection: "column",
            gap: 18,
            opacity: pageIn,
            transform: `translateY(${(1 - pageIn) * 26}px) scale(${0.98 + pageIn * 0.02})`,
          }}
        >
          {/* The real graph header lands first */}
          <Reveal delay={10} distance={18} blur={12} duration={16}>
            <Img
              src={demoAsset("shieldcn/header-graph.svg")}
              style={{ width: PAGE_INNER, height: "auto", display: "block" }}
            />
          </Reveal>
          {/* Three real xs badges snap in one after another */}
          <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
            {["stars-shieldcn-xs", "license-xs", "npm-react-xs"].map(
              (name, i) => (
                <Reveal
                  key={name}
                  delay={20 + i * 5}
                  distance={8}
                  blur={6}
                  duration={10}
                >
                  <Img
                    src={demoAsset(`shieldcn/${name}.svg`)}
                    style={{ height: 22, width: "auto", display: "block" }}
                  />
                </Reveal>
              ),
            )}
          </div>
          {/* Prose skeleton draws on */}
          <div style={{ display: "flex", flexDirection: "column", gap: 9 }}>
            <ProseLine width="94%" at={32} />
            <ProseLine width="100%" at={37} />
            <ProseLine width="72%" at={42} />
          </div>
          {/* The real star-history chart slides into place */}
          <Reveal delay={42} distance={26} blur={14} duration={18}>
            <Img
              src={demoAsset("shieldcn/chart-stars.svg")}
              style={{ width: PAGE_INNER, height: "auto", display: "block" }}
            />
          </Reveal>
          {/* The real sponsor wall settles at the bottom */}
          <Reveal delay={58} distance={26} blur={14} duration={18}>
            <Img
              src={demoAsset("shieldcn/sponsors.svg")}
              style={{ width: PAGE_INNER, height: "auto", display: "block" }}
            />
          </Reveal>
        </div>
      </div>
    </AbsoluteFill>
  );
};

// ===========================================================================
// Scene 2 — What this is. Two beats on the shared Z axis.
// ===========================================================================
const MicroPhase: React.FC<{ children: ReactNode; outAt?: number }> = ({
  children,
  outAt,
}) => {
  const frame = useCurrentFrame();
  const easing = Easing.bezier(0.32, 0.72, 0, 1);
  const opacityIn = interpolate(frame, [0, 18], [0, 1], {
    ...clampOpts,
    easing,
  });
  const scale = interpolate(frame, [0, 18], [0.96, 1], {
    ...clampOpts,

Showing the first 400 of 2250 lines. View the full file on GitHub.