{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "lamp-effect",
  "type": "registry:component",
  "title": "Lamp effect",
  "description": "A glowing strip light at the top of a dark panel that switches on and widens to light the headline beneath it.",
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://ui.minidev.pro/r/button.json",
    "utils"
  ],
  "files": [
    {
      "path": "registry/premium/lamp-effect.tsx",
      "type": "registry:ui",
      "target": "components/ui/lamp-effect.tsx",
      "content": "\"use client\"\nimport * as React from \"react\"\nimport { motion, useReducedMotion } from \"motion/react\"\nimport { ArrowRight } from \"lucide-react\"\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\n\n/**\n * A glowing strip light at the top of a dark panel that switches on and widens to light the headline beneath it.\n * The lamp is a thin bright line with a soft trapezoid of light falling from\n * it. On first view the line stretches open and the light follows a beat\n * later, with springs. The panel stays dark in both themes by default so the\n * light has something to fall on; reduced motion shows the lamp already on.\n */\ntype LampEffectProps = {\n  /** Width of the lamp line in pixels. The light scales with it and never exceeds the panel. */\n  width?: number\n  /** Any CSS colour, including var(--token). Defaults to the accent. */\n  color?: string\n  /** Strength of the glow, 0 to 2. */\n  glow?: number\n  /** Keep the panel dark in both themes. Turn off to follow the page theme. */\n  dark?: boolean\n  className?: string\n  children?: React.ReactNode\n}\n\n/** Where the lamp line sits, as a share of the panel height. */\nconst LINE = 0.34\n\nconst MORPH = { type: \"spring\", bounce: 0.16, duration: 0.5 } as const\n\nfunction LampEffect({ width = 440, color = \"var(--accent)\", glow = 1, dark = true, className, children }: LampEffectProps) {\n  const reduce = useReducedMotion()\n  const power = Math.min(2, Math.max(0, glow))\n  const w = Math.max(80, width)\n  const vars = {\n    \"--lamp-w\": `min(${w}px, 84cqw)`,\n    \"--lamp-c\": color,\n  } as React.CSSProperties\n  const soft = (pct: number) => `color-mix(in oklch, var(--lamp-c) ${Math.round(pct * Math.min(1.25, power))}%, transparent)`\n  const trapezoid = (top: string) => `polygon(calc(50% - ${top}) 0, calc(50% + ${top}) 0, 100% 100%, 0 100%)`\n  const view = { once: true, amount: 0.3 } as const\n\n  return (\n    <div\n      data-slot=\"lamp-effect\"\n      className={cn(\n        \"@container relative isolate h-[360px] w-full overflow-hidden rounded-2xl border border-border bg-bg\",\n        dark && \"dark\",\n        className\n      )}\n      style={vars}\n    >\n      <div aria-hidden className=\"pointer-events-none absolute inset-0 z-0\">\n        {/* The wide, faint fall of light. Blur is on the wrapper so the clipped shape keeps soft edges. */}\n        <div className=\"absolute inset-x-0 bottom-0\" style={{ top: `${LINE * 100}%`, filter: `blur(${18 + 10 * power}px)` }}>\n          <motion.div\n            className=\"absolute left-1/2 h-full w-[calc(var(--lamp-w)*2.6)] -translate-x-1/2\"\n            style={{\n              clipPath: trapezoid(\"var(--lamp-w) / 2\"),\n              background: `linear-gradient(to bottom, ${soft(42)}, ${soft(16)} 45%, transparent 100%)`,\n              transformOrigin: \"50% 0%\",\n            }}\n            initial={reduce ? false : { scaleX: 0.08, opacity: 0 }}\n            whileInView={{ scaleX: 1, opacity: 1 }}\n            viewport={view}\n            transition={reduce ? { duration: 0 } : { scaleX: { ...MORPH, delay: 0.12 }, opacity: { duration: 0.5, delay: 0.12, ease: [0.2, 0, 0, 1] } }}\n          />\n        </div>\n        {/* A tighter, brighter core right under the line. */}\n        <div className=\"absolute inset-x-0\" style={{ top: `${LINE * 100}%`, height: \"46%\", filter: `blur(${10 + 6 * power}px)` }}>\n          <motion.div\n            className=\"absolute left-1/2 h-full w-[calc(var(--lamp-w)*1.5)] -translate-x-1/2\"\n            style={{\n              clipPath: trapezoid(\"var(--lamp-w) / 2.2\"),\n              background: `linear-gradient(to bottom, ${soft(70)}, ${soft(24)} 40%, transparent 100%)`,\n              transformOrigin: \"50% 0%\",\n            }}\n            initial={reduce ? false : { scaleX: 0.08, opacity: 0 }}\n            whileInView={{ scaleX: 1, opacity: 1 }}\n            viewport={view}\n            transition={reduce ? { duration: 0 } : { scaleX: { ...MORPH, delay: 0.06 }, opacity: { duration: 0.4, delay: 0.06, ease: [0.2, 0, 0, 1] } }}\n          />\n        </div>\n        {/* The housing: a solid block above the line keeps the light below it. */}\n        <div className=\"absolute inset-x-0 top-0 bg-bg\" style={{ height: `${LINE * 100}%` }} />\n        {/* The lamp line and its halo. */}\n        <motion.div\n          data-slot=\"lamp-effect-line\"\n          className=\"absolute left-1/2 h-0.5 w-(--lamp-w) -translate-x-1/2 -translate-y-1/2 rounded-full\"\n          style={{\n            top: `${LINE * 100}%`,\n            background: `linear-gradient(to right, transparent, var(--lamp-c) 12%, var(--lamp-c) 88%, transparent)`,\n            boxShadow: `0 0 ${Math.round(14 * power + 6)}px ${Math.round(2 * power)}px ${soft(60)}, 0 0 ${Math.round(40 * power + 12)}px ${Math.round(6 * power + 2)}px ${soft(28)}`,\n          }}\n          initial={reduce ? false : { scaleX: 0, opacity: 0 }}\n          whileInView={{ scaleX: 1, opacity: 1 }}\n          viewport={view}\n          transition={reduce ? { duration: 0 } : { scaleX: MORPH, opacity: { duration: 0.2 } }}\n        />\n      </div>\n      <div className=\"relative z-10 h-full\">\n        {children ?? (\n          <div className=\"flex h-full flex-col items-center justify-end gap-4 px-6 pb-10 text-center\">\n            <span className=\"rounded-full border border-accent-line bg-accent-soft px-2.5 py-0.5 text-xs font-medium text-accent-fg\">\n              Lumen 3.0\n            </span>\n            <p className=\"max-w-[18ch] text-3xl font-medium tracking-[-0.035em] text-balance text-fg\">\n              Close the books in minutes, not days\n            </p>\n            <Button>\n              See what changed\n              <ArrowRight />\n            </Button>\n          </div>\n        )}\n      </div>\n    </div>\n  )\n}\n\nexport { LampEffect }\nexport type { LampEffectProps }\n"
    }
  ]
}
