> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/phases/phase_21/prd_phase_21.md).

# PRD Phase 21: Bottom Rail Focused Surface Expansion

**Status**: Complete **Sessions**: 7 (initial estimate) **Estimated Duration**: 4-6 days

**Progress**: 7/7 sessions (100%)

***

## Overview

Phase 21 fixes the cockpit bottom-rail interaction model for Quest Board, Orchestration, and War Room. The bottom rail may continue to host full implementations for large screens, but each panel must also open into a focused working surface that automatically reflects the same usable interface for smaller screens and single-panel focus.

Proper delivery means every shipped interaction proves the user's intended outcome end to end in the product, with real execution, visible results, recovery paths, and tests. For this phase, a surface is not complete because a modal or scaffold exists; it is complete only when the user can open the panel, use the actual underlying interface, preserve state, recover from close/nested overlay flows, and see the same working content without duplicate or drifting component trees.

The source-backed findings from the former planning note are folded into this PRD and the Phase 21 session stubs. The former note may be deleted without losing planning detail once this phase record is committed.

***

## Progress Tracker

| Session | Name                                     | Status   | Est. Tasks | Validated  |
| ------- | ---------------------------------------- | -------- | ---------- | ---------- |
| 01      | Expansion State Foundation               | Complete | \~12-18    | 2026-06-29 |
| 02      | Shared Expansion Host                    | Complete | \~18-25    | 2026-06-29 |
| 03      | Orchestration Command Center Expansion   | Complete | \~18-25    | 2026-06-29 |
| 04      | Shortcut And Overlay Layering            | Complete | \~14-22    | 2026-06-29 |
| 05      | Quest Board And War Room Parity          | Complete | \~16-24    | 2026-06-29 |
| 06      | Responsive Layout And Accessibility Pass | Complete | \~12-20    | 2026-06-29 |
| 07      | Final Regression And Documentation       | Complete | \~12-18    | 2026-06-29 |

***

## Completed Sessions

* Session 01: Expansion State Foundation - Completed 2026-06-29.
* Session 02: Shared Expansion Host - Completed 2026-06-29.
* Session 03: Orchestration Command Center Expansion - Completed 2026-06-29.
* Session 04: Shortcut And Overlay Layering - Completed 2026-06-29.
* Session 05: Quest Board And War Room Parity - Completed 2026-06-29.
* Session 06: Responsive Layout And Accessibility Pass - Completed 2026-06-29.
* Session 07: Final Regression And Documentation - Completed 2026-06-29.

***

## Upcoming Sessions

* None. Phase 21 is complete.

***

## Objectives

1. Establish one transient shell state and one shared expansion host for the three bottom-rail panels.
2. Make Orchestration's primary open path expose the actual Command Center workbench, including Campaigns, instead of a summary-only details popup.
3. Preserve one mounted implementation per panel so compact and expanded modes do not fork local state, hydration, drawer state, or action behavior.
4. Prove the focused surfaces with product-visible behavior, recovery flows, accessibility checks, and focused automated tests.

***

## Prerequisites

* Phase 20 completed as Orchestration Actionability Execution.
* The folded source findings in this phase PRD reviewed as the source plan for this phase.
* Existing `apps/web` cockpit shell, Quest Board, Orchestration, War Room, settings store, shortcut, and panel tests remain the baseline.
* No session may claim completion unless it proves the user-visible outcome in the product, not only scaffolding, props, or cosmetic modal chrome.

***

## Planning Assumptions And Resolutions

### Working Assumptions

* The supplied source plan is the authoritative source for Phase 21 scope because it contains the source-backed code findings, target contract, detailed implementation plan, and session split.
* Phase 21 is primarily an `apps/web` phase because the relevant implementation lives in `apps/web/src/App.tsx`, `apps/web/src/components`, the web stores, web shortcut libraries, and web tests.
* Bottom panels as full implementations are valid and should not be removed. The required change is an expanded focused presentation of the same working surface.
* Same-instance promotion is the preferred architecture. Rendering duplicate panel trees is a risk because Orchestration, Quest Board, and War Room all hold local UI state that can drift from global store state.
* Details popups may remain only as secondary inspectors. They are not the primary answer to where users operate Campaigns, queue work, Quest Board actions, or War Room controls.

