Elements

Buttons

Five distinct levels of emphasis. Add .sm for the small size. Every button has live hover, focus, active, and disabled states. Try them with your mouse and keyboard.

Variants
.btn
Primary. Ink fill. The most prominent CTA on a page.
.btn.outline
Secondary. Outlined on white. Pairs with a primary.
.btn.accent
Brand CTA. Accent fill. Conversion moments.
.btn.ghost
Utility. Faint chrome. Filters, sort, secondary controls.
.btn.link
Inline link. No chrome. Reads as a link inside text.

Pick the highest-emphasis variant that fits the moment. A page rarely needs more than one primary button per view.

Size — add .sm to any variant
Default
.sm

.sm drops the button to 11px text with tighter padding. Use it inside cards, toolbars, dense rows, and toasts. .btn.link stays the same size; it's already inline-sized.

Interactive states

Hover, focus, and active all work on real HTML. Mouse over the row below; press Tab to walk through with keyboard focus.

Try: hover · focus (tab) · click · hold
State Trigger Visual
default .btn Resting state. Set by the variant.
hover .btn:hover Background and border darken. Primary & accent shift one step; outline and ghost pick up a subtle --paper-2 / --paper wash.
focus-visible .btn:focus-visible 2px --accent outline at 2px offset. Only shown for keyboard users (mouse clicks suppress it).
active .btn:active The press moment. Same direction as hover, slightly tighter (subtle).
disabled .btn[aria-disabled="true"] Opacity drops to 45%, cursor turns not-allowed. The button stays in the DOM and remains focusable for screen readers.

All five states live in wireframe.css so they update everywhere at once. Hover transitions are 120ms. Keep them quiet so the wireframe doesn't feel like a design comp.

Disabled — aria-disabled="true"

Use aria-disabled="true" (not the HTML disabled attribute) so the button stays in the keyboard tab order and screen readers can announce it. Combine with onclick guards in real builds.

With an icon

The .btn base sets gap: 6px between children, so drop an <i> before or after the label. Set color: inherit on the icon so it follows the button's text color through every state.