Implementation Plan 18.1: Crucible UI & Combat Loop Integration
This document outlines the comprehensive technical design and step-by-step implementation plan to resolve all accumulated UI/UX cosmetic issues, layout debt, and critical combat loop state bugs identified during the Sprint 18 E2E Sandbox Crucible runs.📋 Architectural Context & Objectives
All fixes must adhere to the core guidelines established in Sprint 13 & 14:- Zero-Hardcoding Policy: No physical JSON files or hardcoded credentials. Rely entirely on environment-injected Base64 service accounts.
- Deterministic State Machine: Ensure the frontend remains an exact, deterministic mirror of the synced backend state, specifically avoiding unauthorized intermediate terminal states (e.g., preserving
RESOLVEDas the terminal state). - Anti-Meta Rules: The core spatial coordinates (vectors) of the central Target News Stub must remain 100% air-gapped from the player to prevent client-side meta-gaming.
🛠️ Proposed Changes
Phase A: The Arena & Compass Overhaul
This phase refactors the Faction Selection lobby and general user navigation shell to align with the political compass and correct terminology.1. Faction Selection 2x2 Grid Layout
- File:
frontend/app/arena/page.tsx - Target: Refactor the container element rendering the list of available factions.
- Design:
- Utilize CSS Grid with
grid-cols-2 grid-rows-2to represent the classic Political Compass. - Enforce the canonical ordering:
- Top-Left:
AUTH_LEFT(Authoritarian Left / Red / Labor) - Top-Right:
AUTH_RIGHT(Authoritarian Right / Blue / Dinars) - Bottom-Left:
LIB_LEFT(Libertarian Left / Green / Pronouns) - Bottom-Right:
LIB_RIGHT(Libertarian Right / Yellow / Monke)
- Top-Left:
- Utilize CSS Grid with
2. Faction Selection UI Overlap & Label Copy
- File:
frontend/app/arena/page.tsx - Target: Update the overlay text and layout for the selected faction.
- Design:
- Replace the confusing
"LOCKED"text badge with"SELECTED". - Fix absolute positioning and set
z-indexvalues so the text badge sits cleanly below or inside a defined action frame without overlapping the faction’s primary SVG emblem or icon.
- Replace the confusing
3. Pill Box Placement Relocation
- File:
frontend/app/arena/page.tsx - Target: Completely remove the
"Pill Box"tracking indicator and container from the Arena Entryway / Faction Selection page. - Rationale: The Pill Box tracking belongs strictly inside the user’s personal
/bunkerand during active play in/arena/[lobbyId]. Its presence in the entryway creates visual clutter.
4. Deck Stats Terminology Alignment
- File:
frontend/app/arena/page.tsx - Target: Rename core deck statistics text labels to clarify their gameplay impact.
- Changes:
- Rename
MAGNITUDEtoVector Impact(representing the raw power to push the coordinates). - Rename
RESILIENCEtoCoordinate Defense(representing the defense rating to resist coordinate shifts). - Update any localized help-text, tooltips, or descriptions to maintain semantic alignment.
- Rename
Phase B: The Radial Combat Layout
This phase re-architects the primary screen layout of the active game board into a geographic 2x2 grid matching the Political Compass Meme style.- File:
frontend/app/arena/[lobbyId]/page.tsx - Current Layout: A landscape split dividing the viewport into a Left Column (Target Vector / HUD) and a Right Column (Contender Vectors horizontal row).
- Refactored Layout:
- Re-architect the combat zone into a nested CSS Grid or absolute container representing the 2x2 Political Compass quadrant structure.
- Center: Place the Active News Stub in the dead center of the 2x2 arena grid (applying absolute centering
top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-30). - Four Corners: Place the four Contender Slots in their respective geographic positions:
- Top-Left: Player aligned with Authoritarian Left.
- Top-Right: Player aligned with Authoritarian Right.
- Bottom-Left: Player aligned with Libertarian Left.
- Bottom-Right: Player aligned with Libertarian Right.
- Connecting Rays: Render modern CSS neon lines or micro-animations extending from the center News Stub out to each contender slot to visually represent the radial “Euclidean pull” on the news vector.
- Copy Update: Change the label
"Active Target Vector"above the central card to"Active News Stub".
Phase C: Anti-Meta & Stacking Mechanics
This phase secures target card coordinates and fixes selection logic to allow proper item stack builds.1. News Stub Vector Leak Shield (Anti-Meta Air-Gap)
- File:
frontend/components/NewsCard.tsx&frontend/app/arena/[lobbyId]/page.tsx - Target: Add a conditional parameter to the
NewsCardcomponent to enforce hiding of the coordinate grid. - Fix:
- Introduce an optional prop:
hideVectorMap?: boolean. - In
NewsCard.tsx, ifhideVectorMapistrue, replace theCARD FOOTER(the X/Y grid and green blip radar) with a stylized dark aesthetic block or a generic watermark, fully preventing vector coordinates from rendering on the client. - In
frontend/app/arena/[lobbyId]/page.tsx, ensure<NewsCard {...tableState.targetVector} />is explicitly passedhideVectorMap={true}.
- Introduce an optional prop:
2. Phantom Item Cards & Combo Stacking Fix
- File:
frontend/components/PlayerHand.tsx&frontend/lib/cardUtils.ts - Target: Ensure modifier card clicks append to the
selectedCardIdsReact state and feed correctly into the projected coordinates math. - Diagnostics:
- Item cards in the user’s hand may fail to toggle selection if the card metadata does not strictly match the
'ITEM'string format or if case insensitivity is not handled. - Fix:
- Update
getCardTypeincardUtils.tsto execute a.toUpperCase()comparison oncard.cardTypeto handle lowercase anomalies gracefully. - Ensure that clicking an Item card (when a Core Meme card is already active) correctly appends its ID to
selectedCardIdsinsidePlayerHand.tsx:handleCardClick. - Enforce that the staged 3D stack correctly overlays the active
modifierCardsin a staggered stack behind the baseMemecard. - Enforce that the projected vector calculations (
calculateProjectedVectorincardUtils.ts) recalculate immediately, updating the Tactical HUD preview values upon selection changes.
- Update
- Item cards in the user’s hand may fail to toggle selection if the card metadata does not strictly match the
Phase D: The Resolution Animation
This phase fixes a state-sync race condition that prevents the 3D SVG isometric vector animation from showing.- File:
frontend/app/arena/[lobbyId]/page.tsx - Diagnosis:
- The
useEffectthat triggersisAnimatingMathtotruelistens only totableState?.status === 'RESOLVING'. - Because the backend processes resolution instantly, the synced Firestore state transitions from
'DEBATE_PHASE'directly to'RESOLVED'in a single tick. - The transient
'RESOLVING'status is completely skipped by the React state observer, leavingisAnimatingMathasfalse. The overlay is bypassed entirely, depriving players of the visual feedback.
- The
- Fix:
- Introduce a round-tracking state hook on the page:
const [lastAnimatedRound, setLastAnimatedRound] = useState<number>(-1);. - Refactor the triggering
useEffectto listen to BOTH'RESOLVING'and'RESOLVED'statuses: - This ensures that upon entering a resolved phase of a new round, the visual overlay is guaranteed to mount, execute the 4-second SVG Euclidean sweep animation, and gracefully transition to the resolution board only after
onAnimationCompletefires.
- Introduce a round-tracking state hook on the page:
🧪 Verification Plan
Automated Verification
Run integration tests inbackend and frontend to verify that states resolve correctly and that prisma queries remain intact:
Manual Visual Verification Flow
- Lobby Creation: Open
/arena, choose a faction, and select a deck. Verify the 2x2 grid ordering matches the Compass (AuthLeft top-left, etc.), thatLOCKEDis replaced withSELECTEDwith clean margins, and that the Pill Box is absent. - Tactical Selection: Select a base card and multiple item modifier cards. Verify that items visually stack behind the base card and that projected coordinates in the HUD update instantly.
- News Stub Coords Shield: Inspect the central News Stub card. Verify that its coordinate map at the bottom is completely invisible (grid hidden).
- Resolution Transition: Play cards, allow the timer to expire, and verify that the
MathResolutionOverlaysweeps, plots vectors, and completes its full 4-second SVG animation before revealing the post-match summary.