{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "beacon-badge",
  "title": "Beacon Badge",
  "description": "A status badge with a customizable beacon (ping) animation and blur reveal text.",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "path": "packages/beacon-badge/beacon-badge.tsx",
      "content": "\"use client\";\r\nimport { motion } from \"motion/react\";\r\n\r\nexport type BeaconColor =\r\n  | \"green\"\r\n  | \"blue\"\r\n  | \"purple\"\r\n  | \"yellow\"\r\n  | \"pink\"\r\n  | \"orange\"\r\n  | \"red\"\r\n  | \"white\"\r\n  | \"black\";\r\n\r\nexport type RevealDirection = \"up\" | \"down\" | \"left\" | \"right\" | \"none\";\r\nexport type BorderSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"full\";\r\n\r\nexport interface BeaconBadgeProps {\r\n  label?: string;\r\n  className?: string;\r\n  beconColor?: BeaconColor;\r\n  beconPulses?: boolean;\r\n  speedReveal?: number;\r\n  revealDirection?: RevealDirection;\r\n  staticTheme?: \"dark\" | \"light\";\r\n  border?: BorderSize;\r\n}\r\n\r\nconst colorMap: Record<BeaconColor, { light: string; dark: string }> = {\r\n  green: { light: \"bg-emerald-500\", dark: \"bg-emerald-400\" },\r\n  blue: { light: \"bg-sky-500\", dark: \"bg-sky-400\" },\r\n  purple: { light: \"bg-purple-500\", dark: \"bg-purple-400\" },\r\n  yellow: { light: \"bg-yellow-500\", dark: \"bg-yellow-400\" },\r\n  pink: { light: \"bg-pink-500\", dark: \"bg-pink-400\" },\r\n  orange: { light: \"bg-orange-500\", dark: \"bg-orange-400\" },\r\n  red: { light: \"bg-red-500\", dark: \"bg-red-400\" },\r\n  white: { light: \"bg-zinc-200\", dark: \"bg-white\" },\r\n  black: { light: \"bg-black\", dark: \"bg-zinc-800\" },\r\n};\r\n\r\nconst borderMap: Record<BorderSize, string> = {\r\n  sm: \"rounded-sm\",\r\n  md: \"rounded-md\",\r\n  lg: \"rounded-lg\",\r\n  xl: \"rounded-xl\",\r\n  full: \"rounded-full\",\r\n};\r\n\r\nconst directionMap: Record<\r\n  RevealDirection,\r\n  { initial: { x: number; y: number }; animate: { x: number; y: number } }\r\n> = {\r\n  up: { initial: { x: 0, y: 20 }, animate: { x: 0, y: 0 } },\r\n  down: { initial: { x: 0, y: -20 }, animate: { x: 0, y: 0 } },\r\n  left: { initial: { x: 20, y: 0 }, animate: { x: 0, y: 0 } },\r\n  right: { initial: { x: -20, y: 0 }, animate: { x: 0, y: 0 } },\r\n  none: { initial: { x: 0, y: 0 }, animate: { x: 0, y: 0 } },\r\n};\r\n\r\nconst BeaconBadge = ({\r\n  label = \"50+ Components Available\",\r\n  className,\r\n  beconColor = \"blue\",\r\n  beconPulses = true,\r\n  speedReveal = 3,\r\n  revealDirection = \"up\",\r\n  staticTheme,\r\n  border = \"full\",\r\n}: BeaconBadgeProps) => {\r\n  const colorClass = colorMap[beconColor] || colorMap.blue;\r\n  const { initial, animate } = directionMap[revealDirection];\r\n\r\n  const themeClasses = {\r\n    container:\r\n      staticTheme === \"dark\"\r\n        ? \"border-white/[0.08] bg-white/[0.03]\"\r\n        : staticTheme === \"light\"\r\n          ? \"border-black/[0.08] bg-black/[0.03]\"\r\n          : \"border-black/[0.08] bg-black/[0.03] dark:border-white/[0.08] dark:bg-white/[0.03]\",\r\n    text:\r\n      staticTheme === \"dark\"\r\n        ? \"text-white/60\"\r\n        : staticTheme === \"light\"\r\n          ? \"text-black/60\"\r\n          : \"text-black/60 dark:text-white/60\",\r\n    beacon:\r\n      staticTheme === \"dark\"\r\n        ? colorClass.dark\r\n        : staticTheme === \"light\"\r\n          ? colorClass.light\r\n          : `${colorClass.light} dark:${colorClass.dark}`,\r\n  };\r\n\r\n  return (\r\n    <motion.div\r\n      initial={{ opacity: 0, ...initial }}\r\n      animate={{ opacity: 1, ...animate }}\r\n      transition={{\r\n        duration: 0.5,\r\n        ease: \"easeOut\",\r\n      }}\r\n      className={`inline-flex items-center gap-2 px-3 py-1.5 border backdrop-blur-sm ${borderMap[border]} ${themeClasses.container} ${className || \"\"}`}\r\n    >\r\n      <span className=\"relative flex h-1.5 w-1.5 shrink-0\">\r\n        {beconPulses && (\r\n          <span\r\n            className={`animate-ping absolute inline-flex h-full w-full rounded-full ${themeClasses.beacon} opacity-75`}\r\n          />\r\n        )}\r\n        <span\r\n          className={`relative inline-flex rounded-full h-1.5 w-1.5 ${themeClasses.beacon}`}\r\n        />\r\n      </span>\r\n      <motion.span\r\n        variants={{\r\n          hidden: { opacity: 0 },\r\n          visible: {\r\n            opacity: 1,\r\n            transition: {\r\n              staggerChildren: 0.03 / speedReveal,\r\n              delayChildren: 0.1,\r\n            },\r\n          },\r\n        }}\r\n        initial=\"hidden\"\r\n        animate=\"visible\"\r\n        className={`text-[11px] tracking-widest uppercase font-medium ${themeClasses.text}`}\r\n      >\r\n        {label.split(\"\").map((char, index) => (\r\n          <motion.span\r\n            key={index}\r\n            variants={{\r\n              hidden: { opacity: 0, filter: \"blur(10px)\", y: 5 },\r\n              visible: {\r\n                opacity: 1,\r\n                filter: \"blur(0px)\",\r\n                y: 0,\r\n                transition: {\r\n                  duration: 0.4,\r\n                },\r\n              },\r\n            }}\r\n            className=\"inline-block\"\r\n          >\r\n            {char === \" \" ? \"\\u00A0\" : char}\r\n          </motion.span>\r\n        ))}\r\n      </motion.span>\r\n    </motion.div>\r\n  );\r\n};\r\n\r\nexport default BeaconBadge;\r\n",
      "type": "registry:component",
      "target": "components/satori-ui/beacon-badge.tsx"
    }
  ],
  "type": "registry:component"
}