Pabloler21 Claude Opus 4.8 commited on
Commit
0508e33
Β·
1 Parent(s): 2cea026

docs: plan for game-view chrome polish (controls/drawers/dialogue), Space-verified

Browse files
docs/superpowers/plans/2026-06-15-game-chrome-polish.md ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Game-View Chrome Polish Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED first reads β€” `CLAUDE.md` (or `AGENTS.md`) and `docs/superpowers/AGENT-EXECUTION-BRIEF.md`. Branch `feat/game-chrome-polish` (already created off the deployed integration branch). Execute phase-by-phase, one commit per phase.
4
+ >
5
+ > **CRITICAL β€” verification is SPACE-ONLY.** Local rendering differs from the Space (this whole effort proved it: Gradio SSR, fonts, layout). Do NOT judge these visual changes locally and do NOT block on local appearance. The implementer applies the change + keeps tests green; **Pablo verifies on the live mirror Space after each phase's deploy** and we tune from there. Pixel values below are starting points to be tuned on the Space, not final.
6
+
7
+ **Goal:** Compose the game-view chrome around the (already-good) foggy scene + child. Three approved changes (from the visual-companion mockup): (1) controls become a minimal top-right **icon cluster** with "begin again" de-emphasized; (2) drawers show a **count** and read as tappable; (3) the dialogue anchors in a **consistent lower band**, two voices balanced inside the frame, older lines faded.
8
+
9
+ **Architecture:** Pure CSS in `styles.css` Β§26 for the controls + dialogue; `render.py` drawer-head strings for the count (+ a little CSS). No Python logic change β†’ 276 tests stay green (no new unit tests; this is visual chrome). The scene, child, fog, letterbox, palette, and input bar stay as-is.
10
+
11
+ **Workflow per phase:** implement β†’ `import app` + `pytest -q` green β†’ commit β†’ `git push space HEAD:main` (mirror) β†’ **Pablo verifies on the Space** β†’ tune if needed (extra commit + redeploy) β†’ next phase. Deploy to `hackathon` only after all three are confirmed on the mirror.
12
+
13
+ **Key seams (read the real text first):** `styles.css` `#game-topbar` (~1463), `.restart-btn` (~858), the mute `.voice-btn`; `#game-dialogue` + `.bot`/`.user` (~218); `.game-drawer` (~1493). `render.py` drawer-head strings (~339 recovered, ~362 treasure). `app.py` restart/voice buttons (`elem_classes="restart-btn"` / `"voice-btn"`).
14
+
15
+ ---
16
+
17
+ ### Phase 1: Controls β†’ a minimal top-right icon cluster (highest impact)
18
+
19
+ Make `begin again` + mute a small, low-contrast, grouped cluster (icons, labels on hover), with `begin again` de-emphasized to a quiet `β†Ί`. Today they're two mismatched boxes in the hottest corner, and the destructive restart is the most prominent thing on screen.
20
+
21
+ **Files:** `app.py` (button labels), `styles.css` (`.restart-btn`, `.voice-btn`, `#game-topbar`).
22
+
23
+ - [ ] **Step 1: Slim the restart button label.** In `app.py`, the restart button currently reads `"β†Ί begin again"`. Change its label to just `"β†Ί"` and add a `title` for the native hover tooltip (find the `gr.Button(... elem_classes="restart-btn" ...)`; keep `elem_id`/`elem_classes`):
24
+ - label `"β†Ί begin again"` β†’ `"β†Ί"`; if Gradio `gr.Button` supports it, this is a label-only change (the JS still wires `.restart-btn`). Do NOT touch the click wiring.
25
+ - (The mute `.voice-btn` already shows an icon β€” leave its label.)
26
+
27
+ - [ ] **Step 2: Restyle the cluster in `styles.css` Β§26.** Replace the boxy `.restart-btn` look with a small hairline icon, and group it tight with the mute button. Starting point (tune on the Space):
28
+ - `.restart-btn`: drop the filled background/border box β†’ `background:transparent !important; border:none !important; max-width:none; min-width:0; width:auto !important; font-size:1rem !important; color:#8b83a2 !important; opacity:.7; padding:4px 6px;` and on `:hover` `color:#e0cdb0 !important; opacity:1;` (amber-tinted, in-world).
29
+ - `.voice-btn`: same minimal treatment (transparent, hairline-on-hover, `color:#b6acd0`, small).
30
+ - Group them: the topbar's right side already holds both; add a small gap and right-align them as one cluster (e.g. wrap target `#game-topbar` right items or set `.restart-btn, .voice-btn { margin-left:10px; }`). Keep `#game-title` on the left, but consider reducing `#game-title` `font-size` to ~`0.9rem` and `color:#7d7596` so the child stays the hero (tune on the Space).
31
+ - Optional hover label: a CSS `::after` on `.restart-btn` showing "begin again" on hover is nice-to-have; the `title` tooltip from Step 1 already covers it β€” skip the CSS label unless Pablo wants it.
32
+
33
+ - [ ] **Step 3:** `import app` β†’ ok; `pytest -q` β†’ 276 green. Commit:
34
+ ```bash
35
+ git add app.py styles.css
36
+ git commit -m "style(game): minimal top-right control cluster, de-emphasized restart"
37
+ ```
38
+ - [ ] **Step 4:** `git push space HEAD:main` β†’ Pablo verifies the cluster on the Space; tune values if needed (extra commit + redeploy) before Phase 2.
39
+
40
+ ---
41
+
42
+ ### Phase 2: Drawer counts + tappable affordance
43
+
44
+ Show how many items each drawer holds and make it read as openable.
45
+
46
+ **Files:** `render.py` (drawer-head strings), `styles.css` (`.game-drawer`).
47
+
48
+ - [ ] **Step 1: Add the count to the drawer headers.** In `render.py`:
49
+ - Treasure head (~line 362): the header uses a `title` var β€” append the count of shown items, e.g. `f'{title} <span class="drawer-count">Β· {n}</span>'` where `n` is the number of treasure entries rendered. Pass/compute the count from the items the function already has.
50
+ - Recovered head (~line 339): `"✦ What it remembers"` β†’ `f'✦ What it remembers <span class="drawer-count">Β· {n}</span>'` with `n` = recovered/claimed count it already renders.
51
+ - Keep the `✦` decoration and the `_HEADER` inline style.
52
+
53
+ - [ ] **Step 2: Style the count + a clearer tappable state in `styles.css`.** Starting point:
54
+ - `.drawer-count { color: var(--mem-accent, #e0b283); font-weight: 600; }`
55
+ - Strengthen the chip's "tappable" read: `.game-drawer { opacity: .82; }` and `.game-drawer:hover { opacity: 1; border-color: rgba(180,160,210,.4); }` (it already toggles `.open` on click; just make hover clearer).
56
+
57
+ - [ ] **Step 3:** `import app` β†’ ok; `pytest -q` β†’ 276 green (if a render test asserts the exact old header string, update it to include the count β€” check `tests/test_render.py`). Commit:
58
+ ```bash
59
+ git add render.py styles.css
60
+ git commit -m "style(game): drawer counts + clearer tappable affordance"
61
+ ```
62
+ - [ ] **Step 4:** `git push space HEAD:main` β†’ Pablo verifies on the Space; tune; then Phase 3.
63
+
64
+ ---
65
+
66
+ ### Phase 3: Dialogue β†’ a consistent lower band, balanced two voices, faded history
67
+
68
+ Anchor the subtitle transcript in a steady lower band with a soft scrim, keep both voices INSIDE the frame (the player's line currently jams to the far-right edge), and fade older lines so only the last ~2 read strongly.
69
+
70
+ **Files:** `styles.css` (`#game-dialogue`, `.bot`, `.user`, the chatbot message rows).
71
+
72
+ - [ ] **Step 1: Anchor + scrim.** In Β§26, give `#game-dialogue` a consistent position in the lower third and a soft bottom scrim behind the text for legibility over the scene (a `::before` gradient `transparent β†’ rgba(5,4,10,.6)`), so text never sits naked on a bright fog patch. Keep it inside the frame vars (`--fw/--band-h`).
73
+ - [ ] **Step 2: Balance the two voices INSIDE the frame.** `.bot` (the child) stays centered/left; `.user` (you) right-aligns but clamps within the frame (`max-width`, `margin-right` off the edge β€” today it bleeds to the far right / cuts off). Keep the small `YOU` label (`.user`'s `::before` or existing label) and the child/you color split.
74
+ - [ ] **Step 3: Fade older lines.** Make only the last ~2 messages fully opaque; older ones dim (e.g. target all but the last two chatbot rows with reduced opacity, or a top fade-mask on the scroll container). The transcript already auto-scrolls; this just reduces the 5-line pile-up competing with the child. (Verify against the running app β€” do NOT disable opacity under `prefers-reduced-motion`; per the gotcha, only sway/fog are disabled there.)
75
+ - [ ] **Step 4:** `import app` β†’ ok; `pytest -q` β†’ 276 green. Commit:
76
+ ```bash
77
+ git add styles.css
78
+ git commit -m "style(game): anchored lower dialogue band, balanced voices, faded history"
79
+ ```
80
+ - [ ] **Step 5:** `git push space HEAD:main` β†’ Pablo verifies on the Space; tune until it reads right.
81
+
82
+ ---
83
+
84
+ ### Phase 4: Ship
85
+
86
+ - [ ] **Step 1:** Once all three are confirmed good on the mirror, deploy the submission: `git push hackathon HEAD:main`, verify live.
87
+ - [ ] **Step 2:** Merge `feat/game-chrome-polish` back into the integration branch.
88
+
89
+ ---
90
+
91
+ ## Self-Review
92
+ - **Spec coverage:** controls cluster (Phase 1), drawer counts (Phase 2), dialogue band (Phase 3) β€” the three approved mockup changes βœ…. Scene/child/fog/input untouched βœ….
93
+ - **Space-only verification** is the spine: every phase deploys to the mirror and Pablo judges there; pixel values are starting points, tuned live. No local visual judgement.
94
+ - **Risk / gotchas:** these touch Gradio-styled internals (the chatbot rows, the buttons), so behavior can differ on the Space β€” that's exactly why each phase is verified live before the next. Don't disable opacity under `prefers-reduced-motion` (Phase 3). If a `test_render.py` test pins an old drawer header string, update it (Phase 2). Edits via Edit tool only (UTF-8: `β†Ί`, `✦`, em-dashes).
95
+ - **No tuple/logic hazard:** counts come from data the render functions already have; the restart label change doesn't touch the `.restart-btn` JS wiring (`openingRitual` + server `_reset`).
96
+ ```