The page had a viewport tag and a 960px breakpoint that stacked the
columns for tablets, but nothing below it — so everything from 320px to
960px shared one layout. Real phones sit at 390-430px, where three things
actually broke:
- Five mode tabs on one row. They now scroll horizontally instead of
wrapping into a stack tall enough to push the board off screen.
- The ask row (text input + ask + summon) crammed onto one line. The
input now takes the full row and the two buttons share the next.
- The four judgment verdicts sat two-up, leaving each too narrow for its
rune plus label. They go full width — these are irreversible,
consequential choices and must not be mis-tapped.
Every interactive target now clears 44px (Apple's HIG floor; Android's
48dp is close enough that one rule serves both), and the ask input is
exactly 16px because iOS Safari zooms the whole page when a focused input
is any smaller and leaves the layout zoomed after blur.
A second breakpoint at 380px handles SE-class phones, mainly by giving the
board less height so the transcript stays visible without scrolling.
Audited the rest first rather than assuming: the many `max-width` rules
are mobile-safe (they cap, they don't force), and InventoryPanel's grids
already use auto-fill/minmax and self-collapse. Only the fixed
`repeat(2, 1fr)` grids needed touching.
355 frontend tests pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>