# **Hub UI Specification: The Forward Operating Base** This document defines the architecture, visuals, and integration logic for the **Hub Screen**. This is the persistent "Main Menu" of the campaign where the player manages resources, units, and mission selection. ## **1. Integration Architecture** The HubScreen is a **View** that consumes data from the **GameStateManager** singleton. ### **Data Sources** - **Wallet:** gameStateManager.persistence.loadProfile().currency (or similar cached state). - **Roster:** gameStateManager.rosterManager.getDeployableUnits(). - **Unlocks:** Derived from gameStateManager.missionManager.completedMissions. ### **Navigation Flow** 1. **Entry:** GameStateManager switches state to STATE_META_HUB. index.html mounts . 2. **Mission Selection:** - User clicks "Mission Board". - mounts overlay. - emits mission-selected. 3. **Squad Assembly:** - catches event. - Transitions to STATE_TEAM_BUILDER (passing the selected Mission ID). 4. **Deployment:** - TeamBuilder emits embark. - GameStateManager handles embark (starts GameLoop). ## **2. Visual Layout (The "Dusk Camp")** Style: 2.5D Parallax or Static Art background with UI overlays. Theme: A makeshift military camp at twilight. Torches, magical lanterns, supplies piled high. ### **A. The Stage (Background)** - **Image:** assets/images/ui/hub_bg_dusk.png covers 100% width/height. - **Hotspots:** Invisible, clickable divs positioned absolutely over key art elements. - _The Tent (Barracks):_ top: 40%, left: 10%, width: 20%. Hover: Glows Blue. - _The Table (Missions):_ top: 60%, left: 40%, width: 20%. Hover: Glows Gold. - _The Wagon (Market):_ top: 50%, left: 80%, width: 15%. Hover: Glows Green. ### **B. Top Bar (Status)** - **Left:** Game Logo. - **Right:** Resource Strip. - [💎 450 Shards] [⚙️ 12 Cores] [Day 4] ### **C. Bottom Dock (Navigation)** - A row of large, labeled buttons acting as redundant navigation. - [BARRACKS] [MISSIONS] [MARKET] [RESEARCH] [SYSTEM] - **State:** Buttons are disabled/greyed out if the facility is locked. ### **D. Overlay Container (Modal Layer)** - A centralized div with a semi-transparent backdrop (rgba(0,0,0,0.8)) where sub-screens (Barracks, MissionBoard) are rendered without leaving the Hub. ## **3. TypeScript Interfaces** // src/types/HubInterfaces.ts export interface HubState { wallet: { aetherShards: number; ancientCores: number; }; rosterSummary: { total: number; ready: number; injured: number; }; unlocks: { market: boolean; research: boolean; }; activeOverlay: 'NONE' | 'BARRACKS' | 'MISSIONS' | 'MARKET' | 'SYSTEM'; } export interface HubEvents { // Dispatched when the player wants to leave the Hub context entirely 'request-team-builder': { detail: { missionId: string } }; 'save-and-quit': void; } ## **4. Conditions of Acceptance (CoA)** **CoA 1: Live Data Binding** - On mount (connectedCallback), the component must fetch wallet and roster data from gameStateManager. - The Top Bar must display the correct currency values. **CoA 2: Hotspot & Dock Sync** - Clicking the "Mission Table" hotspot OR the "Missions" dock button must perform the same action: setting activeOverlay = 'MISSIONS'. **CoA 3: Overlay Management** - When activeOverlay is 'MISSIONS', the component must be rendered in the Overlay Container. - Clicking "Close" or "Back" inside an overlay must set activeOverlay = 'NONE'. **CoA 4: Mission Handoff** - Selecting a mission in the Mission Board must dispatch an event that causes the Hub to dispatch request-team-builder, effectively handing control back to the App Router. ## **5. Implementation Prompt** "Create src/ui/screens/HubScreen.js as a LitElement. 1. **Imports:** Import gameStateManager singleton and html, css, LitElement. 2. **State:** Define properties for wallet, unlocks, and activeOverlay. 3. **Lifecycle:** In connectedCallback, read gameStateManager.persistence to populate wallet/unlocks. 4. **Layout:** - Background img covering host. - Absolute divs for Hotspots. - Flexbox header for Resources. - Flexbox footer for Dock Buttons. - Centered div for Overlays. 5. **Logic:** > \* \_openOverlay(type): Sets state. - \_closeOverlay(): Sets state to NONE. - \_onMissionSelected(e): Dispatches request-team-builder to window/parent. 6. **Lazy Loading:** Use dynamic imports inside the render() method'