Components

Button

The one shared button, in src/components/button.tsx. Give it href and it renders a link; otherwise a <button>. For a link styled as a button elsewhere, use buttonClasses().

import { Button } from "@/components/button";

<Button variant="brand" size="lg" href="/demo">Book a demo</Button>
<Button variant="soft" size="lg">See pricing</Button>

Variants

Pick by the surface it sits on and how much it should stand out.
variantWhen to use it
ghostText-only, for use on dark surfaces (nav links).
outlineWhite outline, for use on dark surfaces (header over the home hero).
plainText-only, for use on light surfaces (nav links).
secondaryWhite with a muted border, for use on light surfaces.
softSoft grey fill, no border — header actions and secondary CTAs on light surfaces.
brandBrand yellow — primary call to action.
darkDark fill — secondary CTA on light surfaces.
inversePlain white, for use over photos.

Sizes

sizeWhen to use it
md—
lg—
xl—
iconSquare, for a lone icon (32px).
icon-xlSquare, for a lone icon (44px).

Shape and width

shapeWhen to use it
round—
square—
widthWhen to use it
hugSized to its label; content centred.
fillFills its container; label left, trailing icon right.
fullFills its container; content centred.

With an icon

Put an Icon after the label for direction (arrows) or before it for meaning.
<Button variant="dark" size="lg">Get started <Icon name="arrow-right" /></Button>

Busy

While an action runs, busy swaps the label for a spinner and keeps the width, so nothing jumps.
<Button variant="brand" size="lg" busy>Send</Button>

Guidelines

  • Do:One brand button per view: it's the main action.
  • Do:Write labels as the action: “Book a demo”, not “Submit”.
  • Do:Give icon-only buttons an aria-label.
  • Don't:Don't restyle a button with className colours. Add a variant instead.
<Button size="icon" aria-label="Next"><Icon name="arrow-right" /></Button>