{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "metal-button",
  "type": "registry:ui",
  "title": "Metal Button",
  "author": "Lakshay Bhushan",
  "description": "A shadcn/ui based button but it's made of metal",
  "files": [
    {
      "path": "registry/metal-button/metal-button.tsx",
      "content": "\"use client\";\nimport React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\ntype ColorVariant =\n  | \"default\"\n  | \"primary\"\n  | \"success\"\n  | \"error\"\n  | \"gold\"\n  | \"bronze\";\n\ninterface MetalButtonProps\n  extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n  variant?: ColorVariant;\n}\n\nconst colorVariants: Record<\n  ColorVariant,\n  {\n    outer: string;\n    inner: string;\n    button: string;\n    textColor: string;\n    textShadow: string;\n  }\n> = {\n  default: {\n    outer: \"bg-gradient-to-b from-[#000] to-[#A0A0A0]\",\n    inner: \"bg-gradient-to-b from-[#FAFAFA] via-[#3E3E3E] to-[#E5E5E5]\",\n    button: \"bg-gradient-to-b from-[#B9B9B9] to-[#969696]\",\n    textColor: \"text-white\",\n    textShadow: \"[text-shadow:_0_-1px_0_rgb(80_80_80_/_100%)]\",\n  },\n  primary: {\n    outer: \"bg-gradient-to-b from-[#0051B4] to-[#90C2FF]\",\n    inner: \"bg-gradient-to-b from-[#C4EBFF] via-[#0B3F89] to-[#A6DDFB]\",\n    button: \"bg-gradient-to-b from-[#96C6EA] to-[#2D7CCA]\",\n    textColor: \"text-[#FFF7F0]\",\n    textShadow: \"[text-shadow:_0_-1px_0_rgb(30_58_138_/_100%)]\",\n  },\n  success: {\n    outer: \"bg-gradient-to-b from-[#005A43] to-[#7CCB9B]\",\n    inner: \"bg-gradient-to-b from-[#E5F8F0] via-[#00352F] to-[#D1F0E6]\",\n    button: \"bg-gradient-to-b from-[#9ADBC8] to-[#3E8F7C]\",\n    textColor: \"text-[#FFF7F0]\",\n    textShadow: \"[text-shadow:_0_-1px_0_rgb(6_78_59_/_100%)]\",\n  },\n  error: {\n    outer: \"bg-gradient-to-b from-[#5A0000] to-[#FFAEB0]\",\n    inner: \"bg-gradient-to-b from-[#FFDEDE] via-[#680002] to-[#FFE9E9]\",\n    button: \"bg-gradient-to-b from-[#F08D8F] to-[#A45253]\",\n    textColor: \"text-[#FFF7F0]\",\n    textShadow: \"[text-shadow:_0_-1px_0_rgb(146_64_14_/_100%)]\",\n  },\n  gold: {\n    outer: \"bg-gradient-to-b from-[#917100] to-[#EAD98F]\",\n    inner: \"bg-gradient-to-b from-[#FFFDDD] via-[#856807] to-[#FFF1B3]\",\n    button: \"bg-gradient-to-b from-[#FFEBA1] to-[#9B873F]\",\n    textColor: \"text-[#FFFDE5]\",\n    textShadow: \"[text-shadow:_0_-1px_0_rgb(178_140_2_/_100%)]\",\n  },\n  bronze: {\n    outer: \"bg-gradient-to-b from-[#864813] to-[#E9B486]\",\n    inner: \"bg-gradient-to-b from-[#EDC5A1] via-[#5F2D01] to-[#FFDEC1]\",\n    button: \"bg-gradient-to-b from-[#FFE3C9] to-[#A36F3D]\",\n    textColor: \"text-[#FFF7F0]\",\n    textShadow: \"[text-shadow:_0_-1px_0_rgb(124_45_18_/_100%)]\",\n  },\n};\n\nconst metalButtonVariants = (\n  variant: ColorVariant = \"default\",\n  isPressed: boolean,\n  isHovered: boolean,\n  isTouchDevice: boolean,\n) => {\n  const colors = colorVariants[variant];\n  const transitionStyle = \"all 250ms cubic-bezier(0.1, 0.4, 0.2, 1)\";\n\n  return {\n    wrapper: cn(\n      \"relative inline-flex transform-gpu rounded-full p-[1.25px] will-change-transform\",\n      colors.outer,\n    ),\n    wrapperStyle: {\n      transform: isPressed\n        ? \"translateY(2.5px) scale(0.99)\"\n        : \"translateY(0) scale(1)\",\n      boxShadow: isPressed\n        ? \"0 1px 2px rgba(0, 0, 0, 0.15)\"\n        : isHovered && !isTouchDevice\n          ? \"0 4px 12px rgba(0, 0, 0, 0.12)\"\n          : \"0 3px 8px rgba(0, 0, 0, 0.08)\",\n      transition: transitionStyle,\n      transformOrigin: \"center center\",\n    },\n    inner: cn(\n      \"absolute inset-[1px] transform-gpu rounded-full will-change-transform\",\n      colors.inner,\n    ),\n    innerStyle: {\n      transition: transitionStyle,\n      transformOrigin: \"center center\",\n      filter:\n        isHovered && !isPressed && !isTouchDevice ? \"brightness(1.05)\" : \"none\",\n    },\n    button: cn(\n      \"relative z-10 m-[2.5px] inline-flex h-11 transform-gpu cursor-pointer items-center justify-center overflow-hidden rounded-full px-6 pt-4 pb-5 text-2xl leading-none font-bold will-change-transform outline-none\",\n      colors.button,\n      colors.textColor,\n      colors.textShadow,\n    ),\n    buttonStyle: {\n      transform: isPressed ? \"scale(0.97)\" : \"scale(1)\",\n      transition: transitionStyle,\n      transformOrigin: \"center center\",\n      filter:\n        isHovered && !isPressed && !isTouchDevice ? \"brightness(1.02)\" : \"none\",\n    },\n  };\n};\n\nconst ShineEffect = ({ isPressed }: { isPressed: boolean }) => {\n  return (\n    <div\n      className={cn(\n        \"pointer-events-none absolute inset-0 z-20 overflow-hidden rounded-full transition-opacity duration-300\",\n        isPressed ? \"opacity-20\" : \"opacity-0\",\n      )}\n    >\n      <div className=\"absolute inset-0 bg-gradient-to-r from-transparent via-gray-100 to-transparent\" />\n    </div>\n  );\n};\n\nexport const MetalButton = React.forwardRef<\n  HTMLButtonElement,\n  MetalButtonProps\n>(({ children, className, variant = \"default\", ...props }, ref) => {\n  const [isPressed, setIsPressed] = React.useState(false);\n  const [isHovered, setIsHovered] = React.useState(false);\n  const [isTouchDevice, setIsTouchDevice] = React.useState(false);\n\n  React.useEffect(() => {\n    setIsTouchDevice(\"ontouchstart\" in window || navigator.maxTouchPoints > 0);\n  }, []);\n\n  const buttonText = children || \"Button\";\n  const variants = metalButtonVariants(\n    variant,\n    isPressed,\n    isHovered,\n    isTouchDevice,\n  );\n\n  const handleInternalMouseDown = () => {\n    setIsPressed(true);\n  };\n  const handleInternalMouseUp = () => {\n    setIsPressed(false);\n  };\n  const handleInternalMouseLeave = () => {\n    setIsPressed(false);\n    setIsHovered(false);\n  };\n  const handleInternalMouseEnter = () => {\n    if (!isTouchDevice) {\n      setIsHovered(true);\n    }\n  };\n  const handleInternalTouchStart = () => {\n    setIsPressed(true);\n  };\n  const handleInternalTouchEnd = () => {\n    setIsPressed(false);\n  };\n  const handleInternalTouchCancel = () => {\n    setIsPressed(false);\n  };\n\n  return (\n    <div className={variants.wrapper} style={variants.wrapperStyle}>\n      <div className={variants.inner} style={variants.innerStyle}></div>\n      <button\n        ref={ref}\n        className={cn(variants.button, className)}\n        style={variants.buttonStyle}\n        {...props}\n        onMouseDown={handleInternalMouseDown}\n        onMouseUp={handleInternalMouseUp}\n        onMouseLeave={handleInternalMouseLeave}\n        onMouseEnter={handleInternalMouseEnter}\n        onTouchStart={handleInternalTouchStart}\n        onTouchEnd={handleInternalTouchEnd}\n        onTouchCancel={handleInternalTouchCancel}\n      >\n        <ShineEffect isPressed={isPressed} />\n        {buttonText}\n        {isHovered && !isPressed && !isTouchDevice && (\n          <div className=\"pointer-events-none absolute inset-0 rounded-full bg-gradient-to-t from-transparent to-white/5\" />\n        )}\n      </button>\n    </div>\n  );\n});\n\nMetalButton.displayName = \"MetalButton\";\n",
      "type": "registry:ui",
      "target": "components/metal-button.tsx"
    }
  ]
}