# 3D Push Button

> 3D push button with layered edge and shadow that rises on hover and sinks on press; hue is configurable.

- Author: Atelier UI
- License: MIT
- Page: https://chromotion.dev/en/components/push-3d-button
- Site: Atelier UI (https://chromotion.dev)

## Install

```bash
npx shadcn@latest add https://chromotion.dev/r/push-3d-button.json
```

Stack: React + TypeScript + Tailwind CSS v4, shadcn/ui conventions. `cn` comes from `@/lib/utils`.

## Dependencies

No extra dependencies.

## Usage

```tsx title="components/push-3d-button-demo.tsx"
import { Push3DButton } from "@/components/push-3d-button"

export default function Push3DButtonDemo() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-8 rounded-2xl bg-neutral-100 p-12 dark:bg-neutral-900">
      <Push3DButton>Push me</Push3DButton>
      <Push3DButton hue={210}>Launch</Push3DButton>
      <Push3DButton hue={140} style={{ "--push-fg": "#0a0a0a" } as React.CSSProperties}>Confirm</Push3DButton>
    </div>
  )
}
```

## Source

```tsx title="components/push-3d-button.tsx"
import * as React from "react"

import { cn } from "@/lib/utils"

export interface Push3DButtonProps extends React.ComponentProps<"button"> {
  /** HSL hue 0-360 */
  hue?: number
}

export function Push3DButton({ hue = 345, className, style, children, ...props }: Push3DButtonProps) {
  return (
    <button
      type="button"
      style={{ "--h": hue, ...style } as React.CSSProperties}
      className={cn(
        "group relative cursor-pointer border-0 bg-transparent p-0 select-none",
        "focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-ring",
        "disabled:pointer-events-none disabled:opacity-50",
        className
      )}
      {...props}
    >
      <span
        aria-hidden
        className="absolute inset-0 translate-y-0.5 rounded-xl bg-black/30 blur-sm transition-transform duration-300 ease-out group-hover:translate-y-1 group-active:translate-y-px"
      />
      <span
        aria-hidden
        className="absolute inset-0 rounded-xl bg-[linear-gradient(to_left,hsl(var(--h)_100%_16%),hsl(var(--h)_100%_32%)_8%,hsl(var(--h)_100%_32%)_92%,hsl(var(--h)_100%_16%))]"
      />
      <span className="relative block -translate-y-1 rounded-xl bg-[hsl(var(--h)_100%_44%)] px-8 py-3 text-base font-bold text-[color:var(--push-fg,#fff)] transition-transform duration-300 ease-out group-hover:-translate-y-1.5 group-active:-translate-y-0.5 group-active:duration-75">
        {children}
      </span>
    </button>
  )
}
```