### Conflict Resolutions

* The master PRD and `state.json` ended at Phase 20 complete with no Phase 21 row, while the supplied source plan and phasebuild command define a clear next product phase. The chosen interpretation is to create Phase 21 as the next sequential phase and update both master PRD and state tracking.
* Phase 20 remains complete for truthful local orchestration execution. Phase 21 does not reopen backend execution semantics; it fixes the cockpit access and presentation layer so those implemented surfaces are discoverable and usable.
* The source plan initially describes session breadth rather than spec-system task counts. The generated phase keeps the same seven implementation slices and sizes each session to the standard 12-25 task range for later `plansession` output.

***

## Technical Considerations

### Architecture

Phase 21 should centralize bottom-rail expansion in one shell-level UI contract:

* `apps/web/src/store/useSettingsStore.ts` owns transient expansion state.
* `apps/web/src/App.tsx` wires the three bottom-rail cells through one shared expansion host.
* The shared host owns open/close, backdrop, Escape, focus restore, ARIA, sizing, guarded panel-background clicks, and stable test ids.
* `QuestBoard`, `OrchestrationPanel`, and `WarRoomPanel` remain the single mounted working implementations.
* Orchestration's primary open action routes to the expanded Command Center, while `OrchestrationDetailPortal` stays secondary if retained.

### Technologies

* React and TypeScript in `apps/web`
* Zustand settings and game stores
* Existing cockpit shell and panel components
* Vitest and Testing Library for component behavior
* Playwright or browser verification for desktop and small viewport evidence

### Risks

* Duplicate trees can silently fork local state: preserve one mounted instance or prove any portal implementation does not remount children.
* A larger modal can still fail the user outcome: acceptance must verify the actual Command Center tabs, Quest actions, and War Room controls are usable.
* Panel-background clicks can steal interactions from nested controls: the host must guard buttons, links, inputs, tab roles, editable content, and explicit no-expand descendants.
* Escape handling can close the wrong layer: nested drawers and inspectors must close before the expanded bottom-rail surface.
* Responsive polish can regress the cockpit: desktop and small viewport checks must prove no clipping, overlap, or unreachable controls.

### Relevant Considerations

* \[P20] **Release evidence is the execution claim source**: Phase 21 must prove product-visible outcomes and tests before claiming a panel expansion is shipped.
* \[P20] **Do not add action verbs before evidence**: UI labels such as open, execute, dispatch, apply, or recover must match implemented behavior and evidence.
* \[P20] **Broad privacy gates are release-critical**: Focused surfaces must not expose raw commands, terminal output, file contents, diffs, tokens, provider payloads, or broad absolute paths in broad rows.
* \[P03] **Stable docs are the current contract**: Update stable docs if the Campaigns or Orchestration entry path changes from the current documented behavior.

***

## Folded Source Findings

This section replaces the planning dependency on the former bottom-rail ongoing-project note. It preserves the full source-backed investigation, target contract, code evidence, findings, recommended fix, code touch list, verification targets, and open product decision inside the Phase 21 spec-system record.

### Source Date And Scope

**Date:** 2026-06-29

**Scope:** `apps/web` cockpit bottom rail: Quest Board, Orchestration, War Room.

### Source Summary

The user's diagnosis is directionally correct: it is acceptable for bottom panels to contain full implementations, because large-screen users may want to work directly in the cockpit grid. The bug is that the expanded popup path does not automatically expose the same full usable interface for smaller screens or focused single-panel work.

Quest Board and War Room already have header-click detail popups, but the clickable target is only the header, not the whole panel shell. Orchestration also has a header-click popup, but that popup is a read-only state summary. The real Campaigns/Files/Queue workbenches are embedded directly in the constrained bottom rail panel.

