AquaButton is a nostalgic, glossy pill button inspired by Apple's classic Aqua design language. It layers a top highlight, a soft bottom diffusion, and rich inner shadows to create the signature lickable look.

Preview

AquaButton

Interactive

Secondary

Secondary

Interactive

Icon Button

Override the pill shape, padding, and min-width via className for a compact square icon button. The gloss layers reflow automatically.

Icon Button

Interactive

Install

Add the item with the shadcn CLI.

npx shadcn@latest add @evilbuttons/aqua-button

Usage

[]txt
import { AquaButton } from "@/components/evil-buttons/aqua-button";

export function ButtonDemo() {
  return (
    <div className="flex gap-4">
      <AquaButton variant="secondary">Cancel</AquaButton>
      <AquaButton>Save</AquaButton>
    </div>
  );
}

export function IconButtonDemo() {
  return (
    <AquaButton
      aria-label="Show menu"
      className="h-9 w-9 min-w-0 rounded-md px-0"
    >
      <svg width="11" height="11" viewBox="0 0 10 10" aria-hidden="true">
        <path d="M1 3 L9 3 L5 8 Z" fill="currentColor" />
      </svg>
    </AquaButton>
  );
}

Props

PropTypeDefaultDescription
variant"primary" | "secondary""primary"Blue Aqua gel or silver/white Aqua gel.
classNamestring-Extra classes passed to the wrapper.
childrenReact.ReactNode-The visible button label or content.

All other <button> attributes (onClick, disabled, type, etc.) are forwarded.

Notes

Sizing is driven by font-size. Padding, height, and the gloss layers use em units, so changing the button's font-size (via className or style) scales the entire button proportionally.

Registry

The registry item includes components/evil-buttons/aqua-button.tsx and installs clsx and tailwind-merge as dependencies. The component imports cn from @/lib/utils.