Combined app document — Host app
|
|
| Status |
Draft |
| App |
Host app |
| Generated |
2026-05-13 |
| Source of truth |
.claude/context/apps/host.md |
The TV-show app — runs the live quiz session on a TV or projector. Receives .quiz packages from the Designer over local Wi-Fi, advertises itself for Clients to discover, advances slides during the session, and is paired with a Remote for quizmaster control. Runs on iPad, Windows, macOS, and Android tablets.
Overview
The Host renders the Host canvas of each slide at the connected display's native resolution (typical target: 1920×1080 TV or projector). It is the authoritative source of session state — timer, scores, slide pointer, locked/unlocked input — and pushes per-Client slide content eagerly to each Client as it joins.
The Host also accepts a paired Remote (one per session) over a control-message WebSocket. The Remote drives navigation, sees the slide mirror + host-notes + live state, and (in Alpha) issues rich commands like jump-to-slide and trigger-element-reveal.
For the cross-cutting requirements, scope, and platform list, see the project PRD.
User flows
Per-flow diagrams (lifecycle, idle/load, join, session controls, fallback overlay, Remote pairing) live on the dedicated flow page, each linked to its relevant UI mockups.
- Full flow diagrams — App lifecycle · Idle + load · Join + start · Session controls · Single-display fallback overlay · Remote pairing. Each flow links to the mockups it touches.
- Surface inventory matrix — Every screen / panel / control / dialog with
leads-to targets, phase tags, FR references.
- Mockup launcher → — Browse every static mockup in one browser tab.
Architecture
A Unity project, sibling to Quiz.Client, Quiz.Remote, and Quiz.Preview. Two top-level scenes — MainMenu (pre-quiz lobby: load .quiz, accept Designer transfers, list connected teams, start session) and Play (slide-driven runner). References com.quiz.shared-assets, com.quiz.runtime, com.quiz.core via UPM. See Per-App Scaffolding — Host for the on-disk shape. Cross-cutting:
- Architecture overview for the platform-level diagram.
- Networking for the WebSocket transport, mDNS advertisement, eager-push model, and authoritative-timer mechanics.
- Quiz Package Format for the
.quiz archive shape the Host loads.
- Backend Schema (stretch) for the cloud-backed library path the Host would consume in a future release.
Design notes
The brand identity, palette, typography, and motion language are project-wide and live in the Design Specification. Host-specific design notes (canvas, in-room visual hierarchy, animations) are tagged *{host}* in that document.
Build plan
The Host's items are part of the single project Build Plan. Filter visually for host — Host-tagged work is concentrated in Load-bearing prototype, Designer→Host transfer (Host side), Host live-session features, Crash recovery, First-pass animation.
User flows — detail
Surface-to-surface navigation flows for the Host. Each diagram is a Mermaid flowchart rendered inline. Authoring conventions and theme tokens live in .claude/skills/mermaid-diagrams/SKILL.md.
Surfaces in Host surfaces. Functional requirements in Functional Requirements — Host.
2. Idle + load
Mockups: Idle · Incoming transfer · Package incompatible · Settings
%%{init: {"theme":"base","themeVariables":{"fontFamily":"Inter, system-ui, sans-serif","fontSize":"14px","primaryColor":"#FFFFFF","primaryBorderColor":"#FF009F","primaryTextColor":"#1F1933","secondaryColor":"#F0EBE3","secondaryBorderColor":"#16B2EB","secondaryTextColor":"#1F1933","tertiaryColor":"#F8F5F0","tertiaryBorderColor":"#5A536B","tertiaryTextColor":"#1F1933","lineColor":"#5A536B","edgeLabelBackground":"#F8F5F0","mainBkg":"#F8F5F0","clusterBkg":"#F0EBE3","clusterBorder":"#DDD5C8","titleColor":"#1F1933","nodeBorder":"#5A536B"},"flowchart":{"useMaxWidth":false,"htmlLabels":false,"curve":"basis","padding":20,"nodeSpacing":70,"rankSpacing":80}}}%%
flowchart TB
ID[Idle screen]
ID -->|tap quiz card| LD[Loaded]
ID -->|Load file…| OS[OS file picker] --> RCV[Receive + validate] --> ID
ID -->|Settings| ST[Settings dialog]
ID -->|tap quiz row long-press| QCM[Quiz context menu]
QCM --> QSTART[Start session] --> JO[Join screen]
QCM --> QPREV[Preview slides] --> LD
QCM --> QDEL[Delete from device] --> ID
ID -->|incoming push| IT[Incoming-transfer prompt]
IT -->|accept| ITR[Receiving... CRC32 + resume] --> ITD[Done banner] --> ID
IT -->|reject| ID
RCV -->|object-type mismatch| PI[Package-incompatible dialog] --> ID
classDef terminal fill:#E8F5EC,stroke:#36D17B,stroke-width:2px,color:#1F1933,rx:14,ry:14
class LD,JO terminal
3. Join + start
Mockups: Join screen · Remote pair prompt
%%{init: {"theme":"base","themeVariables":{"fontFamily":"Inter, system-ui, sans-serif","fontSize":"14px","primaryColor":"#FFFFFF","primaryBorderColor":"#FF009F","primaryTextColor":"#1F1933","secondaryColor":"#F0EBE3","secondaryBorderColor":"#16B2EB","secondaryTextColor":"#1F1933","tertiaryColor":"#F8F5F0","tertiaryBorderColor":"#5A536B","tertiaryTextColor":"#1F1933","lineColor":"#5A536B","edgeLabelBackground":"#F8F5F0","mainBkg":"#F8F5F0","clusterBkg":"#F0EBE3","clusterBorder":"#DDD5C8","titleColor":"#1F1933","nodeBorder":"#5A536B"},"flowchart":{"useMaxWidth":false,"htmlLabels":false,"curve":"basis","padding":20,"nodeSpacing":70,"rankSpacing":80}}}%%
flowchart TB
JO[Join screen\nQR + URL + code + roster]
JO -->|team connects| TR[Team roster row added]
TR -->|long-press| TCM[Team context menu]
TCM --> RN[Rename team] --> TR
TCM --> KK[Kick] --> JO
TCM --> AC[Assign colour — Beta] --> TR
JO -->|Start quiz ▸| SE[Session]
JO -->|Back to library| BCONF{Teams joined?}
BCONF -->|yes| BC[Confirm leave] --> ID[Idle]
BCONF -->|no| ID
JO -->|Pair Remote| RP[Remote pair prompt\ncode + QR] --> RPA[Remote accepts / rejects] --> JO
classDef decision fill:#FFF1DC,stroke:#FFA94D,stroke-width:2px,color:#1F1933
classDef terminal fill:#E8F5EC,stroke:#36D17B,stroke-width:2px,color:#1F1933,rx:14,ry:14
class BCONF decision
class SE,ID terminal
4. Session — controls (operator window)
Mockups: Operator window · Audience window · End-session confirm · Final standings
%%{init: {"theme":"base","themeVariables":{"fontFamily":"Inter, system-ui, sans-serif","fontSize":"14px","primaryColor":"#FFFFFF","primaryBorderColor":"#FF009F","primaryTextColor":"#1F1933","secondaryColor":"#F0EBE3","secondaryBorderColor":"#16B2EB","secondaryTextColor":"#1F1933","tertiaryColor":"#F8F5F0","tertiaryBorderColor":"#5A536B","tertiaryTextColor":"#1F1933","lineColor":"#5A536B","edgeLabelBackground":"#F8F5F0","mainBkg":"#F8F5F0","clusterBkg":"#F0EBE3","clusterBorder":"#DDD5C8","titleColor":"#1F1933","nodeBorder":"#5A536B"},"flowchart":{"useMaxWidth":false,"htmlLabels":false,"curve":"basis","padding":20,"nodeSpacing":70,"rankSpacing":80}}}%%
flowchart TB
SE[Session\naudience window + operator window]
SE -->|Next slide ▸| SE
SE -->|◂ Previous| SE
SE -->|+10s| SE
SE -->|Skip timer| SE
SE -->|Lock now| SE
SE -->|Unlock| SE
SE -->|Show leaderboard| SE
SE -->|Trigger reveal — Alpha| SE
SE -->|Jump to slide… — Alpha| JTS[Jump dialog] --> SE
SE -->|Score overrides — Alpha| SO[Overrides panel] --> SE
SE -->|Pause session| PA[Paused overlay] --> SE
SE -->|End session…| ES{Confirm?}
ES -->|yes| EN[Session end · final standings]
ES -->|no| SE
SE -->|Mute jingles| SE
SE -->|client disconnect| RB[Reconnecting banner] --> SE
SE -->|Remote disconnect| RD[Remote-disconnected notification] --> SE
classDef decision fill:#FFF1DC,stroke:#FFA94D,stroke-width:2px,color:#1F1933
classDef terminal fill:#E8F5EC,stroke:#36D17B,stroke-width:2px,color:#1F1933,rx:14,ry:14
class ES decision
class EN terminal
5. Single-display fallback overlay
Mockups: Audience window (overlay state)
%%{init: {"theme":"base","themeVariables":{"fontFamily":"Inter, system-ui, sans-serif","fontSize":"14px","primaryColor":"#FFFFFF","primaryBorderColor":"#FF009F","primaryTextColor":"#1F1933","secondaryColor":"#F0EBE3","secondaryBorderColor":"#16B2EB","secondaryTextColor":"#1F1933","tertiaryColor":"#F8F5F0","tertiaryBorderColor":"#5A536B","tertiaryTextColor":"#1F1933","lineColor":"#5A536B","edgeLabelBackground":"#F8F5F0","mainBkg":"#F8F5F0","clusterBkg":"#F0EBE3","clusterBorder":"#DDD5C8","titleColor":"#1F1933","nodeBorder":"#5A536B"},"flowchart":{"useMaxWidth":false,"htmlLabels":false,"curve":"basis","padding":20,"nodeSpacing":70,"rankSpacing":80}}}%%
flowchart TB
AW[Audience window only\nno second display] -->|tap / move mouse| OV[Overlay summoned\ncontrol row visible]
OV -->|auto-hide 4s| AW
OV -->|operator action| AW
6. Remote pairing
Mockups: Remote pair prompt
%%{init: {"theme":"base","themeVariables":{"fontFamily":"Inter, system-ui, sans-serif","fontSize":"14px","primaryColor":"#FFFFFF","primaryBorderColor":"#FF009F","primaryTextColor":"#1F1933","secondaryColor":"#F0EBE3","secondaryBorderColor":"#16B2EB","secondaryTextColor":"#1F1933","tertiaryColor":"#F8F5F0","tertiaryBorderColor":"#5A536B","tertiaryTextColor":"#1F1933","lineColor":"#5A536B","edgeLabelBackground":"#F8F5F0","mainBkg":"#F8F5F0","clusterBkg":"#F0EBE3","clusterBorder":"#DDD5C8","titleColor":"#1F1933","nodeBorder":"#5A536B"},"flowchart":{"useMaxWidth":false,"htmlLabels":false,"curve":"basis","padding":20,"nodeSpacing":70,"rankSpacing":80}}}%%
flowchart TB
RPP[Remote pair prompt\nopened from join / settings / operator menu]
RPP -->|show code + QR| WAIT[Wait for Remote]
WAIT -->|Remote scans QR or types code| RA[Accept prompt — Remote 'X' wants to pair]
RA -->|Accept| PAIRED[Paired indicator on operator HUD]
RA -->|Reject| WAIT
RPP -->|Regenerate code| RPP
PAIRED -->|Remote disconnects| WAIT
classDef terminal fill:#E8F5EC,stroke:#36D17B,stroke-width:2px,color:#1F1933,rx:14,ry:14
class PAIRED terminal
See also: Host surfaces · Networking · Functional Requirements — Host.