There is also a real synchronization risk: several popup/drawer open states are local React state inside each panel, while command-center tab and record selection state lives in the global game store. The architecture needs a consistent, robust expansion model where compact and expanded surfaces are two presentations of the same implementation, not separate interfaces that drift.

### Target Contract

* The bottom-rail panel and the expanded focused view are two presentations of the same working surface. They are not separate feature implementations.
* Quest Board, Orchestration, and War Room remain fully usable in the compact rail for large screens. Expanded mode adds room and focus; it does not replace or shrink the compact implementation.
* The primary open action for each bottom panel opens the usable interface. A summary/details popup can remain only as a secondary inspector.
* Only one bottom-rail surface can be expanded at a time.
* Expansion state is transient UI state, not domain state and not persisted across reloads.
* Proper delivery means every shipped feature proves the user's intended outcome end to end in the product, with real execution, visible results, recovery paths, and tests, not just scaffolding that looks complete.

### Implementation Sequence

1. Add canonical transient expansion state.
   * Add a bottom-rail-only surface type such as `BottomRailSurfaceId = "quest-board" | "orchestration" | "war-room"`.
   * Add `expandedBottomRailSurfaceId: BottomRailSurfaceId | null` and `setExpandedBottomRailSurfaceId(...)` to `apps/web/src/store/useSettingsStore.ts`.
   * Keep this field out of the persisted settings snapshot. It belongs beside the existing transient overlay booleans: `replayPanelOpen`, `commandPaletteOpen`, `settingsDrawerOpen`, `heatmapOpen`, `standingsOpen`, `leaderboardOpen`, `toolUsageOpen`, and `complexityOverlayOpen`.
   * Update test reset helpers that currently recreate `DEFAULT_SETTINGS` so the new transient field does not leak between tests.
2. Introduce one shared bottom-rail expansion host.
   * Create a shared component, likely near `apps/web/src/components/`, that wraps the existing `ShellSurface` bottom-rail cells from `apps/web/src/App.tsx`.
   * The host owns the common contract: open trigger, panel click handling, backdrop, close button, Escape handling, focus restore, `role="dialog"` while expanded, `aria-modal="true"`, `aria-labelledby`, `aria-controls`, labels, sizing, and stable test ids such as `bottom-rail-expand-orchestration` and `bottom-rail-expanded-orchestration`.
   * Keep the existing `SurfaceStateNote` behavior inside the wrapper so loading/offline/unavailable notes do not diverge across compact and expanded presentations.
   * Add a visible explicit "open full surface" affordance to each rail cell. Also allow panel-background clicks to open the surface, but guard against clicks that begin inside interactive descendants: `button`, `a`, `input`, `textarea`, `select`, `[role="button"]`, `[role="tab"]`, `[contenteditable]`, and an escape hatch such as `[data-no-panel-expand]`.
3. Promote the same mounted panel instance instead of rendering duplicates.
   * The lowest-risk architecture is same-instance promotion: the wrapper keeps the panel mounted once, then changes the wrapper from normal rail layout to fixed full-viewport/focused layout when expanded. This preserves local React state and avoids a second hydration/mutation tree.
   * Do not implement Orchestration expansion by rendering another `<OrchestrationPanel />` in a dialog. That would duplicate `OrchestrationShell` effects, including command-center hydration, diagnostics fetches, lineage roster fetches, local filters, selected campaign/attention ids, terminal drawer state, and local result state.
   * If a portal implementation is chosen instead, first prove with tests that switching between compact and expanded targets does not unmount the panel. If it does unmount, either abandon that route or lift all affected local UI state into a canonical store before using it.
   * Allow panels to receive an optional presentation prop such as `surfaceMode: "compact" | "expanded"` only for layout density and labels. The prop must not fork behavior or create two code paths for actions.
