{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "buttons-shiny",
  "title": "Shiny buttons",
  "description": "Styled buttons: the Shiny set. 5 decorative buttons variations (ShimmerButton, SheenButton, MetallicButton, SpotlightButton, HolographicButton) on the ai2 token system, powered by framer-motion, reduced-motion aware and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "motion@^12.42.2"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/buttons-shiny.tsx",
      "content": "\"use client\"\n\nimport type * as React from \"react\"\nimport { motion, useReducedMotion, type HTMLMotionProps } from \"motion/react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Shiny button family: 5 variations on light and reflection. All are sized (aligned with the base scale), use framer-motion (motion/react), take colour ONLY from semantic tokens and are reduced-motion safe. The sheens derive from primary-foreground so they are visible over the button in both themes (a plain white glare disappeared in dark). */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst sizes: Record<StyledSize, string> = {\n  sm: \"h-8 gap-1.5 rounded-md px-3 text-sm\",\n  md: \"h-9 gap-2 rounded-lg px-4 text-sm\",\n  lg: \"h-10 gap-2 rounded-lg px-5 text-sm\",\n  xl: \"h-12 gap-2.5 rounded-xl px-6 text-base\",\n}\n\nconst base =\n  \"relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden font-medium whitespace-nowrap outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_i]:text-base [&_i]:leading-none\"\n\ntype Props = HTMLMotionProps<\"button\"> & { size?: StyledSize }\n\n/* Shimmer: a single sweep of light passing over it on hover (foreground sheen). */\nexport function ShimmerButton({ className, size = \"md\", children, ...props }: Props) {\n  const reduce = useReducedMotion()\n  return (\n    <motion.button\n      data-slot=\"styled-button\"\n      whileHover={reduce ? undefined : { scale: 1.03 }}\n      whileTap={reduce ? undefined : { scale: 0.97 }}\n      transition={{ type: \"spring\", stiffness: 400, damping: 20 }}\n      className={cn(base, sizes[size], \"group bg-primary text-primary-foreground\", className)}\n      {...props}\n    >\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent via-primary-foreground/25 to-transparent transition-transform duration-700 ease-out group-hover:translate-x-[130%] motion-reduce:hidden\"\n      />\n      <span className=\"relative flex items-center gap-2\">{children as React.ReactNode}</span>\n    </motion.button>\n  )\n}\n\n/* Sheen: bekleme durumunda bile surekli tekrar eden capraz parlama dongusu. */\nexport function SheenButton({ className, size = \"md\", children, ...props }: Props) {\n  const reduce = useReducedMotion()\n  return (\n    <motion.button\n      data-slot=\"styled-button\"\n      whileTap={reduce ? undefined : { scale: 0.97 }}\n      transition={{ type: \"spring\", stiffness: 400, damping: 20 }}\n      className={cn(base, sizes[size], \"bg-primary text-primary-foreground\", className)}\n      {...props}\n    >\n      <motion.span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-y-0 -left-1/2 w-1/3 -skew-x-12 bg-primary-foreground/20 blur-sm\"\n        animate={reduce ? undefined : { left: [\"-50%\", \"150%\"] }}\n        transition={reduce ? undefined : { duration: 2.4, ease: \"easeInOut\", repeat: Infinity, repeatDelay: 1 }}\n      />\n      <span className=\"relative flex items-center gap-2\">{children as React.ReactNode}</span>\n    </motion.button>\n  )\n}\n\n/* Metallic: token yuzeyden turemis fircalanmis metal gradyani + hover parlamasi. */\nexport function MetallicButton({ className, size = \"md\", children, ...props }: Props) {\n  const reduce = useReducedMotion()\n  return (\n    <motion.button\n      data-slot=\"styled-button\"\n      whileHover={reduce ? undefined : { scale: 1.03 }}\n      whileTap={reduce ? undefined : { scale: 0.97 }}\n      transition={{ type: \"spring\", stiffness: 400, damping: 20 }}\n      className={cn(\n        base,\n        sizes[size],\n        \"group border border-border bg-gradient-to-b from-surface-3 via-surface-2 to-secondary text-foreground\",\n        className\n      )}\n      {...props}\n    >\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-x-0 top-0 h-1/2 bg-gradient-to-b from-foreground/10 to-transparent\"\n      />\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent via-foreground/15 to-transparent transition-transform duration-700 ease-out group-hover:translate-x-[130%] motion-reduce:hidden\"\n      />\n      <span className=\"relative flex items-center gap-2\">{children as React.ReactNode}</span>\n    </motion.button>\n  )\n}\n\n/* Spotlight: a soft light opening from the centre on hover (radial, token). */\nexport function SpotlightButton({ className, size = \"md\", children, ...props }: Props) {\n  const reduce = useReducedMotion()\n  return (\n    <motion.button\n      data-slot=\"styled-button\"\n      whileHover={reduce ? undefined : { scale: 1.03 }}\n      whileTap={reduce ? undefined : { scale: 0.97 }}\n      transition={{ type: \"spring\", stiffness: 400, damping: 20 }}\n      className={cn(base, sizes[size], \"group bg-primary text-primary-foreground\", className)}\n      {...props}\n    >\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 scale-0 rounded-[inherit] bg-[radial-gradient(circle_at_center,color-mix(in_oklch,var(--color-primary-foreground)_35%,transparent),transparent_60%)] opacity-0 transition-all duration-(--motion-base) ease-(--motion-ease) group-hover:scale-100 group-hover:opacity-100\"\n      />\n      <span className=\"relative flex items-center gap-2\">{children as React.ReactNode}</span>\n    </motion.button>\n  )\n}\n\n/* Holographic: cok tonlu (info/success/primary) yaniltici sheen surekli kayar. */\nexport function HolographicButton({ className, size = \"md\", children, ...props }: Props) {\n  const reduce = useReducedMotion()\n  return (\n    <motion.button\n      data-slot=\"styled-button\"\n      whileHover={reduce ? undefined : { scale: 1.03 }}\n      whileTap={reduce ? undefined : { scale: 0.97 }}\n      transition={{ type: \"spring\", stiffness: 400, damping: 20 }}\n      className={cn(\n        base,\n        sizes[size],\n        \"border border-border bg-secondary text-secondary-foreground\",\n        className\n      )}\n      {...props}\n    >\n      <motion.span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 bg-[linear-gradient(110deg,transparent,color-mix(in_oklch,var(--color-info)_50%,transparent),color-mix(in_oklch,var(--color-success)_50%,transparent),color-mix(in_oklch,var(--color-primary)_50%,transparent),transparent)] bg-[length:250%_100%] opacity-70 mix-blend-overlay\"\n        animate={reduce ? undefined : { backgroundPositionX: [\"0%\", \"100%\"] }}\n        transition={reduce ? undefined : { duration: 4, ease: \"linear\", repeat: Infinity }}\n      />\n      <span className=\"relative flex items-center gap-2\">{children as React.ReactNode}</span>\n    </motion.button>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/buttons-shiny.tsx"
    }
  ],
  "categories": [
    "styled",
    "buttons"
  ],
  "type": "registry:component"
}