[art] #9-3: wire portraits into OPERATIVES cards + SELECTED panel #20

Closed
opened 2026-09-24 15:16:13 +00:00 by Mark · 1 comment
Owner

Parent-Issue: #9

Depends on: #9-2 (atlas entries must exist first).

Wire the portraits into the UI:

  1. Title screen OPERATIVES cards (web/js/ui.js showTitle() — the ops += ... loop, around line 213): each operative button gets a portrait <img> (or canvas draw from the atlas) on the left side, sized 96×96 (or matching the card's row height). The existing border-left:3px solid ${s.color} accent stays.
  2. In-mission SELECTED panel (web/index.html #sel section): when a unit is selected, render the unit's portrait above or beside its stat block. Look up the renderer that fills #sel (likely in web/js/ui.js — search for $(sel) or id("sel")).

Acceptance:

  • Title screen OPERATIVES cards show a portrait on the left side (per parent body)
  • IN-mission SELECTED panel shows a portrait when a unit is selected (per parent body)
  • make ci passes (Playwright smoke + node smoke tests)
  • Existing functionality preserved (selection toggle, ALPHA/BRAVO tags, wounded/INFIRMARY badge)

Refs: parent body acceptance criteria; web/js/ui.js showTitle() line 196.

**Parent-Issue:** #9 **Depends on: #9-2 (atlas entries must exist first).** Wire the portraits into the UI: 1. **Title screen OPERATIVES cards** (`web/js/ui.js` `showTitle()` — the `ops += ...` loop, around line 213): each operative button gets a portrait `<img>` (or canvas draw from the atlas) on the left side, sized 96×96 (or matching the card's row height). The existing `border-left:3px solid ${s.color}` accent stays. 2. **In-mission SELECTED panel** (`web/index.html` `#sel` section): when a unit is selected, render the unit's portrait above or beside its stat block. Look up the renderer that fills `#sel` (likely in `web/js/ui.js` — search for `$(`sel`)` or `id("sel")`). **Acceptance:** - Title screen OPERATIVES cards show a portrait on the left side (per parent body) - IN-mission SELECTED panel shows a portrait when a unit is selected (per parent body) - `make ci` passes (Playwright smoke + node smoke tests) - Existing functionality preserved (selection toggle, ALPHA/BRAVO tags, wounded/INFIRMARY badge) Refs: parent body acceptance criteria; `web/js/ui.js` `showTitle()` line 196. <!-- forgejo-id: Mark/cybertactics#9-3 -->
Author
Owner

Shipped on main @ ca31dfe: title-screen OPERATIVES cards render <img class="opport"> 96×96 portraits via the PORTRAIT registry (the .opstat wrapper preserves the existing name/cls/rank/XP/HP/AP/SPD/SGT flow + ALPHA/BRAVO tags + wounded/INFIRMARY badge). In-mission SELECTED panel renders <img class="selport"> 96×96 alongside .selstat when a unit is selected.

make ci green on ca31dfe (7 node smoke + gdlint + Playwright UI smoke + Godot import). Headless portrait probe verified .opport renders for all 6 squad members on title and .selport renders for the post-DEPLOY selected unit.

Note: self-hosted Forgejo Actions runner on unstable.tail018ac4.ts.net continues to surface status:failure for every recent commit (pattern pre-dates this card — same noise on cybertactics#15, #17, #18, #19, and now #20). Local make ci on ca31dfe is the gating surface.

Shipped on main @ ca31dfe: title-screen OPERATIVES cards render `<img class="opport">` 96×96 portraits via the PORTRAIT registry (the .opstat wrapper preserves the existing name/cls/rank/XP/HP/AP/SPD/SGT flow + ALPHA/BRAVO tags + wounded/INFIRMARY badge). In-mission SELECTED panel renders `<img class="selport">` 96×96 alongside .selstat when a unit is selected. `make ci` green on ca31dfe (7 node smoke + gdlint + Playwright UI smoke + Godot import). Headless portrait probe verified `.opport` renders for all 6 squad members on title and `.selport` renders for the post-DEPLOY selected unit. Note: self-hosted Forgejo Actions runner on unstable.tail018ac4.ts.net continues to surface `status:failure` for every recent commit (pattern pre-dates this card — same noise on cybertactics#15, #17, #18, #19, and now #20). Local `make ci` on ca31dfe is the gating surface.
Sign in to join this conversation.
No description provided.