main character

button · 5 kinds · 4 sizes · 4 states
source: static/css/components.css

Button

Five voices, from loudest to quietest: send, the one primary in a composer; filled, a quieter primary for confirm and apply; quiet, the default secondary; text, borderless, for clear and back links; and danger, a quiet button that only turns red when pointed at. No button is red all the time.

Kinds and states

Each row is one kind at its default size, in its four states. Hover and focus are held still with the .is-hover and .is-focus-visible twins design.js makes from the app's own :hover and :focus-visible rules. Disabled is the real attribute.

Sizes

pill is send's compact form for the chat and search bars: 1.8rem, fully round, with an optional ↵. Quiet comes in three heights: 2.2rem (md, the default), 2rem (.sm) and 1.8rem (.xs, smaller type too). Text buttons are always 1.8rem.

In context

Write's control row: two sends beside a quiet, then a text button. Undo and redo use .quiet.empty, half strength while there is nothing to undo.

Anatomy
button.send[.pill]       primary · 2.2rem (pill 1.8rem)
  span.ret               pill only, the ↵
button.filled            secondary primary · 2.2rem
button.quiet[.sm | .xs]  default secondary · 2.2 / 2 / 1.8rem
button.text              borderless · 1.8rem
button.quiet.danger      quiet, --text-danger on hover
send
--fill-accent fill, --text-on-accent text, --radius-lg. At most one per composer. Hover steps to --fill-accent-hover: brighter in dark, deeper in light.
filled
--fill-accent-muted fill and rule, --text-on-accent text, --radius-base. Lifts to the full --fill-accent on hover, so it reads as a quieter send until pointed at.
quiet
A --border-default hairline, --text-muted label, no fill. Hover brings the label to --text-default on --bg-raised.
text
Quiet without the rule, at --radius-sm. Hover is the label colour only.
danger
Quiet until hover, when the label turns --text-danger and the rule --border-danger. Always paired with an undo or a confirm.
focus
Keyboard only (:focus-visible): a 2px --focus-ring outline, 2px off the edge. Never a ring on a mouse click.
disabled
Send at 45% opacity, filled, quiet and danger at 50%; hover does nothing. Text has no disabled style of its own: hide it instead.
Tokens

Fills --fill-accent, --fill-accent-hover, --fill-accent-muted, --bg-raised; labels --text-on-accent, --text-muted, --text-default, --text-danger; rules --border-default, --border-danger; focus --focus-ring; radius --radius-sm, --radius-base, --radius-lg, --radius-pill; type --font-ui. In Figma: one Button set, kind × size × state, with a label text property and show return on the pill.