To pick one of two to five options that are visible at once: the round length, a date range, a console view.
Don’t use it
For navigation between pages. Use links.
For more than five options. Use a list.
States
Unselected options are text-muted on the track; hover lifts them to text. The selected option is a white surface with the card shadow. Focus is the focus ring, on top of either.
rest
hover
focus
option
60s
60s
60s
selected
60s
60s
60s
rest
hover
focus
option
60s
60s
60s
selected
60s
60s
60s
Accessibility
Key
What it does
Tab
Moves into the group, onto the selected option, then out of it. The group is one tab stop.
← / →
Moves to the previous or next option and selects it.
Home / End
Selects the first or last option.
A tablist of tabs with aria-selected, named by label. Selection follows focus, because every option is cheap to show.
Props
Prop
Type
Default
Description
value
string
—
The selected id.
onChange
(id) => void
—
Called with the new id.
items
{ id: string; label: string }[]
—
Two to five options.
label
string
—
The group’s accessible name.
Tokens
Token
Value
Where it lands
--hm-bg-subtle
#f1f0f4 / #0b0e15
Recessed ground: sidebars, segmented-control tracks, the area behind cards.
--hm-border
#e6e5eb / #2d323b
Hairlines between rows and inside cards. Decorative only.
--hm-surface
#ffffff / #1c2129
Cards and panels. Lifted from bg by shadow-card, not by a heavy border.
--hm-text
#141318 / #ebedef
Primary text. Light: graphite #141318 on paper, softer than black on white.
--hm-text-muted
#5b5869 / #9b9fa5
Secondary text: descriptions, helper text, metadata. Reads on every ground including surface-hover.
Select
One choice from a list whose options each need a line of explanation, like the round length.
Concept · live ReactSource file: tokens.jsonReact component: Select
Try it
Open it with a click, or focus it and press an arrow key.
A custom select rather than the native one, because each option needs a line explaining it, and sometimes a tag.
For one choice from three or more options that need a description: round length, a question set.
Don’t use it
For two to five short options that fit in a row. Use Tabs, so every option is in view.
For navigation.
Accessibility
Key
What it does
↓ / ↑ / Enter / Space
On the button: opens the list on the selected option.
↓ / ↑
Moves through the options.
Home / End
Jumps to the first or last option.
Enter / Space
Chooses, closes, and returns focus to the button.
Escape
Closes without changing, and returns focus to the button.
Tab
Closes and moves on.
A button with aria-haspopup="listbox" and aria-expanded, named by its label and current value. The list is a listbox that tracks the active option with aria-activedescendant.
Props
Prop
Type
Default
Description
value
string
—
The selected id.
onChange
(id) => void
—
Called with the chosen id.
options
{ id; label; description?; tag? }[]
—
Each option, with an optional line and tag.
label
string
—
Visible label, and the name.
hideLabel
boolean
false
Hide it visually where the context names it; it is still the accessible name.
block
boolean
false
Full width.
align
'start' | 'end'
'start'
Which edge the list lines up with.
Tokens
Token
Value
Where it lands
--hm-surface
#ffffff / #1c2129
Cards and panels. Lifted from bg by shadow-card, not by a heavy border.
--hm-surface-raised
#ffffff / #2d323b
Things that float: menus, dialogs, sheets, the record button at rest.
--hm-border-control
#7c798a / #7c8088
Outlines of inputs and secondary controls. Holds 3:1 on bg and surface.
--hm-text
#141318 / #ebedef
Primary text. Light: graphite #141318 on paper, softer than black on white.
--hm-text-muted
#5b5869 / #9b9fa5
Secondary text: descriptions, helper text, metadata. Reads on every ground including surface-hover.
--hm-surface-hover
#f1f0f4 / #2d323b
Hover and pressed fill for rows, ghost buttons and list items.
--hm-focus-ring
#2d49c9 / #ffc550
Keyboard focus: cobalt on paper, honey on ink, 2px outside a 2px bg gap.
Switch
An on/off setting that applies at once, like letting the readout quote your line.
Concept · live ReactSource file: tokens.jsonReact component: Switch
Try it
From the review screen: whether the readout may quote your line.
If the readout quotes you
Theme
<Switch checked={quoteOk} onChange={setQuoteOk} label="Let the readout quote this line" />
When to use
For one setting that takes effect at once, with the line beside it saying what it governs.
On the review screen, settings and the host panel.
Don’t use it
For a choice that needs a confirm step. Use buttons.
Without a visible label next to it. The accessible name is not enough on its own.
States
Off is the border-control track, which holds 3:1 against the ground. On is honey: the setting is about your own voice. Disabled flattens to border with no knob shadow.
rest
hover
focus
disabled
off
on
rest
hover
focus
disabled
off
on
Accessibility
Key
What it does
Tab
Moves focus to the switch.
Space / Enter
Turns it on or off.
A button with role="switch" and aria-checked. The label names what it controls, not its state.
40 by 24px, clear of the 24px target.
Props
Prop
Type
Default
Description
checked
boolean
—
On or off.
onChange
(on: boolean) => void
—
Called with the new value.
label
string
—
The accessible name: what it controls.
disabled
boolean
false
Not available right now.
state
'hover' | 'focus'
—
Forces a state. For documentation matrices only.
Tokens
Token
Value
Where it lands
--hm-border-control
#7c798a / #7c8088
Outlines of inputs and secondary controls. Holds 3:1 on bg and surface.
--hm-accent
#f2b106 / #ffc550
Primary, honey. A fill, glow or dot only, always carrying ink: live, the record comb, the shared mind, the hero series.
--hm-border
#e6e5eb / #2d323b
Hairlines between rows and inside cards. Decorative only.
--hm-focus-ring
#2d49c9 / #ffc550
Keyboard focus: cobalt on paper, honey on ink, 2px outside a 2px bg gap.
Transcript
Your answer as words you can take out but never rewrite, before you send it.
Concept · live ReactSource file: tokens.jsonReact component: TrimTranscript
Try it
Tap a word to take it out; tap it again to put it back. What would be sent updates underneath.
Sends: “Honestly, onboarding. Half the trials I talk to never finish setup, and we keep building features they never reach.”
The most Hivemind of the controls. People can take words out of what they said, but can’t write in new ones: the round is about what the room actually thinks, not a polished version of it.
On the review screen, between speaking and sending, with the clock still visible.
With the line that says what is happening: “You can remove words, not rewrite them.”
Don’t use it
As a text editor. If someone needs to type, that is the typed answer, with its own field.
States
A word is in or out. Out keeps its place, struck through in text-subtle, so the sentence still reads and the word can be put back. Hover is a surface-hover wash; focus is the focus ring.
onboardingin
Honestly,out
Accessibility
Key
What it does
Tab
Moves word by word.
Enter / Space
Takes the word out, or puts it back.
A group named “Your transcript. Tap a word to remove it.” Each word is a toggle button with aria-pressed; a removed word is read as “Honestly, removed”.
The words are targets inside running text, which WCAG 2.2’s target-size rule exempts (2.5.8, inline). At the phone’s 17px type each is 30px tall.
Props
Prop
Type
Default
Description
text
string
—
The transcript, as heard. Split into words once.
onChange
(text: string) => void
—
Called with the answer that would be sent.
Tokens
Token
Value
Where it lands
--hm-surface
#ffffff / #1c2129
Cards and panels. Lifted from bg by shadow-card, not by a heavy border.
--hm-border
#e6e5eb / #2d323b
Hairlines between rows and inside cards. Decorative only.
--hm-text
#141318 / #ebedef
Primary text. Light: graphite #141318 on paper, softer than black on white.
--hm-text-subtle
#5b5869 / #9b9fa5
Placeholder text and fine print. 4.5:1 on bg and surface.
--hm-surface-hover
#f1f0f4 / #2d323b
Hover and pressed fill for rows, ghost buttons and list items.
--hm-focus-ring
#2d49c9 / #ffc550
Keyboard focus: cobalt on paper, honey on ink, 2px outside a 2px bg gap.
Badge and live tag
A short label. The live tag is the only badge in honey, and it always says Live.
Concept · live ReactSource file: tokens.jsonReact component: Badge, LiveTag, SampleDataTag
Variants
A neutral badge labels; the live tag is the only badge in honey, and it always carries the word.
Round 2neutral
Livelive
60sneutral
Livelive
When to use
Neutral for a short fact beside a heading: the round number, the timer length, “Used 9 times”.
Live only while a round is open, on the stage, the phone and the host panel.
Don’t use it
For status that needs a decision. Write a sentence instead.
A honey badge for anything that isn’t live.
Content
One to three words, sentence case. Numbers in figures: “Round 2”, not “Round two”.
Accessibility
A badge is text, read where it sits. It is not a button and takes no focus.
The live tag’s dot is hidden from screen readers. The word “Live” carries the state, so it never depends on colour.
The tag is not a live region: the surface that opens a round announces it, once.
Props
Prop
Type
Default
Description
children
ReactNode
—
Badge: the label.
label
string
'Live'
LiveTag: override the word.
Tokens
Token
Value
Where it lands
--hm-bg-subtle
#f1f0f4 / #0b0e15
Recessed ground: sidebars, segmented-control tracks, the area behind cards.
--hm-border
#e6e5eb / #2d323b
Hairlines between rows and inside cards. Decorative only.
--hm-text-muted
#5b5869 / #9b9fa5
Secondary text: descriptions, helper text, metadata. Reads on every ground including surface-hover.
--hm-accent-subtle
#fff2db / #2e1e00
Honey wash behind ink text: the selected row, a verdict pill, a highlight.
--hm-accent-border
#ffd68b / #755402
Edge of an accent-subtle area.
--hm-accent-text
#141318 / #ffd68b
Emphasis inside a readout. Ink on paper (honey never goes dark and brown), honey on ink.
--hm-live
#f2b106 / #ffc550
Alias of accent. Anything that means the hive is listening right now: the record button, the live dot, the round timer while it runs.
Toast
A brief confirmation of something that happened off screen.
Concept · live ReactSource file: tokens.jsonReact component: Toast
Example
Press a button. The toast repeats the verb and the object, then leaves.
Join link copied
When to use
To confirm something that happened off screen: a link copied, a set saved.
Don’t use it
For errors. Say what happened next to the thing that failed.
For anything someone needs to read twice.
Content
Object and past-tense verb: “Join link copied”. No exclamation marks.
Accessibility
Rendered with role="status", so it is announced without moving focus.
It stays for 1.8 seconds and never holds an action.
Props
Prop
Type
Default
Description
children
ReactNode
—
An optional 16px icon, aria-hidden, then the message.
The surface that shows it owns the timing: it mounts the toast, then removes it after 1.8 seconds.
Tokens
Token
Value
Where it lands
--hm-p-gray-900 / 50
ink pill, paper text
The same in both themes: a toast is an aside, not part of the surface
--hm-shadow-overlay
ring + 12/32 lift
Lifts it off whatever is behind
--hm-radius-full
9999px
Pill
Room code and QR
How people join a hive: scan, or type six characters. Neither asks for a name.
Concept · live ReactSource file: tokens.jsonReact component: QrBlock
Example
How people join: scan the code on the stage, or type the room code. Neither asks for a name.
Room codeKX7-42QScan to join, or use the link in the chat. Your answers stay anonymous.
When to use
On the stage’s join screen, large, with the anonymity line beside it.
In the host panel as a copyable link, never as a code to read aloud.
Don’t use it
Codes with letters that look alike. Room codes skip O, 0, I and 1.
Content
Six characters in two groups of three: KX7-42Q. Geist with tabular figures, room-code style.
Accessibility
The QR is one image named “QR code to join”. The code beside it is the text alternative: anyone who can’t scan can type it.
Give the code an aria-label with its characters spaced, “K X 7, 4 2 Q”, so a screen reader spells it instead of reading “forty-two”.
The anonymity line sits next to the code, not behind a link, so it is read before anyone joins.
Props
Prop
Type
Default
Description
QrBlock · size
number
168
Width and height in px.
QrBlock · seed
number
7
Varies the sample pattern. The concept has no real join URL, so the code is a stand-in.
Tokens
Token
Value
Where it lands
.hm-t-room-code
48/56 · 500 · tabular
The code itself
--hm-text
#141318 / #ebedef
Primary text. Light: graphite #141318 on paper, softer than black on white.
--hm-text-muted
#5b5869 / #9b9fa5
Secondary text: descriptions, helper text, metadata. Reads on every ground including surface-hover.