Buttons and actions
Buttons say what happens
A button is a promise. Its label says exactly what will happen, it looks as important as the action is, and it responds the instant it is pressed.
- Labels are verbs in sentence case: “Send 3 emails”, “Issue licence”, not “Submit” or “OK”.
- One primary button per view. Secondary for alternatives, tertiary for low-emphasis actions.
- Keep the action's name through the flow: “Publish” → “Publishing…” → “Published”.
- Put the primary action last (right) in a button row; in RTL layouts it moves to the left.
Variants and states
Every variant has the same six states. The loading state keeps the button's width so the layout never jumps.
Variants × states
DefaultHoverFocusPressedDisabledLoading
PrimarySecondaryTertiaryDangerDanger (secondary)
| Variant | Use | Never |
|---|---|---|
| Primary | The single most important action | More than one per view |
| Secondary | Alternatives, cancel, back | For the main action |
| Tertiary | Low-emphasis actions, inline actions in cards and tables | For destructive actions |
| Danger | Irreversible destructive actions, usually inside a confirmation dialog | As the first button a user sees |
| Danger (secondary) | Entry point to a destructive flow (opens the confirmation) | For reversible actions |
| Inverse | On Midnight or image backgrounds in marketing | In product UI |
Anatomy and tokens
Primary button
| Part / state | Value | Token |
|---|---|---|
| Height | 32 / 40 / 48px | --n-size-control-* |
| Padding | 12 / 16 / 22px | |
| Radius | 8px | --n-radius-sm |
| Label | Text Medium 15px (13.5 / 16) | --n-font-family-text |
| Background | Gulf 70 (light), Oasis 30 (dark) | --n-action |
| Hover | Gulf 80 / Oasis 20 | --n-action-hover |
| Text | White / Midnight 90 | --n-text-on-action |
| Icon | 18px, 8px gap, leading | --n-size-icon-md |
| Focus | 3px ring, 2px offset | --n-focus |
Instant feedback on press
Respond within 100ms
- On press: 1px down shift (pressed state) immediately.
- If the result takes longer than ~300ms: switch to the loading state (spinner, label hidden, width kept) and ignore further clicks.
- On success: change the label to the past tense (“Sent”) with a check for 1.5 seconds, or close the surface; confirm with a toast if the result is not visible.
- On failure: restore the button and show the error next to it, never only in a toast.
Click to see loading, success and failure.
Couldn't reach NorthStar Admiral Server. Check your network, then try again.
Icon buttons
Square, labelled for assistive tech
- 40px square (32px small), 20px icon, 8px radius.
- Always an
aria-labeland a tooltip with the same text. - Use only for universally understood actions: close, more, search, copy, settings. Otherwise use a text button.
- Floating icon buttons over images use the translucent Midnight style with backdrop blur.
SearchSettings
Menu (burger) button
Three lines that become a cross
- Use only where navigation must collapse: below 960px, or in dense product chrome.
- Placed at the leading edge of the header (left; right in RTL), before the logo.
- Animates into a close icon in 220ms when the menu opens;
aria-expandedandaria-controlsare required. - The opened menu is a drawer from the same edge, with a scrim; Esc and the scrim close it.
Click it
Copy buttons
Top right of what is copied
- Sits in the top-right corner of the code block or field it copies (top-left in RTL), inside the frame with 10px inset.
- Visible on hover and keyboard focus on desktop; always visible on touch.
- On click: label changes to “Copied” with a check for 1.5s. No toast needed.
- For single values (IDs, tokens, keys) use an inline icon button after the value.
curl -fsS https://admiral.example.gov/healthzkey_9f2c…41ab
Button groups and split buttons
Group and split button
For mutually exclusive views prefer the segmented control on the Navigation page. Split buttons combine a default action with a menu of alternatives.
Links
- Inline links are Gulf 70 (Oasis 30 on dark), underlined with a 1px line at 3px offset; 2px on hover.
- Links go somewhere; buttons do something. Never style a navigation link as a button or vice versa, except CTAs in marketing.
- External links get the external-link icon and open in the same tab unless the user would lose work.
- Link text describes the destination: “Read the residency guide”, never “click here”.
Code
<button class="n-btn n-btn--primary" type="button">Save</button>
<button class="n-btn n-btn--secondary n-btn--sm">Cancel</button>
<button class="n-btn n-btn--primary" aria-busy="true">Saving</button> <!-- loading -->
<button class="n-icon-btn" aria-label="Close">…svg…</button>
<!-- Tailwind -->
<button class="inline-flex items-center gap-2 h-control-md px-4 rounded-sm bg-n-action text-n-on-action
font-medium hover:bg-n-action-hover active:translate-y-px focus-visible:outline-3
focus-visible:outline-offset-2 focus-visible:outline-n-focus disabled:opacity-disabled">Save</button>Dos and don'ts
Do
- Write specific verb labels.
- Show loading inside the button and keep its width.
- Confirm destructive actions in a dialog with the danger button.
- Give icon buttons labels and tooltips.
Don't
- Use more than one primary button per view.
- Disable a button without saying why.
- Use colour other than the variants (no green “Go” buttons).
- Use “OK”, “Submit” or “Click here”.
Last updated on 14 October 2026