Controls

Button

Starts an action. One primary per view, in magenta; secondary and ghost for the rest.

Concept · live ReactSource file: tokens.jsonReact component: Button

Try it

Variant
Size
Theme
Disabled
<Button variant="primary" size="md">Send</Button>

When to use

  • Primary for the one action that moves things on: Send, Join Jake, Add someone.
  • Secondary for a real alternative beside it: Edit, Heads down for 1 hour.
  • Ghost for the quiet way out: Not now, Cancel.
Don’t use it
  • Two primaries in one view.
  • A text link for an action on her phone: below 44px it can’t be tapped reliably.

Variants

Primary is Magenta 600 under white in light, and Magenta 500 under ink in dark. Secondary carries a 4.4:1 edge.

primary
secondary
ghost
with icon
primary
secondary
ghost

Sizes

md · 40, desktop
lg · 52, her phone

Content

  • Name what happens: Send, Join Jake, Add someone.
  • Use the person’s name when there is one.
  • Sentence case, no exclamation marks.

Accessibility

A real button. Focus is a 2px ring with a 2px gap in the accent colour, 5.5:1 against white (2.4.13).

KeyWhat it does
Enter / SpaceActivates.

Props

PropTypeDefaultDescription
variant'primary' | 'secondary' | 'ghost''primary'Emphasis.
size'md' | 'lg''md'40px desktop, 52px phone.
iconReactNode—A 16px icon before the label.
blockbooleanfalseFull width, for her phone.

Tokens

TokenValueWhere it lands
--cm-button-primary-bg#ca0e6f / #ff2d95Primary button fill
--cm-button-primary-bg-hover#a6085b / #ff56aaPrimary button, hovered
--cm-button-primary-fg#ffffff / #0e0e10Primary button label
--cm-border-strong#77777fInput and control edges, 3:1 or better
--cm-focus-ring#ca0e6f / #ff56aaThe 2px focus ring

Switch

Turns a setting on or off at once, with a visible label and an optional line of detail.

Concept · live ReactSource file: tokens.jsonReact component: Switch

Try it

When to use

  • A setting that takes effect the moment it changes: polite mode, sound.
Don’t use it
  • A choice that needs saving. Use a button.
  • More than two options. Use the corner picker’s segmented style.

States

Off has a 4.4:1 edge and a grey knob, so off reads as off without colour (1.4.11).

Accessibility

role=“switch” with aria-checked, and a visible label tied to it. The whole 44px row is the target.

KeyWhat it does
Space / EnterToggles.

Props

PropTypeDefaultDescription
checkedboolean—On or off.
onChange(checked: boolean) => void—Called with the new value.
labelstring—Required; also the accessible name.
descriptionstring—One line of what it does.
disabledbooleanfalseNot available right now.

Tokens

TokenValueWhere it lands
--cm-switch-on#ca0e6f / #ff2d95Switch track, on
--cm-border-strong#77777fInput and control edges, 3:1 or better
--cm-bg-sunken#ececee / #1f1f24Chips, keycaps, tracks
--cm-focus-ring#ca0e6f / #ff56aaThe 2px focus ring

Corner picker

Where the overlay sits: three corners, chosen without dragging.

Concept · live ReactSource file: tokens.jsonReact component: CornerPicker

Try it

Pick a corner, or Tab in and use the arrow keys.

When to use

  • Choosing where the overlay sits, for all games or one.
  • Beside a draggable preview, as the way to place it without a drag.
Don’t use it
  • Offering the centre or the bottom left. The crosshair and chat live there.

Accessibility

The non-drag way to place the overlay (2.5.7). A radio group with one tab stop and arrow keys.

KeyWhat it does
TabMoves into the group.
← →Moves between corners and chooses.

Props

PropTypeDefaultDescription
value'top-left' | 'top-right' | 'bottom-right'—The chosen corner.
onChange(corner: Corner) => void—Called on choose.
labelstring'Where messages appear'The group’s accessible name.

Tokens

TokenValueWhere it lands
--cm-bg-sunken#ececee / #1f1f24Chips, keycaps, tracks
--cm-bg-surface#ffffff / #16161aCards and panels
--cm-text-secondary#5a5a62 / #9a9aa2Supporting text, 6.9:1 on its ground
--cm-focus-ring#ca0e6f / #ff56aaThe 2px focus ring

Preset chips

Her usual messages as one-tap chips that fill the composer.

Concept · live ReactSource file: tokens.jsonReact component: PresetChips

Try it

When to use

  • Above her composer: one tap fills it with a message she can still edit.
Don’t use it
  • More than five. Her most-sent replace the defaults over time.

Content

  • Two or three words, in her voice: Dinner’s ready, Call me.
  • The chip is the label; the message it fills can be warmer and longer.

Accessibility

Toggle buttons with aria-pressed, in a labelled group. Her usual messages are one tap, never retyped (3.3.7).

Props

PropTypeDefaultDescription
itemsstring[]—The chip labels.
valuestring | null—The chip in use.
onPick(text: string) => void—Called on tap.

Tokens

TokenValueWhere it lands
--cm-accent-fill#ca0e6f / #ff2d95Primary buttons, selected controls
--cm-accent-subtle#fff0f7 / #42062aSelected backgrounds
--cm-border-subtle#d9d9dd / #2a2a30Dividers and resting edges

Composer

A labelled message field with a count and a send button, 140 characters at most.

Concept · live ReactSource file: tokens.jsonReact component: Composer

Try it

Type, then press Enter or Send.

When to use

  • The last thing on her home screen and in the thread.
Don’t use it
  • Longer than 140 characters. Two lines is what fits on his screen.

States

Empty: Send is disabled
Near the limit

Accessibility

A visible label, not a placeholder (3.3.2). The count is announced at 20 left and at the limit, not on every key.

KeyWhat it does
EnterSends.

Props

PropTypeDefaultDescription
toPerson—Names the label and the send button.
valuestring—The message.
onChange(v: string) => void—Called on input.
onSend() => void—Called on Enter or Send.
maxLengthnumber140Hard limit.

Tokens

TokenValueWhere it lands
--cm-input-border#77777fText field edge
--cm-focus-ring#ca0e6f / #ff56aaThe 2px focus ring
--cm-button-primary-bg#ca0e6f / #ff2d95Primary button fill
--cm-text-secondary#5a5a62 / #9a9aa2Supporting text, 6.9:1 on its ground

Keycap

A key or a chord, with what it does, on light surfaces or the overlay’s glass.

Concept · live ReactSource file: tokens.jsonReact component: Keycap

Try it

F7On my way
Keys
Tone
<Keycap keys={['F7']} label="…" tone="surface" />

When to use

  • Teaching a key: under the notification in his first week, and in his settings.
Don’t use it
  • As a button. To act, the key itself is pressed.

Tones

F7On my wayCtrlShiftCHeads down
F7On my wayF8After this match

Accessibility

Keys are real kbd elements. The keys they describe only listen while a notification is showing, and can be changed or turned off (2.1.4).

Props

PropTypeDefaultDescription
keysstring[]—One key, or a chord.
labelstring—What it does.
tone'surface' | 'overlay''surface'Overlay for the dark glass.

Tokens

TokenValueWhere it lands
--cm-keycap-bg#ececee / #1f1f24Keycap face
--cm-border-subtle#d9d9dd / #2a2a30Dividers and resting edges
--cm-text-primary#0e0e10 / #f6f6f7Body and headings