{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "candy-button",
  "type": "registry:ui",
  "title": "Candy Button",
  "description": "Tactile glossy button with specular reflection highlights, multi-layer depth shadows, and full color customization.",
  "dependencies": [
    "clsx",
    "tailwind-merge"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "src/registry/ui/candy-button.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type CandyButtonVariant =\n  | \"emerald\"\n  | \"ruby\"\n  | \"amber\"\n  | \"violet\"\n  | \"azure\"\n  | \"obsidian\"\n  | \"pearl\";\n\nexport type CandyButtonSize = \"sm\" | \"default\" | \"lg\" | \"icon\";\n\nexport interface CandyButtonProps\n  extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n  as?: React.ElementType;\n  href?: string;\n  target?: string;\n  rel?: string;\n  variant?: CandyButtonVariant;\n  size?: CandyButtonSize;\n  color?: string;\n  glow?: boolean;\n  glassSheen?: boolean;\n  leftIcon?: React.ReactNode;\n  rightIcon?: React.ReactNode;\n}\n\nconst variantStyles: Record<CandyButtonVariant, string> = {\n  emerald:\n    \"bg-[radial-gradient(120%_80%_at_50%_70%,#006a66_0%,#003835_100%)] text-white shadow-[0px_4px_24px_-6px_rgba(0,106,102,0.5),inset_0px_1px_4px_0px_rgba(255,255,255,0.4),inset_0px_-2px_4px_0px_rgba(0,0,0,0.15)] hover:shadow-[0px_6px_28px_-4px_rgba(0,106,102,0.65),inset_0px_1px_4px_0px_rgba(255,255,255,0.5),inset_0px_-2px_4px_0px_rgba(0,0,0,0.15)]\",\n  ruby: \"bg-[radial-gradient(120%_80%_at_50%_70%,#e11d48_0%,#9f1239_100%)] text-white shadow-[0px_4px_24px_-6px_rgba(225,29,72,0.5),inset_0px_1px_4px_0px_rgba(255,255,255,0.4),inset_0px_-2px_4px_0px_rgba(0,0,0,0.15)] hover:shadow-[0px_6px_28px_-4px_rgba(225,29,72,0.65),inset_0px_1px_4px_0px_rgba(255,255,255,0.5),inset_0px_-2px_4px_0px_rgba(0,0,0,0.15)]\",\n  amber:\n    \"bg-[radial-gradient(120%_80%_at_50%_70%,#f59e0b_0%,#b45309_100%)] text-white shadow-[0px_4px_24px_-6px_rgba(245,158,11,0.5),inset_0px_1px_4px_0px_rgba(255,255,255,0.4),inset_0px_-2px_4px_0px_rgba(0,0,0,0.15)] hover:shadow-[0px_6px_28px_-4px_rgba(245,158,11,0.65),inset_0px_1px_4px_0px_rgba(255,255,255,0.5),inset_0px_-2px_4px_0px_rgba(0,0,0,0.15)]\",\n  violet:\n    \"bg-[radial-gradient(120%_80%_at_50%_70%,#8b5cf6_0%,#581c87_100%)] text-white shadow-[0px_4px_24px_-6px_rgba(139,92,246,0.5),inset_0px_1px_4px_0px_rgba(255,255,255,0.4),inset_0px_-2px_4px_0px_rgba(0,0,0,0.15)] hover:shadow-[0px_6px_28px_-4px_rgba(139,92,246,0.65),inset_0px_1px_4px_0px_rgba(255,255,255,0.5),inset_0px_-2px_4px_0px_rgba(0,0,0,0.15)]\",\n  azure:\n    \"bg-[radial-gradient(120%_80%_at_50%_70%,#0ea5e9_0%,#0369a1_100%)] text-white shadow-[0px_4px_24px_-6px_rgba(14,165,233,0.5),inset_0px_1px_4px_0px_rgba(255,255,255,0.4),inset_0px_-2px_4px_0px_rgba(0,0,0,0.15)] hover:shadow-[0px_6px_28px_-4px_rgba(14,165,233,0.65),inset_0px_1px_4px_0px_rgba(255,255,255,0.5),inset_0px_-2px_4px_0px_rgba(0,0,0,0.15)]\",\n  obsidian:\n    \"bg-[radial-gradient(120%_80%_at_50%_70%,#3f3f46_0%,#18181b_100%)] text-zinc-100 border border-white/10 shadow-[0px_4px_20px_-6px_rgba(0,0,0,0.4),inset_0px_1px_3px_0px_rgba(255,255,255,0.25),inset_0px_-2px_4px_0px_rgba(0,0,0,0.2)] hover:shadow-[0px_6px_24px_-4px_rgba(0,0,0,0.5),inset_0px_1px_3px_0px_rgba(255,255,255,0.35),inset_0px_-2px_4px_0px_rgba(0,0,0,0.2)]\",\n  pearl:\n    \"bg-[radial-gradient(120%_80%_at_50%_70%,#ffffff_0%,#e4e4e7_100%)] text-zinc-950 shadow-[0px_4px_20px_-6px_rgba(255,255,255,0.35),inset_0px_1px_3px_0px_rgba(255,255,255,0.9),inset_0px_-2px_4px_0px_rgba(0,0,0,0.08)] hover:shadow-[0px_6px_24px_-4px_rgba(255,255,255,0.45),inset_0px_1px_3px_0px_rgba(255,255,255,1),inset_0px_-2px_4px_0px_rgba(0,0,0,0.08)]\",\n};\n\nconst sizeStyles: Record<CandyButtonSize, string> = {\n  sm: \"h-8 px-3.5 text-xs rounded-lg gap-1.5 [&_svg]:size-3.5\",\n  default: \"h-10 px-5 text-sm rounded-xl gap-2 [&_svg]:size-4\",\n  lg: \"h-12 px-7 text-base rounded-2xl gap-2.5 [&_svg]:size-5\",\n  icon: \"size-10 p-0 rounded-xl gap-0 [&_svg]:size-4\",\n};\n\nexport const CandyButton = React.forwardRef<\n  HTMLElement,\n  CandyButtonProps\n>(\n  (\n    {\n      as,\n      className,\n      children,\n      variant = \"emerald\",\n      size = \"default\",\n      color,\n      glow = true,\n      glassSheen = true,\n      leftIcon,\n      rightIcon,\n      style,\n      disabled,\n      ...props\n    },\n    ref,\n  ) => {\n    const isCustom = Boolean(color);\n\n    const customStyle: React.CSSProperties = isCustom\n      ? {\n          background: `radial-gradient(120% 80% at 50% 70%, ${color} 0%, color-mix(in srgb, ${color} 50%, black) 100%)`,\n          boxShadow: glow\n            ? `0px 4px 24px -6px color-mix(in srgb, ${color} 65%, transparent), inset 0px 1px 4px 0px rgba(255, 255, 255, 0.45), inset 0px -2px 4px 0px rgba(0, 0, 0, 0.15)`\n            : `inset 0px 1px 4px 0px rgba(255, 255, 255, 0.45), inset 0px -2px 4px 0px rgba(0, 0, 0, 0.15)`,\n          color: \"#ffffff\",\n          ...style,\n        }\n      : (style ?? {});\n\n    const commonClass = cn(\n      \"relative inline-flex items-center justify-center font-medium leading-none tracking-[0.01em] select-none overflow-hidden cursor-pointer transition-all duration-200 ease-out active:scale-[0.98] active:brightness-95 hover:brightness-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/40 focus-visible:ring-offset-2 focus-visible:ring-offset-black disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed\",\n      \"after:absolute after:top-0 after:left-[15%] after:right-[15%] after:h-px after:bg-[linear-gradient(90deg,transparent,rgba(255,255,255,0.55),transparent)] after:pointer-events-none\",\n      !isCustom && variantStyles[variant],\n      sizeStyles[size],\n      className,\n    );\n\n    const innerContent = (\n      <>\n        {glassSheen && (\n          <span className=\"absolute inset-x-0 top-0 h-1/2 rounded-t-[inherit] bg-[linear-gradient(180deg,rgba(255,255,255,0.12)_0%,transparent_100%)] pointer-events-none\" />\n        )}\n        <span className=\"relative z-10 inline-flex items-center justify-center gap-2\">\n          {leftIcon && <span className=\"shrink-0\">{leftIcon}</span>}\n          {children}\n          {rightIcon && <span className=\"shrink-0\">{rightIcon}</span>}\n        </span>\n      </>\n    );\n\n    if (as === \"a\" || props.href) {\n      return (\n        <a\n          ref={ref as React.Ref<HTMLAnchorElement>}\n          href={props.href}\n          target={props.target}\n          rel={props.rel}\n          style={customStyle}\n          className={commonClass}\n          aria-disabled={disabled}\n          role=\"button\"\n          {...(props as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n        >\n          {innerContent}\n        </a>\n      );\n    }\n\n    return (\n      <button\n        ref={ref as React.Ref<HTMLButtonElement>}\n        disabled={disabled}\n        style={customStyle}\n        className={commonClass}\n        {...props}\n      >\n        {innerContent}\n      </button>\n    );\n  },\n);\n\nCandyButton.displayName = \"CandyButton\";\n\nexport default CandyButton;\n",
      "type": "registry:ui",
      "target": "@ui/candy-button.tsx"
    }
  ]
}
