← the Atlas

Mobile key bar — two rows, no horizontal scroll

feature · budding ·implemented ·

Reflow the mobile soft key bar from a single overflow-x row into two rows so every key is reachable without horizontal scrolling. Plan + layout options + test/evidence strategy.

Implemented in #1181 . Branch mobile-keybar-two-row. Plan of record for the /be run — Option B (fixed six-column grid) shipped, current key order kept. (As shipped, the column count is derived — COLS = ceil(controls / 2) — and applied via an inline grid-template-columns, not a literal grid-cols-6 class, which Tailwind would purge.)

Today

MobileKeyBar.tsx:88-89 renders all twelve controls in one flex row that scrolls sideways:

class="flex gap-1 px-2 py-1.5 bg-surface-1 border-t border-edge overflow-x-auto"

The twelve controls, in DOM order, are the two sticky modifiers then ten keys:

CtrlAltEscTab⇧Tab
^C/

Each button is shrink-0 min-w-[2.5rem] (KEY_CLASS, line 65-66), so at ~40px + gaps the row is ~520px wide and overflows a ~360px portrait viewport — hence the scroll.

Approach — two candidate layouts

Recommended Option B — fixed grid-cols-6. Replace flex … overflow-x-auto with grid grid-cols-6 gap-1. Twelve controls flow row-major into exactly two rows of six, regardless of viewport width. Drop shrink-0 min-w-[2.5rem] from KEY_CLASS so each cell stretches to fill its column (the grid track sets the width now). The existing DOM order gives:

CtrlAltEscTab⇧Tab
^C/

Guarantees the “two rows” ask on every screen; no scroll container at all.

Option A — flex-wrap. Swap overflow-x-autoflex-wrap, keep min-w-[2.5rem]. Smaller diff, buttons keep their natural width and wrap. But the row count is viewport-dependent — two on a typical phone, possibly three on a very narrow one — so it doesn’t guarantee two rows. Rejected for not meeting the ask precisely.

Files

Test strategy (feature / new behavior)

Add an e2e assertion to the existing mobile-soft-keyboard.feature + steps (mobile_soft_keyboard_steps.ts) that pins the new layout:

This is the covering test for the change; it fails red against the current single-row bar and green after the grid swap.

Evidence

Per .agency/do.md ## PR evidence — visible UI impact, so a screenshot of the mobile key bar showing all twelve keys in two rows with nothing clipped. Captured via the /evidence e2e-recording path on a pu box (mobile viewport).

Out of scope

Key set, escape sequences, sticky-modifier behavior, haptics, and the swipe guard are unchanged — this is purely a reflow of the existing controls.