Treadmill+iPad usability pass — fixing 3 shared components fixed 20+ screens
The app is used all day on a treadmill via iPad. A 35-screen audit found tiny tap targets, sub-14px drill content, and hover-only completion checks as the recurring killers. Fixing SiteHeader, TrackedList, and SpeakGate plus the talk screen fixed the high-severity issues across 20+ screens at once.
The actual usage pattern: walking on a treadmill, holding an iPad, drilling English + interview answers for hours. That changes what "usable" means — no precision tapping, reading at arm's length with motion shake, no touch keyboard typing.
Ran a per-screen audit across 35 routes, each review grounded in the JSX so issues cited file:line instead of guessing. The findings collapsed into a few themes, and almost all of the high-severity ones traced back to three shared components:
- SiteHeader — 14 nav links at
px-2.5 py-1(~28px tall) wrapping into a dense block. Walking → mis-taps. - TrackedList (the list/index component behind speak/labs/design/practice/bugs/diagnose/comms…) — the done toggle was
h-7 w-7(28px), and the unchecked checkmark usedtext-transparent ... hover:text-accent/60, so on touch the check never appeared at all. Subtitles weretext-xs text-slate-400— sub-12px and low contrast. - SpeakGate (the mic gate behind tomorrow/pairing/deepdive/leader/jd/speak/myvoice) — the core "🎙 Speak the line" button was
px-4 py-2 text-sm(~36px), the single most-pressed control in the whole app.
So the leverage was obvious: fix the three shared components, not 35 pages. Toggles went to h-11 w-11, the hover-only check became an always-visible text-slate-300, the mic button became min-h-[48px] px-5 py-3 text-base, nav links got min-h-[44px] + an active: state. TomorrowCard (the D-Day drill card, the most-used screen) had all its content bumped from 12–13.5px to 14–15.5px with darker text. On /talk the native checkbox toggle became a 44px pill and the correction/reply text — the actual reward you read while walking — went up to 14.5–15px.
Two things worth keeping: an HTTP 200 after deploy isn't verification (compare the running task's image digest to the pushed digest — see the earlier ECS false-positive entry), and hover:-only affordances are invisible on touch, so every hover reveal now has an always-on or active: companion.
Left for later: katas is the one screen that's genuinely unusable on a treadmill — its core loop is typing Java into a code editor. That needs a non-typing mode (line-ordering tap chips, or recite→reveal self-grade) rather than a CSS tweak. myvoice needs Korean voice dictation so new sentences can be added by speaking instead of typing.