Pub Quiz Platform — Client app

Combined app document — Client app

Status Draft
App Client app
Generated 2026-05-13
Source of truth .claude/context/apps/client.md

The team device app — runs on each team's phone or tablet during a quiz session. Discovers a Host on the local network, joins as a team, receives the slide content the Host pushes, and submits answers. Runs on iPhone, Android phones, iPad, and Android tablets.

Overview

The Client renders the Client canvas of each slide using a responsive layout (anchors, regions, stack) so it adapts across phone, tablet, portrait, and landscape orientations. Each Client device represents one team, with no per-individual identity in v1. On join, the Client receives an eager push of every Client-canvas slide + its resources for the whole quiz, so live-play continues even on flaky Wi-Fi.

For the cross-cutting requirements, scope, and platform list, see the project PRD.

User flows

Per-flow diagrams (lifecycle, discover, join + customisation, session) live on the dedicated flow page, each linked to its relevant UI mockups.

Architecture

A Unity project, sibling to Quiz.Host, Quiz.Remote, and Quiz.Preview. Two top-level scenes — MainMenu (discovery + join: list visible Hosts, enter team name, join) and Play (render the current slide's Client canvas, dispatch input elements, show score). References com.quiz.shared-assets, com.quiz.runtime, com.quiz.core via UPM. See Per-App Scaffolding — Client for the on-disk shape. Cross-cutting:

Design notes

The brand identity, palette, typography, and motion language are project-wide and live in the Design Specification. Client-specific design notes (canvas layout, responsive typography, touch-target sizing) are tagged *{client}* in that document.

Build plan

The Client's items are part of the single project Build Plan. Filter visually for client — Client-tagged work is concentrated in Load-bearing prototype, MVP object-type cohort (Client side), Client team-play features, Crash recovery (Client side).

User flows — detail

Surface-to-surface navigation for the Client. Each diagram is a Mermaid flowchart rendered inline. Authoring conventions and theme tokens live in .claude/skills/mermaid-diagrams/SKILL.md.

Surfaces referenced here are defined in Client surfaces. Functional requirements are in Functional Requirements — Client.

2. Discover

Mockups: Discover · Code entry

%%{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 DIS[Discover\nBonjour-pulse + host cards] DIS -->|Refresh| DIS DIS -->|⋯ menu| AM[App menu] AM --> AMS[Settings] --> AM AM --> AMA[About] --> AM DIS -->|Have a code? — Stretch| CE[Code-entry\nQ7-3K9-FX input] CE -->|Submit| RES{Resolve via relay} RES -->|hit| JO[Join] RES -->|miss| ERR[Code didn't match] --> CE CE -->|Back to scan| DIS DIS -->|live card tap| JO DIS -->|idle card tap| IDLE[Idle host — no quiz loaded notice] --> DIS 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 RES decision class JO terminal

3. Join and team customisation

Mockups: Team join · Photo capture · Buzzer picker

%%{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\nname + photo + buzzer + colour + avatar] JO -->|Take photo| PC[Camera capture] --> CR[Crop to square] --> JO JO -->|Choose premade avatar| AP[Premade avatar picker] --> JO JO -->|Pick buzzer jingle| BP[Buzzer picker · preview + select] --> JO JO -->|Pick colour — Beta| JO JO -->|Join ▸| EP[Eager-push progress] EP -->|complete| SE[Session] EP -->|fatal mismatch| FM[Fatal mismatch screen] --> DIS[Discover] JO -->|reconnect with prior identity| RJ[Rejoin-as-previous dialog] --> JO JO -->|name taken| NT[Team name taken] --> JO JO -->|host rejects| HR[Host rejected join] --> DIS classDef terminal fill:#E8F5EC,stroke:#36D17B,stroke-width:2px,color:#1F1933,rx:14,ry:14 class SE,DIS terminal

4. Session

Mockups: Session · Session ended

%%{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\nslide canvas + HUD] SE -->|tap MC option| ANS[Answer received pill] SE -->|change answer until lock| SE SE -->|host locks| LOCK[Locked banner] LOCK -->|host advances slide| SE SE -->|tap score chip| ST[Standings panel] ST -->|swipe to dismiss| SE SE -->|tap team chip| SM[Session menu] SM --> SCN[Change team name] --> SE SM --> SLV[Leave session] --> CONF[Confirm] --> DIS[Discover] SM --> SRP[Report an issue] SE -->|connection drop| RB[Reconnecting banner] RB --> SE RB -->|timeout| HG[Host gone notification] --> DIS SE -->|host ends session| END[Session ended\nfinal standings] --> DIS classDef terminal fill:#E8F5EC,stroke:#36D17B,stroke-width:2px,color:#1F1933,rx:14,ry:14 class END,DIS terminal

See also: Client surfaces · Functional Requirements — Client.