{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "spotlight",
  "title": "Spotlight",
  "description": "A soft spotlight cone searches the dark stage, overshoots, and lands on the logo before the house lights lift.",
  "dependencies": ["remotion"],
  "files": [
    {
      "path": "registry/remocn/spotlight/index.tsx",
      "content": "\"use client\";\n\nimport type React from \"react\";\nimport { useId } from \"react\";\nimport {\n  AbsoluteFill,\n  Easing,\n  interpolate,\n  spring,\n  useCurrentFrame,\n  useVideoConfig,\n} from \"remotion\";\n\nexport type SpotlightProps = {\n  /** Lockup the beam lands on. Falls back to a placeholder \"remocn\" lockup. */\n  children?: React.ReactNode;\n  /** Color of the light cone and floor pool. */\n  beamColor?: string;\n  /** Dark stage behind everything. */\n  stageColor?: string;\n  /** Brightness of the unlit lockup, 0 to 1. */\n  dim?: number;\n  speed?: number;\n};\n\nexport const spotlightDefaults = {\n  beamColor: \"#FFFFFF\",\n  stageColor: \"#111111\",\n  dim: 0.16,\n  speed: 1,\n};\n\nconst SEARCH = 12;\nconst SWING = 26;\nconst HOUSE = 38;\nconst clamp = {\n  extrapolateLeft: \"clamp\" as const,\n  extrapolateRight: \"clamp\" as const,\n};\n\nconst PLACEHOLDER_FONT =\n  \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Inter, Helvetica, Arial, sans-serif\";\n\n// Neutral lockup shown when no children are passed.\nfunction PlaceholderLockup({\n  mark,\n  dot,\n  text,\n  scale = 1,\n}: {\n  mark: string;\n  dot: string;\n  text: string;\n  scale?: number;\n}) {\n  return (\n    <div style={{ display: \"flex\", alignItems: \"center\", gap: 28 * scale }}>\n      <div\n        style={{\n          width: 120 * scale,\n          height: 120 * scale,\n          borderRadius: 32 * scale,\n          backgroundColor: mark,\n          display: \"flex\",\n          alignItems: \"center\",\n          justifyContent: \"center\",\n        }}\n      >\n        <div\n          style={{\n            width: 36 * scale,\n            height: 36 * scale,\n            borderRadius: \"50%\",\n            backgroundColor: dot,\n          }}\n        />\n      </div>\n      <span\n        style={{\n          fontFamily: PLACEHOLDER_FONT,\n          fontSize: 104 * scale,\n          fontWeight: 800,\n          letterSpacing: \"-0.04em\",\n          color: text,\n        }}\n      >\n        remocn\n      </span>\n    </div>\n  );\n}\n\nexport function Spotlight(props: SpotlightProps) {\n  const { children, beamColor, stageColor, dim, speed } = {\n    ...spotlightDefaults,\n    ...props,\n  };\n  const uid = `spotlight-${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`;\n  const frame = useCurrentFrame();\n  const { width, height, fps } = useVideoConfig();\n  const t = frame * Math.max(0, speed);\n\n  // Beam target, as a fraction of the width: search left, overshoot right, land.\n  let target: number;\n  if (t < SEARCH) {\n    target = interpolate(t, [0, SEARCH], [0.14, 0.27], {\n      ...clamp,\n      easing: Easing.inOut(Easing.sin),\n    });\n  } else if (t < SWING) {\n    target = interpolate(t, [SEARCH, SWING], [0.27, 0.74], {\n      ...clamp,\n      easing: Easing.inOut(Easing.cubic),\n    });\n  } else {\n    const land = spring({\n      frame: t - SWING,\n      fps,\n      config: { damping: 11, stiffness: 120, mass: 0.8 },\n    });\n    target = 0.74 + (0.5 - 0.74) * land;\n  }\n\n  const tx = target * width;\n  const apexX = width / 2;\n  const apexY = -height * 0.12;\n  const floorY = height * 0.8;\n  const spread = width * 0.27;\n  const apexHalf = width * 0.012;\n\n  const beamOn = interpolate(t, [0, 5], [0, 1], {\n    ...clamp,\n    easing: Easing.out(Easing.quad),\n  });\n  const house = interpolate(t, [HOUSE, HOUSE + 12], [0, 1], {\n    ...clamp,\n    easing: Easing.inOut(Easing.sin),\n  });\n  const coverage = Math.max(0, 1 - Math.abs(target - 0.5) / 0.3);\n  const lit = Math.max(\n    dim,\n    dim + (1 - dim) * Easing.inOut(Easing.quad)(coverage) * beamOn,\n  );\n  const brightness =\n    t >= SWING + 10 ? Math.max(lit, Math.min(1, lit + house)) : lit;\n  const blur = width * 0.012;\n\n  return (\n    <AbsoluteFill style={{ backgroundColor: stageColor }}>\n      <AbsoluteFill\n        style={{\n          background: `radial-gradient(ellipse 80% 70% at 50% 40%, ${beamColor} 0%, transparent 70%)`,\n          opacity: 0.09 * house,\n        }}\n      />\n      <svg\n        width={width}\n        height={height}\n        viewBox={`0 0 ${width} ${height}`}\n        style={{ position: \"absolute\", inset: 0 }}\n      >\n        <defs>\n          <linearGradient\n            id={`${uid}-beam`}\n            gradientUnits=\"userSpaceOnUse\"\n            x1={0}\n            y1={apexY}\n            x2={0}\n            y2={floorY}\n          >\n            <stop offset=\"0\" stopColor={beamColor} stopOpacity={0.55} />\n            <stop offset=\"0.6\" stopColor={beamColor} stopOpacity={0.2} />\n            <stop offset=\"1\" stopColor={beamColor} stopOpacity={0.12} />\n          </linearGradient>\n          <radialGradient id={`${uid}-pool`}>\n            <stop offset=\"0\" stopColor={beamColor} stopOpacity={0.45} />\n            <stop offset=\"0.6\" stopColor={beamColor} stopOpacity={0.14} />\n            <stop offset=\"1\" stopColor={beamColor} stopOpacity={0} />\n          </radialGradient>\n          <filter\n            id={`${uid}-soft`}\n            x={-width}\n            y={-height}\n            width={width * 3}\n            height={height * 3}\n            filterUnits=\"userSpaceOnUse\"\n          >\n            <feGaussianBlur stdDeviation={blur} />\n          </filter>\n        </defs>\n        <g opacity={beamOn * (1 - 0.35 * house)}>\n          <ellipse\n            cx={tx}\n            cy={floorY}\n            rx={spread * 1.25}\n            ry={height * 0.07}\n            fill={`url(#${uid}-pool)`}\n          />\n          <polygon\n            points={`${apexX - apexHalf},${apexY} ${apexX + apexHalf},${apexY} ${tx + spread},${floorY} ${tx - spread},${floorY}`}\n            fill={`url(#${uid}-beam)`}\n            filter={`url(#${uid}-soft)`}\n          />\n        </g>\n      </svg>\n      <AbsoluteFill\n        style={{\n          alignItems: \"center\",\n          justifyContent: \"center\",\n          filter: `brightness(${brightness})`,\n        }}\n      >\n        {children ?? (\n          <PlaceholderLockup\n            mark={beamColor}\n            dot={stageColor}\n            text={beamColor}\n          />\n        )}\n      </AbsoluteFill>\n    </AbsoluteFill>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/spotlight.tsx"
    }
  ],
  "type": "registry:component"
}
