{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "button-glass",
  "title": "Button Glass",
  "description": "Liquid-glass button with translucent blurred surface and press states.",
  "dependencies": [],
  "files": [
    {
      "path": "registry/core/button-glass/component.tsx",
      "content": "\"use client\";\n\nimport { useState, type ButtonHTMLAttributes, type PointerEvent } from \"react\";\n\nexport function GlassButton({\n  className = \"\",\n  children,\n  onPointerEnter,\n  onPointerLeave,\n  onPointerDown,\n  onPointerUp,\n  onPointerCancel,\n  ...props\n}: ButtonHTMLAttributes<HTMLButtonElement>) {\n  // Real pointers drive the native `:hover`/`:active` pseudo-classes below just\n  // fine. But a synthetic (`dispatchEvent`, `isTrusted: false`) pointer never\n  // reaches the UA's own hover/activation state machine — Chromium confirmed\n  // not to flip `:hover`/`:active` for script-dispatched events, even though\n  // the same event fires every JS listener bound to it. That left this button\n  // dead in the landing-page card, whose autoplay driver only has synthetic\n  // events to offer. Mirroring both states into JS-tracked data-attributes\n  // (additive, not a replacement) gives the driver something that responds,\n  // without changing anything for a real mouse, touch, or keyboard press.\n  const [hover, setHover] = useState(false);\n  const [pressed, setPressed] = useState(false);\n\n  return (\n    <button\n      data-hover={hover}\n      data-press={pressed}\n      onPointerEnter={(e: PointerEvent<HTMLButtonElement>) => {\n        setHover(true);\n        onPointerEnter?.(e);\n      }}\n      onPointerLeave={(e: PointerEvent<HTMLButtonElement>) => {\n        setHover(false);\n        setPressed(false);\n        onPointerLeave?.(e);\n      }}\n      onPointerDown={(e: PointerEvent<HTMLButtonElement>) => {\n        setPressed(true);\n        onPointerDown?.(e);\n      }}\n      onPointerUp={(e: PointerEvent<HTMLButtonElement>) => {\n        setPressed(false);\n        onPointerUp?.(e);\n      }}\n      onPointerCancel={(e: PointerEvent<HTMLButtonElement>) => {\n        setPressed(false);\n        onPointerCancel?.(e);\n      }}\n      className={[\n        \"group relative inline-flex items-center justify-center overflow-hidden rounded-sm px-5 py-2.5 text-sm font-medium text-foreground\",\n        // glass material: translucent fill, heavy blur, saturation boost\n        \"bg-black/[0.04] backdrop-blur-xl backdrop-saturate-150 dark:bg-white/[0.06]\",\n        \"border border-black/10 dark:border-white/10\",\n        // depth: top specular edge (inset) + soft lift shadow\n        \"shadow-[inset_0_1px_0_0_rgba(255,255,255,0.5),0_4px_16px_-4px_rgba(0,0,0,0.15)]\",\n        \"dark:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.12),0_8px_24px_-8px_rgba(0,0,0,0.5)]\",\n        // hover: material brightens, border sharpens, 1px lift\n        // (`data-[hover=true]` mirrors `:hover` for synthetic/driver input)\n        \"hover:-translate-y-px hover:bg-black/[0.07] hover:border-black/15 dark:hover:bg-white/[0.1] dark:hover:border-white/20\",\n        \"data-[hover=true]:-translate-y-px data-[hover=true]:bg-black/[0.07] data-[hover=true]:border-black/15 dark:data-[hover=true]:bg-white/[0.1] dark:data-[hover=true]:border-white/20\",\n        // press: springy scale-down (overshoot bezier ~ spring without a dep)\n        // (`data-[press=true]` mirrors `:active` for synthetic/driver input)\n        \"active:translate-y-0 active:scale-[0.96]\",\n        \"data-[press=true]:translate-y-0 data-[press=true]:scale-[0.96]\",\n        \"transition-[transform,background-color,border-color] duration-200 ease-[cubic-bezier(0.34,1.56,0.64,1)]\",\n        \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ns-accent\",\n        \"motion-reduce:transition-none motion-reduce:hover:translate-y-0\",\n        className,\n      ].join(\" \")}\n      {...props}\n    >\n      {/* specular sheen sweeps across the glass on hover\n          (`group-data-[hover=true]` mirrors `group-hover` for synthetic input) */}\n      <span\n        aria-hidden\n        className=\"pointer-events-none absolute inset-y-0 -left-1/2 w-1/3 rotate-12 bg-white/10 blur-sm transition-transform duration-700 ease-out group-hover:translate-x-[500%] group-data-[hover=true]:translate-x-[500%] motion-reduce:hidden\"\n      />\n      <span className=\"relative\">{children}</span>\n    </button>\n  );\n}\n",
      "type": "registry:ui",
      "target": "components/ui/button-glass.tsx"
    }
  ],
  "cssVars": {
    "theme": {
      "color-ns-accent": "var(--ns-accent)"
    },
    "light": {
      "ns-accent": "#006bff"
    }
  },
  "meta": {
    "collection": "core",
    "tags": [
      "button",
      "glass",
      "micro-interaction"
    ],
    "instruction": "A liquid-glass button: translucent blurred surface, thin light border, subtle hover lift and press scale, visible keyboard focus ring, for a dark minimal (Geist-style) design system."
  },
  "type": "registry:ui"
}