{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "studio-reflection",
  "title": "Studio Reflection",
  "description": "A chrome-gradient 250+ appears with studio-style reflection and a small caption.",
  "dependencies": ["remotion", "@remotion/google-fonts"],
  "files": [
    {
      "path": "registry/remocn/studio-reflection/index.tsx",
      "content": "\"use client\";\n\nimport { loadFont as loadGeist } from \"@remotion/google-fonts/Geist\";\nimport { loadFont as loadGeistMono } from \"@remotion/google-fonts/GeistMono\";\nimport { loadFont as loadLexendExa } from \"@remotion/google-fonts/LexendExa\";\nimport { useId } from \"react\";\nimport {\n  AbsoluteFill,\n  Easing,\n  interpolate,\n  useCurrentFrame,\n  useVideoConfig,\n} from \"remotion\";\n\nconst exa = loadLexendExa(\"normal\", { weights: [\"400\"], subsets: [\"latin\"] });\nconst geist = loadGeist(\"normal\", { weights: [\"400\"], subsets: [\"latin\"] });\nconst mono = loadGeistMono(\"normal\", { weights: [\"400\"], subsets: [\"latin\"] });\n\nexport interface StudioReflectionProps {\n  value?: string;\n  label?: string;\n  eyebrow?: string;\n  accent?: string;\n  background?: string;\n  speed?: number;\n  theme?: \"dark\" | \"light\";\n}\n\nconst WAVES = [\"#a9c1df\", \"#5479b0\", \"#24467e\", \"#0f1c38\"] as const;\nconst SPECULAR = \"#f4f7ff\";\n\nconst PALETTES = {\n  dark: {\n    bg: \"#0A0A0B\",\n    body: \"#121318\",\n    reflect: SPECULAR,\n    fg: \"#F4F3F0\",\n    muted: \"#8E8D94\",\n    ground: \"#05070d\",\n    grain: 0.06,\n  },\n  light: {\n    bg: \"#F5F4F0\",\n    body: \"#E7E6E2\",\n    reflect: WAVES[3],\n    fg: \"#111113\",\n    muted: \"#6E6C67\",\n    ground: \"#e9ecf2\",\n    grain: 0.035,\n  },\n} as const;\n\nconst EASE_OUT = Easing.bezier(0.22, 1, 0.36, 1);\nconst EASE_GLIDE = Easing.bezier(0.45, 0.05, 0.55, 0.95);\nconst EASE_PARK = Easing.bezier(0.3, 0.1, 0.1, 1);\nconst CLAMP = {\n  extrapolateLeft: \"clamp\",\n  extrapolateRight: \"clamp\",\n} as const;\n\nconst EXA_400 = [\n  362, 361, 494, 781, 748, 967, 852, 271, 492, 492, 496, 707, 363, 480, 356,\n  653, 694, 565, 639, 623, 683, 644, 651, 604, 673, 641, 356, 387, 622, 678,\n  622, 638, 1093, 817, 807, 800, 872, 738, 720, 892, 884, 628, 738, 868, 719,\n  989, 924, 910, 762, 910, 821, 748, 684, 862, 810, 1108, 796, 780, 749, 501,\n  653, 501, 691, 776, 500, 773, 777, 673, 766, 724, 528, 790, 763, 382, 399,\n  721, 360, 1123, 763, 751, 782, 769, 554, 606, 530, 755, 691, 898, 734, 726,\n  582, 550, 337, 550, 642,\n];\nconst CAP = 0.7;\nconst TRACK = -0.035;\n\nfunction textEm(text: string) {\n  let w = 0;\n  for (const ch of text) {\n    const c = ch.charCodeAt(0);\n    w += (c >= 32 && c <= 126 ? EXA_400[c - 32] : 700) / 1000;\n  }\n  return w;\n}\n\nfunction Grain({ opacity }: { opacity: number }) {\n  const id = `g${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`;\n  return (\n    <svg\n      width=\"100%\"\n      height=\"100%\"\n      style={{ position: \"absolute\", inset: 0, opacity, pointerEvents: \"none\" }}\n      aria-hidden\n    >\n      <filter id={id}>\n        <feTurbulence\n          type=\"fractalNoise\"\n          baseFrequency=\"0.9\"\n          numOctaves={2}\n          seed={5}\n          stitchTiles=\"stitch\"\n        />\n        <feColorMatrix values=\"0 0 0 0 0.5  0 0 0 0 0.5  0 0 0 0 0.5  0 0 0 0.9 0\" />\n      </filter>\n      <rect width=\"100%\" height=\"100%\" filter={`url(#${id})`} />\n    </svg>\n  );\n}\n\ntype Band = {\n  from: number;\n  to: number;\n  t0: number;\n  t1: number;\n  core: number;\n  soft: number;\n  peak: number;\n  park?: boolean;\n};\n\nconst BANDS: Band[] = [\n  { from: -0.15, to: 1.2, t0: 6, t1: 30, core: 0.008, soft: 0.03, peak: 1 },\n  { from: -0.35, to: 1.35, t0: 12, t1: 46, core: 0.035, soft: 0.16, peak: 0.8 },\n  { from: -0.15, to: 1.2, t0: 22, t1: 48, core: 0.01, soft: 0.04, peak: 0.95 },\n  {\n    from: -0.25,\n    to: 0.5,\n    t0: 30,\n    t1: 64,\n    core: 0.012,\n    soft: 0.09,\n    peak: 1,\n    park: true,\n  },\n];\nconst HORIZON = 0.5;\n\nexport function StudioReflection({\n  value = \"250+\",\n  label = \"launch-ready scenes, one command away\",\n  eyebrow = \"In the library\",\n  accent = \"#3B5BFD\",\n  background,\n  speed = 1,\n  theme = \"dark\",\n}: StudioReflectionProps) {\n  const frame = useCurrentFrame() * speed;\n  const { width, height } = useVideoConfig();\n  const p = PALETTES[theme];\n  const uid = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n  const clipId = `c${uid}`;\n  const chromeId = `ch${uid}`;\n  const blurId = `b${uid}`;\n\n  const portrait = height > width * 1.1;\n  const s = portrait\n    ? (width / 1280) * 1.5\n    : Math.min(width / 1280, height / 720);\n\n  const chars = [...value].length;\n  const valueEm = textEm(value) + TRACK * Math.max(0, chars - 1);\n  const maxW = width * (portrait ? 0.88 : 0.84);\n  const fs = Math.min(\n    (portrait ? 300 : 330) * s,\n    maxW / Math.max(0.5, valueEm),\n    (height * (portrait ? 0.3 : 0.46)) / CAP,\n  );\n  const capH = CAP * fs;\n  const valueW = valueEm * fs;\n\n  const eyeFs = (portrait ? 22 : 17) * s;\n  const labelFs = (portrait ? 36 : 30) * s;\n  const labelMax = Math.min(width * 0.8, 900 * s);\n  const eyeGap = Math.max(capH * 0.2, 26 * s);\n  const descends = /[$,;()[\\]{}|gjpqy]/.test(value);\n  const labelGap = Math.max(capH * 0.22, 30 * s) + (descends ? fs * 0.14 : 0);\n  const labelLines = label\n    ? Math.max(1, Math.ceil((label.length * 0.52 * labelFs) / labelMax))\n    : 0;\n  const labelH = labelLines * labelFs * 1.3;\n  const groupH =\n    (eyebrow ? eyeFs + eyeGap : 0) + capH + (label ? labelGap + labelH : 0);\n  const top = height / 2 - groupH / 2;\n  const figTop = top + (eyebrow ? eyeFs + eyeGap : 0);\n  const baseline = figTop + capH;\n  const yOf = (v: number) => figTop + v * capH;\n  const x0 = width / 2 - valueW / 2 - fs * 0.1;\n  const x1 = width / 2 + valueW / 2 + fs * 0.1;\n\n  const ambient = interpolate(frame, [0, 40], [0, 1], {\n    ...CLAMP,\n    easing: Easing.bezier(0.5, 0, 0.5, 1),\n  });\n  const parked = BANDS[BANDS.length - 1];\n  const chrome = interpolate(frame, [parked.t1 - 16, parked.t1 + 8], [0, 1], {\n    ...CLAMP,\n    easing: Easing.bezier(0.4, 0, 0.2, 1),\n  });\n\n  const bandEls = BANDS.map((b, i) => {\n    const t = interpolate(frame, [b.t0, b.t1], [0, 1], {\n      ...CLAMP,\n      easing: b.park ? EASE_PARK : EASE_GLIDE,\n    });\n    if (frame < b.t0) return null;\n    const life = b.park\n      ? 1\n      : interpolate(t, [0, 0.08, 0.85, 1], [0, 1, 1, 0], CLAMP);\n    const v = b.from + (b.to - b.from) * t;\n    const y = yOf(v);\n    const core = Math.max(1.2, b.core * capH);\n    const soft = b.soft * capH;\n    const o = life * b.peak;\n    return (\n      <g key={i} opacity={o}>\n        <rect\n          x={x0}\n          y={y - soft - core / 2}\n          width={x1 - x0}\n          height={soft * 2 + core}\n          fill={`url(#${uid}soft)`}\n        />\n        <rect\n          x={x0}\n          y={y - core / 2}\n          width={x1 - x0}\n          height={core}\n          fill={p.reflect}\n        />\n      </g>\n    );\n  });\n\n  const push = interpolate(frame, [0, 120], [1.06, 1], {\n    ...CLAMP,\n    easing: EASE_OUT,\n  });\n  const drift = interpolate(frame, [0, 120], [10 * s, 0], {\n    ...CLAMP,\n    easing: EASE_OUT,\n  });\n\n  const eyeIn = interpolate(frame, [50, 72], [0, 1], {\n    ...CLAMP,\n    easing: EASE_OUT,\n  });\n  const labelIn = interpolate(frame, [56, 82], [0, 1], {\n    ...CLAMP,\n    easing: EASE_OUT,\n  });\n\n  const transparent = background === \"transparent\";\n  const bg = transparent ? \"transparent\" : (background ?? p.bg);\n\n  const hz = HORIZON;\n  const chromeStops: [number, string][] =\n    theme === \"dark\"\n      ? [\n          [0, WAVES[3]],\n          [0.16, WAVES[2]],\n          [hz - 0.18, WAVES[1]],\n          [hz - 0.06, WAVES[0]],\n          [hz - 0.004, SPECULAR],\n          [hz + 0.004, \"#0b1226\"],\n          [hz + 0.18, WAVES[3]],\n          [0.84, WAVES[2]],\n          [1, WAVES[0]],\n        ]\n      : [\n          [0, WAVES[3]],\n          [0.25, WAVES[2]],\n          [hz - 0.08, WAVES[1]],\n          [hz - 0.004, WAVES[0]],\n          [hz + 0.004, WAVES[3]],\n          [hz + 0.25, WAVES[2]],\n          [1, WAVES[1]],\n        ];\n\n  return (\n    <AbsoluteFill style={{ background: bg, overflow: \"hidden\" }}>\n      {!transparent ? (\n        <div\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            opacity: chrome,\n            background: `radial-gradient(${width * 0.7}px ${height * 0.38}px at 50% ${yOf(hz)}px, color-mix(in oklab, ${WAVES[2]} ${theme === \"dark\" ? 28 : 10}%, transparent) 0%, transparent 100%)`,\n          }}\n        />\n      ) : null}\n\n      <div\n        style={{\n          position: \"absolute\",\n          inset: 0,\n          transform: `translateY(${drift}px) scale(${push})`,\n          transformOrigin: `50% ${(yOf(hz) / height) * 100}%`,\n        }}\n      >\n        {eyebrow ? (\n          <div\n            style={{\n              position: \"absolute\",\n              left: 0,\n              right: 0,\n              top: top,\n              height: eyeFs,\n              display: \"flex\",\n              justifyContent: \"center\",\n              alignItems: \"center\",\n              gap: eyeFs * 0.7,\n              opacity: eyeIn,\n              transform: `translateY(${(1 - eyeIn) * eyeFs * 0.6}px)`,\n            }}\n          >\n            <div\n              style={{\n                width: eyeFs * 0.36,\n                height: eyeFs * 0.36,\n                borderRadius: 1,\n                background: accent,\n              }}\n            />\n            <span\n              style={{\n                fontFamily: mono.fontFamily,\n                fontWeight: 400,\n                fontSize: eyeFs,\n                lineHeight: 1,\n                textTransform: \"uppercase\",\n                letterSpacing: \"0.22em\",\n                marginRight: \"-0.22em\",\n                color: p.muted,\n                whiteSpace: \"nowrap\",\n              }}\n            >\n              {eyebrow}\n            </span>\n          </div>\n        ) : null}\n\n        <svg\n          width={width}\n          height={height}\n          style={{ position: \"absolute\", inset: 0, overflow: \"visible\" }}\n          aria-hidden\n        >\n          <defs>\n            <clipPath id={clipId}>\n              <text\n                x={width / 2}\n                y={baseline}\n                textAnchor=\"middle\"\n                fontFamily={exa.fontFamily}\n                fontWeight={400}\n                fontSize={fs}\n                letterSpacing={`${TRACK}em`}\n              >\n                {value}\n              </text>\n            </clipPath>\n            <linearGradient\n              id={chromeId}\n              gradientUnits=\"userSpaceOnUse\"\n              x1=\"0\"\n              x2=\"0\"\n              y1={yOf(0)}\n              y2={yOf(1)}\n            >\n              {chromeStops.map(([o, c]) => (\n                <stop key={o} offset={o} stopColor={c} />\n              ))}\n            </linearGradient>\n            <linearGradient id={`${uid}soft`} x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n              <stop offset=\"0\" stopColor={p.reflect} stopOpacity={0} />\n              <stop offset=\"0.5\" stopColor={p.reflect} stopOpacity={0.55} />\n              <stop offset=\"1\" stopColor={p.reflect} stopOpacity={0} />\n            </linearGradient>\n            <filter id={blurId} x=\"-10%\" y=\"-50%\" width=\"120%\" height=\"200%\">\n              <feGaussianBlur stdDeviation={3 * s} />\n            </filter>\n          </defs>\n\n          <g clipPath={`url(#${clipId})`}>\n            <rect\n              x={x0}\n              y={yOf(-0.3)}\n              width={x1 - x0}\n              height={capH * 1.6}\n              fill={p.body}\n              opacity={0.35 + 0.65 * ambient}\n            />\n            <rect\n              x={x0}\n              y={yOf(-0.3)}\n              width={x1 - x0}\n              height={capH * 1.6}\n              fill={`url(#${chromeId})`}\n              opacity={chrome}\n            />\n            <g filter={`url(#${blurId})`}>{bandEls}</g>\n            <g>{bandEls}</g>\n          </g>\n        </svg>\n\n        {label ? (\n          <div\n            style={{\n              position: \"absolute\",\n              left: (width - labelMax) / 2,\n              width: labelMax,\n              top: baseline + labelGap,\n              height: labelH + labelFs * 0.4,\n              overflow: \"hidden\",\n            }}\n          >\n            <div\n              style={{\n                transform: `translateY(${(1 - labelIn) * labelFs * 1.4}px)`,\n                opacity: interpolate(labelIn, [0, 0.5], [0, 1], CLAMP),\n                textAlign: \"center\",\n                textWrap: \"balance\",\n                fontFamily: geist.fontFamily,\n                fontWeight: 400,\n                fontSize: labelFs,\n                lineHeight: 1.3,\n                letterSpacing: \"-0.01em\",\n                color: p.muted,\n              }}\n            >\n              {label}\n            </div>\n          </div>\n        ) : null}\n      </div>\n\n      {!transparent ? <Grain opacity={p.grain} /> : null}\n    </AbsoluteFill>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/studio-reflection.tsx"
    }
  ],
  "type": "registry:component"
}
