Skip to main content

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 RESOLVED as 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-2 to 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)

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-index values so the text badge sits cleanly below or inside a defined action frame without overlapping the faction’s primary SVG emblem or icon.

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 /bunker and 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 MAGNITUDE to Vector Impact (representing the raw power to push the coordinates).
    • Rename RESILIENCE to Coordinate Defense (representing the defense rating to resist coordinate shifts).
    • Update any localized help-text, tooltips, or descriptions to maintain semantic alignment.

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 NewsCard component to enforce hiding of the coordinate grid.
  • Fix:
    • Introduce an optional prop: hideVectorMap?: boolean.
    • In NewsCard.tsx, if hideVectorMap is true, replace the CARD 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 passed hideVectorMap={true}.

2. Phantom Item Cards & Combo Stacking Fix

  • File: frontend/components/PlayerHand.tsx & frontend/lib/cardUtils.ts
  • Target: Ensure modifier card clicks append to the selectedCardIds React 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 getCardType in cardUtils.ts to execute a .toUpperCase() comparison on card.cardType to handle lowercase anomalies gracefully.
      • Ensure that clicking an Item card (when a Core Meme card is already active) correctly appends its ID to selectedCardIds inside PlayerHand.tsx:handleCardClick.
      • Enforce that the staged 3D stack correctly overlays the active modifierCards in a staggered stack behind the base Meme card.
      • Enforce that the projected vector calculations (calculateProjectedVector in cardUtils.ts) recalculate immediately, updating the Tactical HUD preview values upon selection changes.

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 useEffect that triggers isAnimatingMath to true listens only to tableState?.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, leaving isAnimatingMath as false. The overlay is bypassed entirely, depriving players of the visual feedback.
  • Fix:
    • Introduce a round-tracking state hook on the page: const [lastAnimatedRound, setLastAnimatedRound] = useState<number>(-1);.
    • Refactor the triggering useEffect to 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 onAnimationComplete fires.

🧪 Verification Plan

Automated Verification

Run integration tests in backend and frontend to verify that states resolve correctly and that prisma queries remain intact:

Manual Visual Verification Flow

  1. Lobby Creation: Open /arena, choose a faction, and select a deck. Verify the 2x2 grid ordering matches the Compass (AuthLeft top-left, etc.), that LOCKED is replaced with SELECTED with clean margins, and that the Pill Box is absent.
  2. 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.
  3. News Stub Coords Shield: Inspect the central News Stub card. Verify that its coordinate map at the bottom is completely invisible (grid hidden).
  4. Resolution Transition: Play cards, allow the timer to expire, and verify that the MathResolutionOverlay sweeps, plots vectors, and completes its full 4-second SVG animation before revealing the post-match summary.