{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"push-button","type":"registry:ui","title":"Push button","description":"A chunky button with visible depth: the face sits on its own edge, lifts a pixel on hover, travels down onto the edge when pressed and springs back when let go. For playful flows such as onboarding, lessons and rewards.","dependencies":["clsx","tailwind-merge"],"registryDependencies":["https://caliperui.site/r/styles.json"],"files":[{"path":"ui/lib/cn.ts","type":"registry:ui","target":"components/ui/lib/cn.ts","content":"import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n  extend: { theme: { radius: [\"control\", \"surface\", \"overlay\"], shadow: [\"overlay\"] } },\n});\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"},{"path":"ui/push-button.tsx","type":"registry:ui","target":"components/ui/push-button.tsx","content":"\"use client\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"./lib/cn\";\nimport \"./push-button.css\";\n\nexport type PushButtonProps = ComponentProps<\"button\"> & {\n  /** Ink for the main action, accent for the one moment that should stand out, neutral for the rest. */\n  variant?: \"default\" | \"accent\" | \"secondary\";\n  size?: \"sm\" | \"md\" | \"lg\";\n};\n\n/**\n * A chunky button with visible depth: the face sits on its own edge, lifts a pixel on hover and travels down onto\n * the edge when pressed, springing back when let go. For playful, game-like flows (onboarding, lessons, rewards);\n * use `Button` for ordinary product actions.\n */\nexport function PushButton({ variant = \"default\", size = \"md\", className, children, type = \"button\", ...props }: PushButtonProps) {\n  return (\n    <button data-slot=\"push-button\" data-variant={variant} data-size={size} type={type} className={cn(\"group\", className)} {...props}>\n      <span data-slot=\"pb-edge\" aria-hidden=\"true\" />\n      <span data-slot=\"pb-face\">{children}</span>\n    </button>\n  );\n}\n"},{"path":"ui/push-button.css","type":"registry:file","target":"components/ui/push-button.css","content":"/* push-button.tsx's styles; it imports this file. Edit freely. */\n@layer theme, base, components, utilities;\n\n@layer components {\n  /* Push button: a face on its own edge; hover lifts, press travels down onto the edge, release springs back. */\n  [data-slot=\"push-button\"] { --pb-depth: 4px; --pb-face: var(--primary); --pb-ink: var(--primary-foreground); position: relative; display: inline-flex; padding: 0; padding-bottom: var(--pb-depth); border: 0; border-radius: var(--radius-button); background: none; font-weight: 600; letter-spacing: -0.006em; cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; }\n  [data-slot=\"push-button\"][data-variant=\"accent\"] { --pb-face: var(--accent); --pb-ink: var(--accent-foreground); }\n  [data-slot=\"push-button\"][data-variant=\"secondary\"] { --pb-face: var(--raised); --pb-ink: var(--foreground); }\n  [data-slot=\"push-button\"] [data-slot=\"pb-edge\"] { position: absolute; inset: var(--pb-depth) 0 0; border-radius: inherit; background: color-mix(in oklab, var(--pb-face), #000 32%); }\n  [data-slot=\"push-button\"][data-variant=\"secondary\"] [data-slot=\"pb-edge\"] { background: var(--border-strong); }\n  [data-slot=\"push-button\"] [data-slot=\"pb-face\"] { position: relative; display: inline-flex; flex: 1; align-items: center; justify-content: center; gap: 8px; min-height: 40px; padding: 0 18px; border-radius: inherit; background: var(--pb-face); color: var(--pb-ink); font-size: 14px; translate: 0 0; transition: translate 0.5s var(--ease-settle), filter var(--duration-fast) var(--ease-out); }\n  [data-slot=\"push-button\"][data-variant=\"secondary\"] [data-slot=\"pb-face\"] { box-shadow: inset 0 0 0 1px var(--border-strong); }\n  [data-slot=\"push-button\"][data-size=\"sm\"] { --pb-depth: 3px; }\n  [data-slot=\"push-button\"][data-size=\"sm\"] [data-slot=\"pb-face\"] { min-height: 32px; padding: 0 14px; font-size: 13px; }\n  [data-slot=\"push-button\"][data-size=\"lg\"] { --pb-depth: 5px; }\n  [data-slot=\"push-button\"][data-size=\"lg\"] [data-slot=\"pb-face\"] { min-height: 48px; padding: 0 24px; font-size: 16px; }\n  [data-slot=\"push-button\"] [data-slot=\"pb-face\"] svg { width: 1.1em; height: 1.1em; flex: none; }\n  @media (hover: hover) { [data-slot=\"push-button\"]:hover:not(:disabled) [data-slot=\"pb-face\"] { translate: 0 -1px; filter: brightness(1.06); transition-duration: 0.25s; } }\n  [data-slot=\"push-button\"]:active:not(:disabled) [data-slot=\"pb-face\"] { translate: 0 var(--pb-depth); transition: translate 34ms linear; }\n  [data-slot=\"push-button\"]:focus-visible { outline: 2px solid var(--ring); outline-offset: 3px; }\n  [data-slot=\"push-button\"]:disabled { cursor: not-allowed; }\n  [data-slot=\"push-button\"]:disabled [data-slot=\"pb-face\"] { translate: 0 var(--pb-depth); background: var(--muted); color: var(--muted-foreground); box-shadow: none; }\n  @media (pointer: coarse) { [data-slot=\"push-button\"] [data-slot=\"pb-face\"] { min-height: 44px; } }\n  @media (prefers-reduced-motion: reduce) {\n    [data-slot=\"push-button\"] [data-slot=\"pb-face\"] { transition: none; }\n  }\n}\n"}],"categories":["motion"],"meta":{"tier":"free","license":"MIT","family":"surfaces","docs":"/docs/components/push-button"}}