4. Make Orchestration's primary action open the Command Center.
   * Change the primary Orchestration open label from `Open Orchestration details` to a working-surface label such as `Open Command Center` or `Open full Orchestration`.
   * The expanded Orchestration surface must contain the existing `OrchestrationTabs` and `CommandCenterPanes` implementation, including the `Campaigns`, `File/Git`, `Attention`, `Executors`, `Federation`, and `Metrics` tabs.
   * Repoint the keyboard route currently described as `o d` / `command_center_details_open` so the primary shortcut opens the expanded Command Center surface. If the old state summary remains, give it a secondary name such as `Open orchestration state summary` and avoid making it the main discoverable route.
   * Keep `OrchestrationDetailPortal` only as a secondary state inspector if it still has product value. It should not be the answer to "where do I use Campaigns?"
5. Apply the same expansion contract to Quest Board and War Room.
   * Quest Board expansion should preserve the existing mounted `QuestBoard` instance so local `replyDraft`, scan feedback, card actions, and action pending state remain aligned.
   * War Room expansion should preserve the mounted `WarRoomPanel` instance so Worker-room controls, local fallback state, approvals, notices, erasure previews, and diagnostics stay aligned with the compact surface.
   * Existing `QuestBoardDetailPortal` and `WarRoomDetailPortal` can stay as secondary inspectors, but the primary cell click/open action should expose the full working panel, not only the summary modal.
6. Harden overlay and Escape behavior.
   * The shared expansion host should own the Escape listener for expanded bottom surfaces.
   * Escape should close only the topmost relevant layer. If a nested drawer or modal is open, such as `TerminalRuntimeDrawer`, `OrchestrationDrawer`, or an existing details inspector, the nested layer should close before the expanded bottom surface closes.
   * Prefer a tiny shared overlay-layer convention over scattered one-off checks. For example, add stable `data-overlay-layer` markers and have the expansion host skip its Escape close when a higher layer is present.
   * Backdrop clicks should close the expanded surface; clicks inside the panel must not close it.
7. Update tests around the new contract.
   * Add App/shell tests, with `OrchestrationPanel` mocked where useful, proving that each bottom-rail surface opens through the shared host, only one is expanded, backdrop/Escape/close button dismiss it, and focus returns to the trigger.
   * Add a shared host test proving nested interactive controls do not trigger panel expansion.
   * Update Orchestration tests that currently assert `Open Orchestration details` so they assert the new primary full-surface behavior.
   * Add Orchestration regression coverage proving the expanded view exposes `data-testid="command-center-tab-campaigns"`, changing tabs updates `commandCenter.activeTab`, close/reopen preserves the intended tab and local selected campaign/attention state, and expansion does not cause duplicate command-center hydration fetches.
   * Add terminal/runtime coverage proving opening `TerminalRuntimeDrawer` inside expanded Orchestration does not desync or close the parent surface first.
   * Add Quest Board and War Room coverage proving full-surface expansion works while existing action buttons still perform their original actions without accidentally opening the expanded view.

### Code Evidence

