{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "shine-border",
  "type": "registry:component",
  "title": "Shine border",
  "description": "A card whose border is a band of coloured light sweeping around it, masked to the border ring so the content is untouched.",
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://ui.minidev.pro/r/button.json",
    "utils"
  ],
  "files": [
    {
      "path": "registry/premium/shine-border.tsx",
      "type": "registry:ui",
      "target": "components/ui/shine-border.tsx",
      "content": "\"use client\"\nimport * as React from \"react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { ArrowRightIcon } from \"lucide-react\"\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\n\n/**\n * A card whose border is a band of coloured light sweeping around it, masked to the border ring so the content is untouched.\n * A conic gradient of your colours turns on a registered CSS angle behind\n * a mask that keeps only the ring, so it stays crisp at any radius. It\n * holds still for reduced motion.\n */\ntype ShineBorderProps = {\n  children?: React.ReactNode\n  /** Colours in the band, in order. Any CSS colour; tokens like var(--accent) work. */\n  colors?: string[]\n  /** Seconds per lap. */\n  duration?: number\n  /** Border width in pixels. */\n  borderWidth?: number\n  /** Corner radius in pixels. */\n  radius?: number\n  className?: string\n}\n\nfunction ShineBorder({ children, colors = [\"var(--accent)\", \"var(--accent-2)\", \"var(--info)\"], duration = 8, borderWidth = 2, radius = 18, className }: ShineBorderProps) {\n  const reduce = useReducedMotion()\n  const list = colors.length ? colors : [\"var(--accent)\"]\n  // The band covers two thirds of the lap and fades back into the plain border at both ends.\n  const span = 240\n  const stops = list.map((c, i) => `${c} ${Math.round(30 + (i * (span - 60)) / Math.max(1, list.length - 1))}deg`).join(\", \")\n  const ring = `conic-gradient(from var(--shine-border-angle), var(--border) 0deg, ${stops}, var(--border) ${span}deg, var(--border) 360deg)`\n  return (\n    <div data-slot=\"shine-border\" className={cn(\"relative isolate mx-auto w-fit max-w-full\", className)} style={{ borderRadius: radius }}>\n      <span\n        aria-hidden\n        className=\"pointer-events-none absolute inset-0 z-10\"\n        style={{\n          borderRadius: radius,\n          padding: borderWidth,\n          background: ring,\n          WebkitMask: \"linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)\",\n          WebkitMaskComposite: \"xor\",\n          mask: \"linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)\",\n          maskComposite: \"exclude\",\n          animation: reduce ? undefined : `shine-border-turn ${duration}s linear infinite`,\n        }}\n      />\n      {children ?? (\n        <div className=\"w-[420px] max-w-full rounded-[inherit] bg-surface p-7 shadow-raised\">\n          <p className=\"text-[12px] font-medium tracking-[0.06em] text-accent-fg uppercase\">Introducing Lumen 3.0</p>\n          <h3 className=\"mt-3 text-2xl font-medium tracking-[-0.03em] text-balance text-fg sm:text-[1.75rem] sm:leading-[1.15]\">Invoices that close themselves</h3>\n          <p className=\"mt-3 text-sm leading-[1.6] text-pretty text-fg-muted\">Lumen chases, reconciles and marks every invoice paid, so you never send another reminder by hand.</p>\n          <Button variant=\"outline\" size=\"sm\" className=\"mt-5\">\n            Read the release notes <ArrowRightIcon />\n          </Button>\n        </div>\n      )}\n      <style>{`@property --shine-border-angle{syntax:\"<angle>\";inherits:false;initial-value:0deg}@keyframes shine-border-turn{to{--shine-border-angle:360deg}}`}</style>\n    </div>\n  )\n}\n\nexport { ShineBorder }\nexport type { ShineBorderProps }\n"
    }
  ]
}
