Design HubStudio

3. Buttons

Five variants, ordered by visual weight. Picking the right one is the most common design decision in any screen UI — and the one most often gotten wrong.

Gallery

Five variants at default size, plus icon and state variations. Sizes (sm / md / lg) are documented in 1f. Component typography.

When to use each variant

Variants are ordered by visual weight. Reach for the lowest-weight variant that conveys the action's importance. Ghost is the default; primary is reserved.

Primary
The one action this view exists to support — Save, Continue, Compile. One per view, max two. Three primary buttons read as noise.
Secondary
A clear alternative to primary — Cancel in a dialog, or an alternate path in a form. Distinct from primary, still affordant.
Ghost
The default. Most clickable text in a UI is ghost — toolbar actions, form helpers, secondary nav. When in doubt, ghost.
Subtle
Barely-visible chrome. Row actions in tables, header utilities, pagination. Exists; doesn't compete for attention.
Danger
Destructive, irreversible actions — Delete, Revoke, Discard. Reserved for actions the user might regret. Cancel is not danger.
Drift to avoid

Named anti-patterns — each one seen in the wild during the audit. Each is tagged with the principle it violates.

  • Don't ship a custom button class
    Principle 2
    .toolbar-btn, .action-btn, .icon-btn — if .btn-* doesn't fit, fix the primitive. Six button systems happen one shortcut at a time.
  • Don't put three primary buttons in one view
    Principle 1
    If everything is primary, nothing is. Demote two of them to ghost or secondary — the page can have one center of gravity.
  • Don't use danger for Cancel
    Principle 4
    Cancel is negative, not destructive. Danger is reserved for actions that destroy data — Delete, Revoke. Cancel is ghost or secondary.
  • Don't disable a button without explanation
    UX
    A disabled button hides why. Pair with a tooltip or helper text explaining the condition that would re-enable it. Otherwise the user is stuck guessing.
  • Don't override hover with inline styles
    Principle 2
    Hover state belongs to the button class. Scoped CSS that overrides color or background on hover creates look-alikes that drift over time.
  • Don't use window.confirm()
    UX
    It's not a button — it's a browser modal with no visual relationship to the system. Use a dialog with the proper ghost/danger pair.
Composition — page header

Four variants used together with reasoning. Subtle for chrome, ghost for the alternative, primary for THE action. Danger lives in the overflow menu — destructive actions don't belong adjacent to primary.

PCR amplification protocol

  • subtle × 2 Duplicate / Export — utility actions that exist for completeness
  • ghost × 1 Preview — clear affordance, doesn't compete with the primary
  • primary × 1 Compile — THE action this page exists to enable
  • subtle icon-only Overflow — danger actions (Delete) live behind it, not adjacent to primary