{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "buttons-pill",
  "title": "Pill buttons",
  "description": "Styled buttons: the Pill set. 5 decorative buttons variations (FillButton, CenterFillButton, SwapButton, OutlineFillButton, DotButton) 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-pill.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/* Pill button family: rounded-full outlines plus different fill methods, 5 variations. All are sized, use a framer-motion tap, take colour ONLY from the primary/foreground tokens (guaranteed contrast in both themes) and are reduced-motion safe. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst sizes: Record<StyledSize, string> = {\n  sm: \"h-8 gap-1.5 px-4 text-sm\",\n  md: \"h-9 gap-2 px-5 text-sm\",\n  lg: \"h-10 gap-2 px-6 text-sm\",\n  xl: \"h-12 gap-2.5 px-7 text-base\",\n}\n\nconst base =\n  \"group relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden rounded-full border border-primary/30 bg-transparent 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/* Fill: soldan saga dolan primary yuzey; metin doldukca foreground'a doner. */\nexport function FillButton({ 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.96 }}\n      transition={{ type: \"spring\", stiffness: 400, damping: 20 }}\n      className={cn(base, sizes[size], \"text-foreground transition-colors group-hover:text-primary-foreground hover:text-primary-foreground\", className)}\n      {...props}\n    >\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 origin-left scale-x-0 rounded-full bg-primary transition-transform duration-(--motion-base) ease-(--motion-ease) group-hover:scale-x-100\"\n      />\n      <span className=\"relative flex items-center gap-2\">{children as React.ReactNode}</span>\n    </motion.button>\n  )\n}\n\n/* Center: the primary surface opens from the center to both sides. */\nexport function CenterFillButton({ 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.96 }}\n      transition={{ type: \"spring\", stiffness: 400, damping: 20 }}\n      className={cn(base, sizes[size], \"text-foreground transition-colors group-hover:text-primary-foreground hover:text-primary-foreground\", className)}\n      {...props}\n    >\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 origin-center scale-x-0 rounded-full bg-primary transition-transform duration-(--motion-base) ease-(--motion-ease) group-hover:scale-x-100\"\n      />\n      <span className=\"relative flex items-center gap-2\">{children as React.ReactNode}</span>\n    </motion.button>\n  )\n}\n\n/* Swap: the current label slides up on hover and a primary-grounded copy comes from below. */\nexport function SwapButton({ 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.96 }}\n      transition={{ type: \"spring\", stiffness: 400, damping: 20 }}\n      className={cn(base, sizes[size], \"text-foreground\", className)}\n      {...props}\n    >\n      <span className=\"pointer-events-none flex items-center gap-2 opacity-0\">{children as React.ReactNode}</span>\n      <span className=\"absolute inset-0 flex items-center justify-center gap-2 transition-transform duration-(--motion-base) ease-(--motion-ease) group-hover:-translate-y-full\">\n        {children as React.ReactNode}\n      </span>\n      <span className=\"absolute inset-0 flex translate-y-full items-center justify-center gap-2 bg-primary text-primary-foreground transition-transform duration-(--motion-base) ease-(--motion-ease) group-hover:translate-y-0\">\n        {children as React.ReactNode}\n      </span>\n    </motion.button>\n  )\n}\n\n/* Outline: stays transparent and fills with an inner primary shadow on hover. */\nexport function OutlineFillButton({ 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.96 }}\n      transition={{ type: \"spring\", stiffness: 400, damping: 20 }}\n      className={cn(\n        base,\n        sizes[size],\n        \"text-foreground transition-[color,box-shadow] duration-(--motion-base) hover:text-primary-foreground hover:shadow-[inset_0_0_0_2.5rem_var(--primary)]\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"relative flex items-center gap-2\">{children as React.ReactNode}</span>\n    </motion.button>\n  )\n}\n\n/* Dot: the leading primary dot grows on hover until it fills the button. */\nexport function DotButton({ 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.96 }}\n      transition={{ type: \"spring\", stiffness: 400, damping: 20 }}\n      className={cn(base, sizes[size], \"pl-9 text-foreground transition-colors group-hover:text-primary-foreground hover:text-primary-foreground\", className)}\n      {...props}\n    >\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute left-3 top-1/2 size-2.5 -translate-y-1/2 origin-left rounded-full bg-primary transition-transform duration-(--motion-slow) ease-(--motion-ease) group-hover:scale-[16]\"\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-pill.tsx"
    }
  ],
  "categories": [
    "styled",
    "buttons"
  ],
  "type": "registry:component"
}