Skip to content
Brand & UX guide
Components

Actions and inputs

Buttons, links, pills, fields, and the theme switch. The things a person presses, reads as a label, or types into.

#Button

A button starts something. Its label says what happens, in the owner’s words: Connect your store, Continue to secure checkout. There is one primary button per view.

Variants
Code
<div class="btn-row">
  <button type="button" class="btn btn-primary">Continue to secure checkout</button>
  <button type="button" class="btn btn-secondary">Manage billing</button>
  <button type="button" class="btn btn-danger">Disconnect store</button>
  <button type="button" class="btn btn-primary" disabled>Saving…</button>
</div>

#Full width, and a row

Use .btn-block inside a card or form that is one column wide, such as sign-in. Group a primary and its alternatives in .btn-row; add .grow to let the primary take the space.

Button row and block
Code
<div class="btn-row" style="margin-bottom: var(--space-4)">
  <button type="button" class="btn btn-primary grow">Continue to secure checkout</button>
  <button type="button" class="btn btn-secondary">Cancel</button>
</div>
<button type="button" class="btn btn-primary btn-block">Log in</button>

Do

Connect your store

Say what happens, with a verb and a noun.

Don’t

Submit

Generic labels make the owner read around them to learn what they do.

  • Minimum height is 2.5rem (40px). Keep it, even when space is tight.
  • Disabled buttons drop to 55% opacity and show a not-allowed cursor. Say why in nearby text when it is not obvious.
  • Focus shows a 2px ring in --color-focus. Never remove it.

.btn-link is for a quiet action that leads somewhere else in the product, usually ending in an arrow: Open store →.

Use it when

  • Moving to another page, at the end of a card or summary
  • A secondary path that should not compete with the primary button

Don’t use it when

  • Saving, connecting, paying, or anything that changes data

#Pill

A pill is a short, read-only status. It is never a button. The tone carries the meaning, and the words carry it too, so it never depends on color alone.

Tones
Monday ● Connected Latest Waiting for first report Failed
Code
<div class="btn-row">
  <span class="pill">Monday</span>
  <span class="pill pill-accent">● Connected</span>
  <span class="pill pill-pop">Latest</span>
  <span class="pill pill-warn">Waiting for first report</span>
  <span class="pill pill-danger">Failed</span>
</div>
ToneMeansExamples
neutralA fact, not a stateMonday, Sep 21–27, 2026
accentReady, connected, fine● Connected, Ready
popNew or currentLatest
warnWaiting or needs a lookWaiting for first report
dangerFailedFailed
Pop is not status

Violet marks what is newest, such as the latest week. Use it in one or two places per screen. Ready, waiting, and failed are told by accent, warn, and danger.

Use it when

  • Showing state: connected, waiting, failed, latest
  • Labeling a week range or a schedule in a page header

Don’t use it when

  • Anything clickable. Use a button or link
  • Long text. Keep it to about three words
  • Decoration or counts

#Field

A text field is a label, an input, and optional hint text. Always pair the label with the input using for and id. Placeholder text is not a label.

Field states
We send your weekly pack here.
Code
<div class="field">
  <label for="f-email">Email</label>
  <input id="f-email" type="email" value="[email protected]" />
  <div class="field-hint">We send your weekly pack here.</div>
</div>
<div class="field">
  <label for="f-ro">Store</label>
  <input id="f-ro" type="text" value="Cozy Goods" readonly />
</div>
<p class="form-error" role="alert">That email and password don’t match. Check them and try again.</p>
  • Labels sit above the input, 13px, semibold. Hints sit below, 11.5px, muted.
  • Read-only fields use the sunken background so they look settled, not broken.
  • Show errors in .form-error with role="alert". Say what went wrong and how to fix it, without apologizing.
  • Two short fields can share a row with .row-2. It stacks below 520px.

#Divider

.divider separates two routes through the same form, such as “or” between a password and another way in.

Divider with a label
or
Code
<button type="button" class="btn btn-primary btn-block">Log in</button>
<div class="divider">or</div>
<button type="button" class="btn btn-secondary btn-block">Continue another way</button>

#Theme switch

A three-way segmented control: System, Light, Dark. System removes the data-theme attribute so the OS decides. It lives in Settings under Appearance, and it is the same control in this guide’s top bar.

Segmented control
Code
<div class="segmented" role="group" aria-label="Color theme">
  <button type="button" aria-pressed="true">System</button>
  <button type="button" aria-pressed="false">Light</button>
  <button type="button" aria-pressed="false">Dark</button>
</div>

Use it when

  • Choosing one of a few mutually exclusive, instantly applied options

Don’t use it when

  • Choosing between pages. Use navigation
  • Long lists of options
Weekwright brand & UX guide v1.0.0 Components rendered from app @ bd6c1f4 · build d2e1ef8