← Catalog

Button

One button component, named by role (D4). Primary is Bolster's black button with highlighter text; brand is the yellow call to action for the one step that moves a job forward ("Preview and send"). Blue is not a button colour: it's for links, focus and selection. Every state has a visible focus ring (D8). Primary, brand, danger and secondary have a body: an edge, a light line along the top, a shadow; hover lifts 1px and a press sinks at once, then eases back. Ghost is for places that already say "button" (toolbars, rows, bars, Close). Every button has 8px corners (D33).

Roles and states

Hover, active and focus are pinned with data-state for this page only. Use one primary per view; secondary for everything else, ghost inside toolbars and rows. Tertiary is gone: secondary covers it.

RoleDefaultHoverActiveKeyboard focusDisabledLoading
primary
brand
secondary
ghost
ghost · danger
danger

Sizes

Heights follow the control scale: 32, 40 (default), 48, 56. Small buttons get a 44px touch area on coarse pointers without drawing bigger.

SizePrimarySecondaryIcon onlyUse
sm · 32tables, dense toolbars
md · 40default: toolbars, forms
lg · 48touch, mobile primary
xl · 56field app hero actions

On the dark top bar

Icons side by side (D41)

A button's size sets its icon's box, but glyphs fill their boxes differently: × draws 62 % of it, the expand arrows all of it. Icons that sit together match their ink and line instead. One drawn smaller goes a weight up so its line stays as thick, and keeps its own size through --icon-size (ic(name, size, { optical: true }), or data-optical in a specimen). scripts/check-icons.js measures a page.

same boxboth 16 Light: ink 16 and 10, so expand reads half as big again
same inkexpand 12 Regular, × 18 Light: ink 12 and 11, both lines 1.1 px

Rules

Markup

<button class="button">Create job</button> <button class="button" data-variant="secondary" data-size="sm">Go to pipeline</button> <button class="button" data-variant="ghost" data-icon-only aria-label="Refresh"><svg …/></button> <a class="button" data-variant="secondary" href="/jobs">View jobs</a> <button class="button" data-variant="ghost" data-tone="danger">Delete</button> <button class="button" aria-busy="true">Saving…</button>