* `apps/web/src/App.tsx:156` renders the bottom rail as three columns: Quest Board, Orchestration, War Room. The Orchestration column directly mounts `OrchestrationPanel` at `apps/web/src/App.tsx:161`.
* `apps/web/src/components/Layout.tsx:21` limits the large-screen bottom row to `minmax(340px,36vh)`, and `apps/web/src/components/Layout.tsx:22` fixes the 2xl bottom row to `340px`. That height then has to contain the entire Orchestration header, state banner, scope filters, current-state summary, and Command Center tabs.
* `apps/web/src/components/orchestration/OrchestrationShell.tsx:2162` puts the real command center content inside a `mobile-scroll-region h-0 min-h-0 flex-1` scroller. This confirms the actual Campaigns UI is not a separate full-size view; it is nested inside the bottom rail.
* `apps/web/src/components/orchestration/OrchestrationTabs.tsx:216` renders the Command Center tablist, and `apps/web/src/components/orchestration/OrchestrationTabs.tsx:252` renders the active tab panel. That is where the `Campaigns` button/tab lives.
* `apps/web/src/components/orchestration/OrchestrationHeader.tsx:60` defines the only Orchestration popup trigger as `Open Orchestration details`. It is not labelled or structured as "Open Command Center" or "Open full Orchestration".
* `apps/web/src/components/orchestration/OrchestrationShell.tsx:2282` opens `OrchestrationDetailPortal`, which receives queue/template/lineage/guarded state views. It does not receive or render the full `OrchestrationTabs` workbench interface, so the popup is not where Campaigns can be used.
* `apps/web/src/components/QuestBoard.tsx:37` and `apps/web/src/components/WarRoomPanel.tsx:155` keep detail popup open state in local component state. Their headers open detail portals at `apps/web/src/components/QuestBoard.tsx:149` and `apps/web/src/components/WarRoomPanel.tsx:687`.
* `apps/web/src/components/orchestration/OrchestrationShell.tsx:357` keeps `detailsOpen` local, `apps/web/src/components/orchestration/OrchestrationShell.tsx:358` keeps `terminalDrawerOpen` local, and `apps/web/src/components/orchestration/OrchestrationShell.tsx:359-360` keep selected Attention/Campaign ids local.
* By contrast, `apps/web/src/store/useGameStore.ts:385-386` stores `commandCenter.activeTab` and `commandCenter.selectedDetail` globally, with setters at `apps/web/src/store/useGameStore.ts:2366` and `apps/web/src/store/useGameStore.ts:2375`.
* Tests currently prove popup mechanics, not full-size launcher semantics: `apps/web/tests/OrchestrationPanel.test.tsx:2334` checks that the Orchestration detail popup renders state summary, while `apps/web/tests/WarRoomPanel.test.tsx:197` checks that War Room header content opens a detail popup without mutating War Room state.

### Source Findings

#### 1. The bottom rail is allowed to be a primary work surface

The bottom rail currently hosts the full Orchestration Command Center workbench. That is a valid design for large screens and should not be treated as wrong by itself.

Impact: the failure mode is not "too much implementation in the bottom panel." The failure mode is that users without enough panel space do not have an equivalent expanded working interface.

#### 2. The Orchestration popup must mirror the usable interface

The current `Open Orchestration details` popup is a detail/status view. It is not the Command Center. It does not render the Campaigns tab, Queue workbench, File/Git workbench, terminal runtime controls, or the other actual action surfaces.

Impact: the natural user action, clicking the Orchestration header to get more room, does not expose the thing the user is trying to operate.

Requirement: the expanded view must automatically reflect the same content and capabilities as the bottom panel. It should be an interface people can actually use on smaller screens or when they want to focus on one cockpit panel.

#### 3. Panel and popup state must not fork

Command Center tab and record drawer selection are global. Panel expansion, terminal drawer open state, selected Attention row, selected Campaign row, and Quest/War detail open state are local component booleans/ids.

Impact: the current implementation is safe only because it renders a single Orchestration shell instance. If a full-size popup is added by rendering another `OrchestrationPanel`, local UI state will fork between compact and popup instances. The active tab may sync, but selected row, terminal drawer visibility, and detail popup visibility may not.

Requirement: compact and expanded modes need one architectural source of truth. The implementation should not depend on manually keeping two parallel component trees in sync.

#### 4. Header-only click targets are too subtle

Quest Board, Orchestration, and War Room all use header buttons as popup triggers. That is technically accessible, but it does not match the intended interaction that "the panel opens the real interface." The body of these panels contains many controls, so the fix should not blindly attach `onClick` to every pixel; it should add an explicit panel-level open affordance that does not steal clicks from form fields and buttons.

Impact: users do not get a strong visual or interaction signal that the compact bottom cards are launchers into larger surfaces.

### Code Areas To Touch

