Measured, on the live console, in WebKit at phone widths
A sweep of 21 routes at 320px and 390px counted every interactive element inside <main> whose
rendered box is under 40px in either axis. Apple HIG says 44×44pt; Material says 48×48dp. 40 is
the lenient floor, and these are the counts against it:
| route |
targets < 40px |
smallest examples |
| Assistant / Board |
40 |
24×24 Copy message · 24×24 Delete this turn · 30px Load earlier |
| Terminals |
39 |
26px agent links |
| Settings (instance) |
30 |
28px Save · 26px Refresh |
| Preferences |
30 |
30px Reconnect / Disconnect |
| Browse |
28 |
32px Subscribe · 34px Open → |
| Behaviour |
27 |
12×12 checkboxes |
| Knowledge |
10 |
38px sub-tabs |
| Data |
9 |
24px Records / Runs |
| Repo |
5 |
16px Re-index · 16px Remove |
| tmux / Terminal |
7 |
32×22 view switch |
Identical at both widths — this is not a narrow-viewport artefact, it is the sizing everywhere.
The three that are not borderline
12×12px checkboxes on the Behaviour tab (BehaviourTab.tsx:379 — a bare
<input type="checkbox" className="mt-1">, so it renders at the UA default). That is a quarter
of the recommended area, on the tab whose entire job is toggling how an agent talks. Everything
else on that tab is a slider or a select; these are the only controls, and they are the smallest
thing on the page.
16px-tall buttons on the Repo tab — Re-index and Remove. Remove deletes an indexed
repository. A destructive action at 16px, next to a 16px non-destructive one, on a touch
surface, is a mis-tap waiting to happen.
24×24px message actions (Copy / Delete this turn / speaker) on every chat bubble. These are
also the controls a hands-free user reaches for when voice has gone wrong — the moment when
precision is lowest.
Why this is not simply "make the buttons bigger"
The controls are hand-authored, one at a time — #366 measured 291 distinct control class strings in
14 shapes, with no Button primitive anywhere. So "40px minimum" cannot be applied as one decision;
today it is 291 edits, and the next control added starts the count again.
That makes this a strong argument for #366's component layer landing first: a Button with
sm/md sizes whose smallest variant still clears 40px of hit area (padding, not necessarily
visual size — an icon button can look 24px and be tappable at 44 via padding or a ::before
expansion) fixes the whole class in one place, and the next 291 sites inherit it.
Suggested order: #367 (the system, shipped) → #366 (the primitives, with the tap-target floor
baked into them) → this ticket becomes "adopt the primitive", not "resize 291 things".
What to decide
- The floor. 44×44 (Apple) is the safer number; 40 is what this audit measured against. Pick one
and put it in DESIGN-SYSTEM.md so it is checkable — that document is descriptive today and this
would be its first prescriptive rule, which is worth doing deliberately.
- Hit area vs visual size. An icon button does not have to look 44px. Deciding this once is
what stops the fix from making the console look like a tablet app.
- Whether to guard it. The e2e mobile sweep already visits every route; a "no interactive element
under Npx" assertion is the same shape as the overflow guard and would hold the line.
Measured 2026-08-08 against production (post-#384), WebKit, 320px and 390px, signed in.
Files: store/console/src/tabs/BehaviourTab.tsx:379, store/console/src/tabs/RepoTab.tsx,
store/console/src/pages/InstanceDetail.tsx:54, and ~291 other control sites (#366).
Measured, on the live console, in WebKit at phone widths
A sweep of 21 routes at 320px and 390px counted every interactive element inside
<main>whoserendered box is under 40px in either axis. Apple HIG says 44×44pt; Material says 48×48dp. 40 is
the lenient floor, and these are the counts against it:
24×24Copy message ·24×24Delete this turn ·30pxLoad earlier26pxagent links28pxSave ·26pxRefresh30pxReconnect / Disconnect32pxSubscribe ·34pxOpen →12×12checkboxes38pxsub-tabs24pxRecords / Runs16pxRe-index ·16pxRemove32×22view switchIdentical at both widths — this is not a narrow-viewport artefact, it is the sizing everywhere.
The three that are not borderline
12×12pxcheckboxes on the Behaviour tab (BehaviourTab.tsx:379— a bare<input type="checkbox" className="mt-1">, so it renders at the UA default). That is a quarterof the recommended area, on the tab whose entire job is toggling how an agent talks. Everything
else on that tab is a slider or a select; these are the only controls, and they are the smallest
thing on the page.
16px-tall buttons on the Repo tab — Re-index and Remove. Remove deletes an indexedrepository. A destructive action at 16px, next to a 16px non-destructive one, on a touch
surface, is a mis-tap waiting to happen.
24×24pxmessage actions (Copy / Delete this turn / speaker) on every chat bubble. These arealso the controls a hands-free user reaches for when voice has gone wrong — the moment when
precision is lowest.
Why this is not simply "make the buttons bigger"
The controls are hand-authored, one at a time — #366 measured 291 distinct control class strings in
14 shapes, with no
Buttonprimitive anywhere. So "40px minimum" cannot be applied as one decision;today it is 291 edits, and the next control added starts the count again.
That makes this a strong argument for #366's component layer landing first: a
Buttonwithsm/mdsizes whose smallest variant still clears 40px of hit area (padding, not necessarilyvisual size — an icon button can look 24px and be tappable at 44 via padding or a
::beforeexpansion) fixes the whole class in one place, and the next 291 sites inherit it.
Suggested order: #367 (the system, shipped) → #366 (the primitives, with the tap-target floor
baked into them) → this ticket becomes "adopt the primitive", not "resize 291 things".
What to decide
and put it in
DESIGN-SYSTEM.mdso it is checkable — that document is descriptive today and thiswould be its first prescriptive rule, which is worth doing deliberately.
what stops the fix from making the console look like a tablet app.
under Npx" assertion is the same shape as the overflow guard and would hold the line.
Measured 2026-08-08 against production (post-#384), WebKit, 320px and 390px, signed in.
Files:
store/console/src/tabs/BehaviourTab.tsx:379,store/console/src/tabs/RepoTab.tsx,store/console/src/pages/InstanceDetail.tsx:54, and ~291 other control sites (#366).