# Layout Review Fix Plan — 2026-04-13_run5

Generated by `/layout-review`. Total findings: **5**.
Review this plan and approve before any changes are made.
This skill did not modify any source files.

**Run scope:** Settings (08) and Poker Guide (09) screens were intentionally skipped at Brett's request. 10 screens × 7 devices = 99 screenshots captured.

## Summary

| # | Severity | Screen | Issue | Category |
|---|----------|--------|-------|----------|
| 1 | P1 | Pre-Flop Result | EV value text truncated with ellipsis on narrow bars | Needs Review |
| 2 | P2 | Read Ready | Report FAB overlaps "Straight Flush" button in 3-col grid (fold) | Needs Review |
| 3 | P2 | Live Ready | Report FAB overlaps "Bet Pot" button on wide tablet | Needs Review |
| 4 | P2 | Hand History | Period/mode filter pills truncated on 360dp phones | Needs Review |
| 5 | P2 | Live Ready | 4-button postflop row cramped on standard phones (412–430dp) | Needs Review |

---

## Auto-Fix Eligible

_No findings in this run qualified as mechanical one-line edits. Each issue needs a design decision before a code change can be pinned down._

---

## Needs Review

These require design decisions, layout restructuring, or have potential side effects. Each includes a proposed fix approach for Brett's judgment.

### <h3 id="issue-1">Issue 1 — P1: EV value text truncated with ellipsis on narrow bars</h3>

**Screen:** 03 Pre-Flop Result
**Affected devices:** small-se (375dp), std-galaxys24 (360dp)
**Requirement violated:** REQUIREMENTS.md §Pre-Flop Result — "EV value text must be on a single line. Text wrapping mid-unit (showing '-0.44b' / 'b' on two lines) is always a bug (P1)." Feedback History 2026-04-13.
**Screenshots:**
- review/2026-04-13_run5/small-se_03_preflop_result_b.png — "Open" bar shows `+0.08...`
- review/2026-04-13_run5/std-galaxys24_03_preflop_result_b.png — both "Call" and "4-Bet" bars show `-0.22...`

