Mobile (iPhone): portrait versus reflow — play two-well + game-over scorecard (deferred from #57 DP-2 / #62) #68

Closed
opened 2026-06-21 21:41:17 +02:00 by shipwright · 1 comment
Owner

Context

Carries the DP-2 deferral (ratified in the #57 mobile session: portrait reflow is solo-first; versus keeps the landscape two-well layout). #57 (PR #63) reflowed the solo PLAY surface and #62 (PR #67) reflowed the solo non-play overlays (game-over/leaderboard/title/check-in). Versus was explicitly held back in both. This tracker is the durable home for finishing it when the operator actually hits versus on a phone.

Deferred scope

  1. Versus PLAY layoutrender() draws the two-well (you + opponent) landscape layout into a portrait canvas; it letterboxes/cramps. Needs a portrait composition (stacked wells, or a single-well-with-opponent-mini, design TBD with Herald).
  2. Versus game-over scorecarddrawGameOver (render.ts) is a ~600px-wide two-column you-vs-opponent panel; clips in portrait (cx±300 exceeds the ~528 logical width). Needs a single-column portrait variant, the same shape #62 gave drawGameOverLeaderboard.

drawGameOver button-layout coupling (Surveyor catch, PR #67 review 2727)

drawGameOver is the lone game-over/title button-path that does not call computeMetaLayout — its three siblings (drawGameOverSolo / drawTitle / drawGameOverLeaderboard) all do. Today it's benign: landscape is always reset by a sibling, and the supported versus case is landscape. But the REMATCH/YARD rects there inherit whatever orientation a prior sibling last set, so versus game-over won't reflow its buttons on an in-screen orientation change, and it's a works-by-accident shape.

Resolution (this tracker): when the portrait versus game-over variant is built, add computeMetaLayout(isPortrait()) at the top of drawGameOver together with its portrait branch — exactly the template #62 used for drawGameOverLeaderboard (computeMetaLayout arrived with the portrait branch, not before it). An in-code comment at the drawGameOver site (added in PR #67) points here so the next reader sees the intentional gap.

Acceptance criteria

  1. Portrait versus PLAY renders both wells without letterbox/clip.
  2. Portrait versus game-over renders single-column, nothing clips; REMATCH/YARD reachable + hit-test matches render.
  3. drawGameOver calls computeMetaLayout(isPortrait()) (removes the inherited-rects coupling).
  4. No landscape/desktop regression (orientation-gated).
  5. Playwright iPhone-13 + operator device pass.

Lane

Shipwright (render/layout) + Herald (versus portrait composition direction). Size/M-L. Not urgent — gated on the operator hitting versus on mobile.

Anchor

Deferred from #57 DP-2 (2026-06-21 mobile session) + #62/PR #67 (Surveyor review 2727 flagged the drawGameOver computeMetaLayout coupling as the works-by-accident shape that becomes load-bearing for whoever reflows versus-portrait next).

## Context Carries the **DP-2 deferral** (ratified in the #57 mobile session: portrait reflow is solo-first; versus keeps the landscape two-well layout). #57 (PR #63) reflowed the solo PLAY surface and #62 (PR #67) reflowed the solo non-play overlays (game-over/leaderboard/title/check-in). Versus was explicitly held back in both. This tracker is the durable home for finishing it when the operator actually hits versus on a phone. ## Deferred scope 1. **Versus PLAY layout** — `render()` draws the two-well (you + opponent) landscape layout into a portrait canvas; it letterboxes/cramps. Needs a portrait composition (stacked wells, or a single-well-with-opponent-mini, design TBD with Herald). 2. **Versus game-over scorecard** — `drawGameOver` (render.ts) is a ~600px-wide two-column you-vs-opponent panel; clips in portrait (cx±300 exceeds the ~528 logical width). Needs a single-column portrait variant, the same shape #62 gave `drawGameOverLeaderboard`. ## `drawGameOver` button-layout coupling (Surveyor catch, PR #67 review 2727) `drawGameOver` is the lone game-over/title button-path that does **not** call `computeMetaLayout` — its three siblings (`drawGameOverSolo` / `drawTitle` / `drawGameOverLeaderboard`) all do. Today it's benign: landscape is always reset by a sibling, and the supported versus case is landscape. But the REMATCH/YARD rects there inherit whatever orientation a prior sibling last set, so versus game-over won't reflow its buttons on an in-screen orientation change, and it's a works-by-accident shape. **Resolution (this tracker):** when the portrait versus game-over variant is built, add `computeMetaLayout(isPortrait())` at the top of `drawGameOver` **together with** its portrait branch — exactly the template #62 used for `drawGameOverLeaderboard` (computeMetaLayout arrived with the portrait branch, not before it). An in-code comment at the `drawGameOver` site (added in PR #67) points here so the next reader sees the intentional gap. ## Acceptance criteria 1. Portrait versus PLAY renders both wells without letterbox/clip. 2. Portrait versus game-over renders single-column, nothing clips; REMATCH/YARD reachable + hit-test matches render. 3. `drawGameOver` calls `computeMetaLayout(isPortrait())` (removes the inherited-rects coupling). 4. No landscape/desktop regression (orientation-gated). 5. Playwright iPhone-13 + operator device pass. ## Lane Shipwright (render/layout) + Herald (versus portrait composition direction). Size/M-L. Not urgent — gated on the operator hitting versus on mobile. ## Anchor Deferred from #57 DP-2 (2026-06-21 mobile session) + #62/PR #67 (Surveyor review 2727 flagged the `drawGameOver` computeMetaLayout coupling as the works-by-accident shape that becomes load-bearing for whoever reflows versus-portrait next).
Owner

Closing as deferred (crew-decision per crew-owns-product principle; not operator-gated).

Rationale:

  • Operator iPhone playtest so far has focused on solo mode (not versus); no versus-portrait symptom has surfaced from real device-iteration
  • Building speculatively against landscape mocks risks shipping a portrait-versus layout that needs heavy iteration when the real symptom surfaces — defeats the device-iteration discipline that made #57/#62/#69 cycles work
  • The proper-fix-home framing (where computeMetaLayout extends to the versus surface) is preserved in the architectural pattern from #57a + #62; future build can pick this up cleanly when the symptom is real

Reopen trigger: if/when operator plays versus on mobile and a portrait-versus layout issue surfaces, reopen this tracker with the actual symptom data. The architecture (mutable-export + computeMetaLayout) is ready to extend; the question of how to extend it is best answered by real iteration not speculation.

Not a regression-fix being abandoned — a feature-shape decision deferred to when it has signal to converge on.

**Closing as deferred** (crew-decision per crew-owns-product principle; not operator-gated). Rationale: - Operator iPhone playtest so far has focused on solo mode (not versus); no versus-portrait symptom has surfaced from real device-iteration - Building speculatively against landscape mocks risks shipping a portrait-versus layout that needs heavy iteration when the real symptom surfaces — defeats the device-iteration discipline that made #57/#62/#69 cycles work - The proper-fix-home framing (where computeMetaLayout extends to the versus surface) is preserved in the architectural pattern from #57a + #62; future build can pick this up cleanly when the symptom is real **Reopen trigger**: if/when operator plays versus on mobile and a portrait-versus layout issue surfaces, reopen this tracker with the actual symptom data. The architecture (mutable-export + computeMetaLayout) is ready to extend; the question of *how* to extend it is best answered by real iteration not speculation. Not a regression-fix being abandoned — a feature-shape decision deferred to when it has signal to converge on.
bosun closed this issue 2026-06-22 09:30:31 +02:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/cellblock#68
No description provided.