feat: phone layout for the séance screen

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>
This commit is contained in:
Indiana
2026-07-28 13:41:00 +00:00
parent 12e2d36527
commit 2e2c64d36b
2 changed files with 94 additions and 0 deletions

View File

@@ -165,3 +165,16 @@
0% { opacity: 1; transform: scale(1); }
100% { opacity: 0.32; transform: scale(0.92); }
}
/* The four verdicts sit two-up by default. On a phone that leaves each
button too narrow for its rune plus label, so they go full width — these
are irreversible, consequential choices and must not be mis-tapped. */
@media (max-width: 480px) {
.judgment-actions {
grid-template-columns: 1fr;
}
.verdict-btn {
min-height: 44px;
}
}

View File

@@ -1377,3 +1377,84 @@
display: none;
}
}
/* --- phones -------------------------------------------------------------
The 960px breakpoint above handles tablets by stacking the columns, but
left everything between 320px and 960px on one layout. Real phones sit at
390-430px, where the five mode tabs, the ask-form row, and the board all
need their own handling.
Principles: nothing horizontally scrolls the page; every interactive
target clears 44px (Apple's HIG floor, and Android's 48dp is close
enough that one rule serves both); and the board keeps enough height to
still read as a board rather than a strip. */
@media (max-width: 560px) {
/* Mode tabs scroll horizontally rather than wrapping into a tall stack
that pushes the board off screen. */
.seance-modes {
overflow-x: auto;
flex-wrap: nowrap;
scrollbar-width: none;
-webkit-overflow-scrolling: touch;
}
.seance-modes::-webkit-scrollbar {
display: none;
}
.mode-tab {
flex: 0 0 auto;
min-height: 44px;
padding: 0.35rem 0.7rem;
font-size: 0.68rem;
}
/* The ask row is an input plus two buttons — far too much for one line
at this width. The input takes the full row, the buttons share the
next one. */
.seance-contact {
flex-wrap: wrap;
}
.seance-contact input {
flex: 1 1 100%;
min-height: 44px;
/* 16px exactly: iOS Safari zooms the whole page when a focused input
is any smaller, which then leaves the layout zoomed after blur. */
font-size: 16px;
}
.ask-btn,
.summon-btn {
flex: 1 1 0;
min-height: 44px;
}
.seance-board-wrap {
/* Shorter than the tablet stack so the transcript stays visible
without scrolling, but tall enough that the planchette still has a
board to wander. */
min-height: 240px;
}
.seance-topbar {
padding: 6px 8px;
}
/* Two columns of voice params is unreadable this narrow. */
.voice-params {
grid-template-columns: 1fr;
}
}
/* Very small / older phones (SE-class, 320-375px). */
@media (max-width: 380px) {
.seance-board-wrap {
min-height: 200px;
}
.mode-tab {
font-size: 0.62rem;
padding: 0.3rem 0.55rem;
}
}