The `numberOfLines={1}` fix from run 4 prevented mid-unit wrap, but the value is now tail-truncated with an ellipsis on narrow (losing-EV) bars. The source-code comment in [ResultPanel.tsx:60-64](src/components/ResultPanel.tsx#L60-L64) explicitly states the evValue Text should "extend past the bar edge into the evTrack's dark background without being clipped." In practice, React Native does not let a Text child visually overflow its flex parent without either `position: 'absolute'` or shrinking the Text below the parent width — so `numberOfLines={1}` ends up clipping.

**Proposed fix (needs judgment between two approaches):**

**Option A — Absolute-positioned value (preserves overflow semantics):**
In [ResultPanel.tsx:58-72](src/components/ResultPanel.tsx#L58-L72), restructure the evTrack so it contains BOTH the `evBar` (fill only, no children) AND an absolutely-positioned `evValue` Text that's anchored to the left edge of the track with `paddingLeft: fs(8)` — letting the text naturally extend across the full track width regardless of bar size.

```tsx
<View style={[styles.evTrack, { height: fs(30), borderRadius: fs(6) }]}>
  <View style={[styles.evBar, { width: `${w}%`, backgroundColor: barColor, borderRadius: fs(6) }]} />
  <Text
    numberOfLines={1}
    style={[styles.evValue, { color: isOk ? '#0A1E2E' : isSlight ? '#713f12' : isSel ? '#fca5a5' : '#3A5A6A', fontSize: fs(12), position: 'absolute', left: fs(8), top: 0, bottom: 0, textAlignVertical: 'center' }]}
  >
    {a.ev >= 0 ? '+' : ''}{a.ev.toFixed(2)}bb
  </Text>
</View>
```

**Option B — Shrink the font on narrow bars:**
Conditionally reduce the evValue font size when the bar width `w` < some threshold (e.g. `w < 20` → `fs(10)` instead of `fs(12)`), so the string still fits inside the bar. Keeps structure simpler but visually inconsistent across rows.

Recommend Option A — matches the existing comment's intent and gives consistent typography.

---

### <h3 id="issue-2">Issue 2 — P2: Report FAB overlaps "Straight Flush" answer button on fold-zfold6-inner (3-col grid)</h3>

**Screen:** 05 Read (ready state)
**Affected devices:** fold-zfold6-inner (768×832)
**Requirement violated:** REQUIREMENTS.md §Global — No Overlapping. Action buttons must not be obscured by floating chrome.
**Screenshot:** review/2026-04-13_run5/fold-zfold6-inner_05_read.png

The 3-column answer grid that kicks in at `width ≥ 744dp` places the 9th button ("Straight Flush") in the bottom-right cell. The "!" Report FAB is anchored `position: 'absolute'` at bottom-right and visibly covers the right third of that button (its label still shows but the right-edge tap target is obscured by the FAB hit circle). On phones (2-col grid), the 9th button sits in the left column so the FAB never overlaps — this is a fold/tablet-grid-specific issue.

**Why it can't be auto-fixed:** Requires a layout decision — shift the grid up, pad the grid bottom, or relocate the FAB. Each has tradeoffs with other screens that share the FAB.

**Proposed fix:**

Add a `paddingBottom` to the answer-button grid's container in [ReadScreen.tsx](src/screens/ReadScreen.tsx) that reserves space for the FAB on tablet-width devices. The FAB diameter is roughly `fs(56)`; an extra `fs(64)` of bottom padding when `isTablet` would keep the bottom-right button clear. Alternatively, reorder the button array so the "overflow" cell (when `count % cols !== 0`) lands in the LEFT cell rather than the right — matches the phone behavior where Straight Flush is in the left column alone.

The reorder is the smaller change (one line: change `justifyContent` on the last row or reorder options) but may leave a visual hole on the right side of the last row. Test both on fold, tablet-ipadmini, and tablet-ipadpro129.

---

### <h3 id="issue-3">Issue 3 — P2: Report FAB overlaps "Bet Pot" action button on tablet-ipadpro129</h3>

**Screen:** 04 Live Ready
**Affected devices:** tablet-ipadpro129 (1024×1366)
**Requirement violated:** REQUIREMENTS.md §Global — No Overlapping.
**Screenshot:** review/2026-04-13_run5/tablet-ipadpro129_04_live_ready.png

Same root cause as Issue 2 — the absolute-positioned bottom-right FAB overlaps the rightmost Live postflop bet-sizing button ("Bet Pot 5.5bb"). On phones the action button row is taller/higher up and the FAB sits below it; on tablet-ipadpro129 the button row ends near the bottom safe area and the FAB intrudes into the tap zone.

Not reproduced on tablet-ipadmini — that device's smaller height leaves more room between the buttons and the FAB.

**Proposed fix:**

Two paths, and they compose:

1. **Increase bottom padding of the Live action-button row on tablets** — add `marginBottom: fs(64)` (FAB clearance) to the action-button row's outer container in [LiveScreen.tsx](src/screens/LiveScreen.tsx) when `isTablet && width >= 1000`.
2. **Or raise the FAB above the action row on screens that render a bottom button bar** — global change across TrainScreen, CustomPlayScreen, LiveScreen, ReadScreen, BestScreen. More invasive.

Recommend the per-screen padding fix — minimal blast radius. Since the same FAB overlap issue may also appear in Train/Custom/Best on tablet-ipadpro129 (not exercised with scroll-captures in this run), apply the pattern defensively.

---

### <h3 id="issue-4">Issue 4 — P2: Hand History period/mode filter pills truncated on 360dp-class phones</h3>

**Screen:** 10 Hand History
**Affected devices:** small-se (375dp), std-galaxys24 (360dp)
**Requirement violated:** REQUIREMENTS.md §Global — nothing clipped or truncated. Per-Screen Rules §10 — "period filter pills (Today / Week / All-Time) must all be visible in the first shot" / "mode filter pills (Pre-Flop / Live) must be visible in the first shot" with full labels.
**Screenshots:**
- review/2026-04-13_run5/small-se_10_hand_history_a.png — "Pre-Fl..." truncated
- review/2026-04-13_run5/std-galaxys24_10_hand_history_a.png — "All-Ti..." and "Pre-Fl..." truncated

In [HandHistoryScreen.tsx:1401-1409](src/screens/HandHistoryScreen.tsx#L1401-L1409) the pill container uses `flex: 1` (equal-width). On 360dp with 5 pills + separator, each pill is ~60dp; at scale 0.75 the 8-char labels "All-Time" and "Pre-Flop" don't fit at `fs(13)`.

**Why it can't be auto-fixed:** Multiple valid approaches:

**Option A — Drop the `flex: 1` and let pills size to content, wrap to second row on narrow phones:**
Remove `flex: 1` from `styles.pill` and set the pillRow to `flexWrap: 'wrap'`. Let pills intrinsic-size and wrap. Takes more vertical space on narrow phones, clean on wider ones.

**Option B — Conditional short labels on narrow phones:**
Branch the label strings on `width < 400`: "All-Time" → "All", "Pre-Flop" → "Pre-F" (or "PF"). Slightly less readable but preserves single-row layout.

**Option C — Reduce horizontal padding + font size on narrow phones:**
`paddingHorizontal: width < 400 ? 6 * scale : 12 * scale` and `fontSize: width < 400 ? fs(11) : fs(13)`. Mechanical but makes the pills look cramped.

Recommend **Option A (wrap to second row)** — preserves label legibility at the cost of one extra row of vertical space. Matches the Live postflop button-wrap pattern already accepted on narrow phones.

---

### <h3 id="issue-5">Issue 5 — P2: 4-button postflop action row cramped on standard phones (412–430dp)</h3>

**Screen:** 04 Live Ready (postflop state)
**Affected devices:** std-pixel8 (412dp), large-iphone14max (430dp)
**Requirement violated:** REQUIREMENTS.md §Button Content Density + Android Rendering Notes (CLAUDE.md) — "Never put more than 2-3 buttons in a single flexDirection: row; stack into multiple rows instead." Feedback History notes the 2-row wrap is intentional on small-se/std-galaxys24.
**Screenshots:**
- review/2026-04-13_run5/std-pixel8_04_live_ready.png — 4 buttons (Check, Bet 33% 1.8bb, Bet 66% 3.4bb, Bet 95% 5.5bb) each ~95dp wide, ~12sp labels
- review/2026-04-13_run5/large-iphone14max_04_live_ready.png — same 4 buttons, still cramped at 430dp

The existing `flexBasis: '47%'` wrap threshold in LiveScreen currently triggers only on small-se and std-galaxys24 (≤ 393dp). std-pixel8 and large-iphone14max stay on a single row and render the bet-sizing labels at ~12sp in a ~95dp button — below the REQUIREMENTS.md ≥ 16sp action-button minimum.

**Why it can't be auto-fixed:** Threshold change affects all devices between 394dp and 743dp. A ≤ 430dp cutoff preserves tablet/fold single-row layouts; a bolder ≤ 500dp cutoff would wrap on every phone-class device.

**Proposed fix:**

Raise the wrap threshold in [LiveScreen.tsx](src/screens/LiveScreen.tsx) (search for the existing `flexBasis: '47%'` condition — likely gated on `width < 400` or similar). Change the breakpoint so 2-row wrap applies at `width <= 430` (covering std-pixel8 and large-iphone14max), still single-row on fold/tablet (≥ 744dp). Verify visually on all 4 phone devices after the change.

Note: this mirrors the already-accepted small-phone postflop wrap in Feedback History ("Live postflop narrow-phone 2-row button wrap via flexBasis 47% + flexWrap is intentional to prevent cramped 'Bet 33% 1.8bb' labels"). This change simply extends the same pattern up the phone ladder.

---

## Screens skipped in this run

- **08 Settings** — skipped at Brett's request.
- **09 Poker Guide** — skipped at Brett's request.

---

## Previously-known issues — status check

No still-open findings were inherited from run 4 (all run 4 issues were either fixed between runs or are documented as accepted design in Feedback History).

---

## Post-run reminders

1. This skill did not modify any source files. All edits are pending Brett's approval.
2. Open `review/2026-04-13_run5/gallery.html` in a browser to scan the full 99-screenshot matrix.
3. Issue 1 (P1) should be prioritized — EV value truncation directly obscures coaching feedback on the most-used training mode.
