From e7e16024b7705d7c03f63087e785ff424707ff73 Mon Sep 17 00:00:00 2001 From: Quintine <15965533+Quintine@users.noreply.github.com> Date: Mon, 21 Sep 2026 13:16:39 +1000 Subject: [PATCH] Show revealed battle components in one shared table area Present public plans in physical attacker/defender order with exact force dials, played leader portraits and printed strength, readable used-card faces and direct inspectors. Keep Cheap Heroes, printed Worthless category, empty slots and late rescue defense distinct. Preserve Banker, native bonus, KH, Stone Burner, Poison Tooth and Diplomat details rather than treating printed values as scores. Mount one shared display after the main grid so every viewer retains access while another seat owns a post-reveal choice. Keyboard links focus the display and pending controls. Render nothing before public revelation, select exact used identities from the authorized projection, and consume no private insight or hands. No game rule, saved field, endpoint, AI strategy or release gate changes. Five new cases cover genuine sealed/revealed actions, stable order, used-card privacy, JSON immutability, fractional dials, hero/Worthless/late/empty slots and both seats during a real Diplomat decision. All28 related focused cases passed before final rule-link adapter changes; types, lint, all 5017 offline tests and production build pass on the final stable source. First broad run caught plain rules-page anchors; next/link and test aliases correct this. Independent privacy/layout review and final follow-up found no material issues. No API/auth/persistence changes; HTTP tests and full game samples not repeated. Browser QA creates a fresh human Emperor/Easy Harkonnen lobby with genuine setup, then explicitly stages a conserved battle. Normal engine actions choose battle and seal the opponent plan; human browser action seals dial2, Captain Aramsham, Slip Tip and Shield. Public display absent beforehand and shows correct both plans afterward. Leader/opponent-card inspection, Escape/focus return, internal help, keyboard section links and refresh preserve the pending decision. At390x844, client/scrollWidth375, stacked panels299px, rules16px and controls44px; normal viewport restores1265px and two560.5px plans without horizontal overflow. Screenshot capture timed out; full visual/screen-reader acceptance remains open. All 1579 opening games, 3347 saved seats and auxiliary rows remain identical. One isolated QA game adds one seat and one entry receipt. Its room remains unchanged after human seal through inspection/help/refresh, and its saved seat remains unchanged. SQLite integrity and foreign keys pass. No server restart, migration, reset, recurring automation or calibration. Record Basic Moritani plus the full Leader Skills deck as the next concrete integration target, requiring coordinated profile guards and real Terror/death/ revival continuations. Existing rulings and mode gates stay explicit; the later Tleilaxu revival-offer ordering issue remains a gated integration dependency. Private evidence: 20260921-revealed-plans. Verified source tree: 8d5496cdea0076aa1cdab4590e95fcaa677c9d2d8513190c2ce9ac6c90bb9196 --- README.md | 4 + app/globals.css | 51 +++++++++--- components/game-table.tsx | 10 +-- components/revealed-battle.tsx | 77 ++++++++---------- components/revealed-plan-pieces.tsx | 47 +++++++++++ docs/COMPONENT_INVENTORY.md | 6 ++ docs/CURRENT_STATUS.md | 58 ++++++++------ docs/IMPLEMENTATION_STATUS.md | 10 +++ docs/REVEALED_BATTLE_COMPONENTS.md | 64 +++++++++++++++ game/reference.ts | 22 ++++++ tests/diplomat-defense-controls.test.tsx | 2 +- tests/kwisatz.test.ts | 2 +- tests/revealed-plan-pieces.test.tsx | 99 ++++++++++++++++++++++++ tests/spice-banker-controls.test.tsx | 2 +- 14 files changed, 368 insertions(+), 86 deletions(-) create mode 100644 components/revealed-plan-pieces.tsx create mode 100644 docs/REVEALED_BATTLE_COMPONENTS.md create mode 100644 tests/revealed-plan-pieces.test.tsx diff --git a/README.md b/README.md index 4841f0a8..47ddaf07 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,10 @@ Above the board, **Treachery draw pile** and **Spice draw pile** show live card counts separately from hands, auction cards and discards. See [draw-pile counts](docs/DRAW_PILES.md). +After both battle plans are revealed, **Compare revealed battle plans** opens +the shared dials, leader portraits and played card faces. Inspect any component, +then return to the pending decision. See [battle components](docs/REVEALED_BATTLE_COMPONENTS.md). + In **Your private hand**, search card names, filter by printed category or change the display order. **Show all cards** clears filters. Inspectors and card actions stay with each physical card. See [hand browsing](docs/HAND_BROWSING.md). diff --git a/app/globals.css b/app/globals.css index 8fecaac3..157ed743 100644 --- a/app/globals.css +++ b/app/globals.css @@ -946,18 +946,51 @@ footer { font-size: 15px; color: #e0ba75; } -.revealed-plans > div { +.revealed-plans { min-width: 0; padding: 20px; scroll-margin-top: 16px; } +.revealed-plan-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); gap: 16px; } +.battle-display-link { display: inline-flex; align-items: center; min-height: 44px; font-size: 16px; line-height: 1.5; text-decoration: underline; margin: 4px 0; } +#table-decisions { scroll-margin-top: 16px; } +.revealed-plans-help { font-size: 16px !important; line-height: 1.6; } +.revealed-plans-help a { text-decoration: underline; } +.revealed-plan { + min-width: 0; border: 1px solid #70633f; - padding: 14px; - margin: 10px 0; - font-size: 14px; + border-radius: 12px; + padding: 16px; + margin: 16px 0; + background: #181f19; } -.revealed-plans span { - display: block; - font-size: 12px; - color: #b5bca6; - margin-top: 8px; +.revealed-plan > h4 { margin: 0 0 12px; font-size: 20px; overflow-wrap: anywhere; } +.revealed-plan-detail { display: block; font-size: 16px; line-height: 1.6; color: #d0d5c7; margin: 8px 0; } +.revealed-plan-pieces { display: grid; gap: 14px; margin: 16px 0; min-width: 0; } +.revealed-plan-leader { display: flex; flex-wrap: wrap; align-items: stretch; gap: 14px; min-width: 0; } +.revealed-dial { + flex: 0 0 116px; align-self: center; width: 116px; height: 116px; margin: 0; + display: flex; flex-direction: column; align-items: center; justify-content: center; + border: 5px double #c5a66d; border-radius: 50%; + background: radial-gradient(circle at 38% 28%, #394331, #11170f); + box-shadow: inset 0 0 0 5px #222b1d; } +.revealed-dial dt { font-size: 14px; color: #e1d2b3; } +.revealed-dial dd { margin: 0; font: 36px/1.2 Georgia, serif; color: #fff0c9; } +.revealed-plan-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: 14px; } +.revealed-piece { + min-width: 0; display: flex; flex-direction: column; gap: 10px; padding: 16px; + border: 1px solid #a18b62; border-radius: 12px; background: linear-gradient(145deg, #35352a, #151b16); +} +.revealed-piece-weapon { background: linear-gradient(145deg, #512f28, #211b19); } +.revealed-piece-defense { background: linear-gradient(145deg, #284544, #18231f); } +.revealed-piece-leader { background: linear-gradient(145deg, #4b3c23, #221e15); } +.revealed-piece-utility { background: linear-gradient(145deg, #38344b, #1d1d26); } +.revealed-piece-empty { border-style: dashed; background: #171c17; } +.revealed-plan-leader > .revealed-piece { flex: 1 1 210px; } +.revealed-piece .revealed-piece-label { margin: 0; font-size: 14px !important; line-height: 1.5; color: #ebd4a4; } +.revealed-piece h4 { margin: 0; font: 22px/1.25 Georgia, serif; color: #fff1d3; overflow-wrap: anywhere; } +.revealed-piece .revealed-piece-rules { margin: 0; font-size: 16px !important; line-height: 1.6; color: #eee5d2; } +.revealed-piece > button { margin-top: auto; align-self: stretch; min-height: 44px; } +.revealed-leader { display: flex; flex-flow: row wrap; align-items: center; } +.revealed-leader > div { flex: 1 1 120px; min-width: 0; } +.revealed-leader > button { flex: 1 0 100%; } .prescience { display: grid; grid-template-columns: 1fr 1fr; diff --git a/components/game-table.tsx b/components/game-table.tsx index e0c4e63a..37d7ca2f 100644 --- a/components/game-table.tsx +++ b/components/game-table.tsx @@ -1562,10 +1562,11 @@ export function GameTable({ )} -