{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"layered-button","type":"registry:ui","title":"Layered Button","description":"A 3D keycap of stacked offset layers that spread on hover and compress on press.","dependencies":[],"registryDependencies":[],"files":[{"path":"registry/ui/layered-button.tsx","type":"registry:ui","content":"\"use client\";\n\nimport type { ButtonHTMLAttributes, CSSProperties } from \"react\";\n\nexport interface LayeredButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n  /** Number of layers stacked under the face. */\n  layers?: number;\n  /** Px between layers at rest. */\n  depth?: number;\n}\n\n// Hover spreads the stack, press collapses it; release springs back with overshoot.\nconst motionCls =\n  \"transition-transform duration-300 ease-[cubic-bezier(.34,1.56,.64,1)] group-active:duration-75 group-active:ease-out motion-reduce:transition-none\";\n\nexport function LayeredButton({ layers = 3, depth = 4, className, style, children, ...props }: LayeredButtonProps) {\n  const total = layers * depth;\n  // The bottom layer stays put; everything above it is spaced by --lb-gap.\n  const shift = (i: number) => `translateY(calc(${total}px - ${layers - i} * var(--lb-gap)))`;\n\n  return (\n    <button\n      type=\"button\"\n      {...props}\n      className={`group relative inline-block select-none rounded-2xl [--lb-gap:var(--lb-depth)] focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-ring enabled:hover:[--lb-gap:calc(var(--lb-depth)*1.5)] enabled:active:[--lb-gap:calc(var(--lb-depth)*0.15)] disabled:cursor-not-allowed disabled:opacity-50 ${className ?? \"\"}`}\n      style={{ \"--lb-depth\": `${depth}px`, paddingBottom: total, ...style } as CSSProperties}\n    >\n      {Array.from({ length: layers }, (_, k) => {\n        const i = layers - k; // paint back to front\n        return (\n          <span\n            key={i}\n            aria-hidden\n            className={`absolute inset-x-0 top-0 rounded-2xl ${motionCls}`}\n            style={{\n              bottom: total,\n              transform: shift(i),\n              background: `color-mix(in oklab, var(--primary) ${Math.round(100 - (i / layers) * 58)}%, black)`,\n              boxShadow:\n                i === layers ? \"0 14px 28px -10px rgb(0 0 0 / .55)\" : \"inset 0 1px 0 rgb(255 255 255 / .12)\",\n            }}\n          />\n        );\n      })}\n      <span\n        className={`relative flex h-12 items-center justify-center gap-2 whitespace-nowrap rounded-2xl bg-primary px-8 text-sm font-semibold text-primary-foreground shadow-[inset_0_1px_0_rgb(255_255_255/.5),inset_0_-2px_0_rgb(0_0_0/.08)] ${motionCls}`}\n        style={{ transform: shift(0) }}\n      >\n        {children}\n      </span>\n    </button>\n  );\n}\n"}]}