ADR-031: Persistent dashboard sections over one-shot modals for orientation¶
Status: Accepted Date: 2026-04-23 Context: During the Apr 22 Beacon team playtest, players who joined the campaign via invite link skipped past the arc description (the world setup) entirely — they landed on the dashboard and went straight into Ch.1 with no sense of what world they were in or who they were playing as. Cici's transcript-quoted confusion was rooted in this gap. We needed to surface campaign orientation reliably to players regardless of how they arrived.
Decision¶
Use persistent, collapsible page sections rather than one-shot modal dialogs for delivering campaign orientation. Specifically:
- "About this Campaign" card at the top of the campaign dashboard — collapsible, expanded by default on first arrival per (user × campaign), shows arc name, theme, chapter count, and full description. Always available for re-reading.
- "Recap" section above the chapter teaser, visible from Ch.2 onward — pulls from
narrative_historyto summarize the prior chapter's decision and outcome. - Chapter synopsis in the chapter card — brief 1-2 sentence "what's about to happen" teaser (separate ADR: see ADR-029).
These three sections compose into layered orientation: world (About) → recent past (Recap) → upcoming (Synopsis). Players re-read at any time; nothing depends on a single click being remembered.
Rationale¶
The first attempt at this problem was a "Welcome to [world name]" modal that fired once per (user × campaign) on first arrival. Shipped, then quickly removed. Reasoning for the reversal:
- Modals get dismissed and forgotten. A player who quickly clicks Begin to start playing has no way to recall the world description later. Returning to the campaign mid-arc with no memory of the setup is a real failure mode.
- Persistent context invites scanning. A collapsed card in the dashboard signals "world details are here if you need them" without forcing a read.
- Modals interrupt; sections compose. Adding a second modal (e.g., a recap) would have been even more annoying. Sections allow stacking multiple orientation layers without modal-fatigue.
- Different players need different orientation at different moments. The host who created the campaign doesn't need a welcome modal; they wrote it. A late-joining player may want to re-read after they've forgotten. Persistent collapsibility serves both without branching logic.
Alternatives Considered¶
- One-shot welcome modal (the abandoned approach). Solved the "first arrival blind" problem but lost the persistent reference. Rejected on Jonathan's feedback — modals get dismissed and forgotten.
- Mandatory pre-Ch.1 intro screen. Forces the host through a "begin world" gate. Rejected — adds friction and the host can't skip it for impatient players.
- Always-visible non-collapsible card. Simpler but takes permanent vertical space on a dashboard that already has Invite/Party + Chapter cards. The collapsible variant gives users control over information density.
- Use the existing curated arc browser lightbox as the only entry point. Rejected because once players join via invite link or code, they bypass the browser entirely. The dashboard is the actual landing page, so orientation belongs there.
Discussion¶
Two iterations on this happened in a single session. The first instinct ("welcome modal") matched the codebase's existing TabsIntroModal pattern and felt like the right precedent. The user's intuition flipped it within minutes by asking a simple question: "will that lightbox come up every time?" The answer ("no, dismissed-once via localStorage") revealed the design flaw — once dismissed, the world context disappears for that user forever. Persistent context was the obvious better answer in retrospect.
This is worth surfacing as a heuristic: for orientation/reference content, default to persistent and collapsible. Reserve modals for blocking decisions or one-time confirmations (e.g., the Stand/Change "your rationale won't be saved" confirm modal — that one should block). The two patterns serve different needs.
The Recap section was originally fired only for reactive arcs in code; this change extended it to all arc types since the underlying narrative_history data exists for both. Static arcs gained a feature for free.
Consequences¶
- Modal usage now signals different intent: modals = block-decision flow (Stand/Change confirm), persistent sections = reference content (About, Recap). Future contributors should follow this split.
- Dashboard vertical space gets denser. Mitigated by collapsibility — default-expanded on first arrival, collapsed thereafter.
- localStorage signal is per-user-per-campaign. A user dismissing the About card on one device sees it expanded again on another device. This is a feature, not a bug — it ensures world context surfaces on each new device.
- Pattern transfers to solo Worlds and reactive Worlds for free since they share the campaign dashboard component. No incremental work to support those modes.
- Watch for: if we ever add a fourth orientation layer (e.g., a per-act section or thematic context), evaluate whether stacking helps or whether we need a tab/drawer pattern.
Key files:
- src/app/(app)/campaigns/[id]/page.tsx — About card, Recap section, synopsis rendering
- (removed) welcome modal — was added then reverted in same session