* `apps/web/src/store/useSettingsStore.ts`: transient expanded bottom-rail state.
* `apps/web/src/App.tsx`: replace the three bottom `ShellSurface` usages with the shared expansion host.
* `apps/web/src/components/QuestBoard.tsx`: keep full implementation mounted; demote detail popup to secondary inspector if retained.
* `apps/web/src/components/WarRoomPanel.tsx`: keep full implementation mounted; demote detail popup to secondary inspector if retained.
* `apps/web/src/components/orchestration/OrchestrationShell.tsx`: rename the current details affordance, route primary open to expansion state, and keep summary/details as secondary if retained.
* `apps/web/src/components/orchestration/OrchestrationHeader.tsx`: update labels, ARIA controls, and shortcut copy.
* `apps/web/src/lib/commandCenterShortcuts.ts` and `apps/web/src/lib/useKeyboardShortcuts.ts`: make the primary Orchestration shortcut open the expanded Command Center, not the summary details popup.
* `apps/web/tests/CockpitShell.test.tsx`, `apps/web/tests/MobileAccessibility.test.tsx`, `apps/web/tests/OrchestrationPanel.test.tsx`, `apps/web/tests/QuestBoard.test.tsx`, `apps/web/tests/WarRoomPanel.test.tsx`, and shortcut tests: update existing assertions and add regression coverage for the new expansion contract.

### Verification Targets

* `npm test -- apps/web/tests/CockpitShell.test.tsx apps/web/tests/MobileAccessibility.test.tsx`
* `npm test -- apps/web/tests/OrchestrationPanel.test.tsx apps/web/tests/QuestBoard.test.tsx apps/web/tests/WarRoomPanel.test.tsx`
* `npm test -- apps/web/tests/keyboardShortcuts.test.ts apps/web/tests/commandCenterShortcuts.test.ts apps/web/tests/KeyboardShortcutsModal.test.tsx`
* `npm run typecheck --workspace @factionos/web`
* After implementation, run a browser pass at a small viewport and a desktop viewport to verify the fixed expanded surface is not clipped by the cockpit grid and that the bottom rail remains usable when no panel is expanded.

### Recommended Fix

Implement Phase 21 with these priorities:

1. Store `expandedBottomRailSurfaceId` as transient shell/UI state in `useSettingsStore`.
2. Add one shared bottom-rail expansion host and use it for Quest Board, Orchestration, and War Room.
3. Preserve one mounted instance of each panel while expanding it. Prefer fixed-position same-instance promotion over rendering a second panel tree. If any portal-based approach is used, first test whether it remounts the child; do not use it for Orchestration unless local state and hydration effects are protected from forking.
4. Make Orchestration's primary open action `Open Command Center` or equivalent and ensure the expanded surface renders the existing `OrchestrationTabs` and `CommandCenterPanes`.
5. Keep existing summary/details popups only as secondary inspectors.
6. Close the work only after tests prove expansion, state preservation, non-duplication of Orchestration hydration, shortcut routing, nested overlay Escape behavior, and guarded click handling for nested controls.

### Open Product Decision

The product decision is not whether bottom panels may contain full implementations. They may. The decision is how compact and expanded presentations share one implementation and one state model so the cockpit stays consistent, robust, and usable across large screens, small screens, and focused single-panel workflows.

***

## Success Criteria

Phase complete when:

* [ ] All 7 sessions completed.
* [ ] Quest Board, Orchestration, and War Room each open from the bottom rail into a focused working surface.
* [ ] Expanded Orchestration exposes and preserves the existing Command Center workbench, including the Campaigns tab.
* [ ] Compact and expanded modes share one mounted implementation per panel or have tests proving no state fork/remount occurs.
* [ ] Nested controls keep their original behavior and do not accidentally trigger panel expansion.
* [ ] Escape, backdrop, close button, focus restore, and nested overlay behavior are tested.
* [ ] Desktop and small viewport verification proves the surfaces are usable, scrollable where needed, and free of incoherent overlap.
* [ ] Stable docs describe the implemented interaction path.

***

## Dependencies

### Depends On

* Phase 20: Orchestration Actionability Execution

### Enables

* Future cockpit ergonomics, mobile usability, and orchestration onboarding work built on a consistent focused-surface contract.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/phases/phase_21/prd_phase_21.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
