Component & design-token showcase

Buttons

Always <Button> — there's no hand-styled-<button> escape hatch anymore. size, icon, and variant cover the dimensions and colors a button can need. Never override its visuals via class/style.

Variants

From zeyo-ui/form. Layout-only classes (mt-4, w-full) are fine — never padding/background/color/border.

Code
<Button variant="default">Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="ghost-destructive">Ghost destructive</Button>
<Button variant="link">Link</Button>
Decorative variant

An animated gradient CTA for a handful of high-stakes spots (pricing, waitlist signup) — not general-purpose, but shared like every other variant. Originated as marketing's own brand fork; promoted into zeyo-ui/template.css so any app can reach for it without re-forking the CSS.

Code
<Button variant="shiny">Get started</Button>
Sizes

Omit size for the default 35px height. size='small' is the one shorter footprint (28px) — for toolbars, inline row actions, dense panels.

Code
<Button>Default (35px)</Button>
<Button size="sm">Small (28px)</Button>
Icon

Square, zero-padding footprint for a single icon child. Combines with size (icon size='small' = 28×28, icon alone = 35×35). Always pair with aria-label — there's no visible text.

Code
<Button icon variant="ghost" aria-label="Edit"><Pencil size={14} /></Button>
<Button icon size="sm" variant="ghost" aria-label="Delete"><Trash2 size={12} /></Button>
States

loading (or a wired-up form prop) swaps the label for a spinner automatically — no manual isPending wiring.

Code
<Button disabled>Disabled</Button>
<Button loading>Loading</Button>
<Button loading loadingMessage="Saving…">Save</Button>
When it's not a Button

A plain <button> is only for chrome that isn't visually a button:

  • A checkbox-shaped control — use the .form-checkbox pattern (see Forms) instead of a bordered square that toggles color.
  • A full-width dropdown/menu row or clickable list row — no color/border/padding to swap in, it's a different shape entirely.
  • An OAuth brand button (Google, etc.) — bound by that provider's brand guidelines, not this design system's tokens.

Everything with a color and a size is a <Button>.