Pub Quiz Platform
Design Specification — Project (cross-cutting)
| Status | Draft |
| Scope | Project (cross-cutting) |
| Generated | 2026-05-13 |
| Source of truth | .claude/context/knowledgebase/design-spec.md |
This document captures the look and feel shared by all four apps — Quiz.Designer, Quiz.Host, Quiz.Client, and Quiz.Remote (see Applications). It is the canonical reference for cross-cutting requirement F-X-3 (shared design language). The brand-true treatment lands in the Beta phase; MVP and Alpha are visually utilitarian.
For the per-app inventory of menus, dialogs, panels, shortcuts, and where each surface leads, see UI Surfaces. The design tokens here are the palette every mockup pulls from.
The final product / brand name is deferred to the Beta phase — see open questions. Throughout this spec the apps are referred to by their engineering project names (Quiz.Designer, Quiz.Host, Quiz.Client, Quiz.Remote).
Brand identity
- Wordmark on banner: bold, slightly condensed uppercase display face, white fill with a heavy black drop shadow. Final wording is locked at Beta alongside the brand name.
- Tagline on banner: clean uppercase sans, lighter weight, white on dark, with neon underline accents. Final wording is locked at Beta alongside the brand name.
- Logomark: a stylized Q with a checkmark tucked inside it, rendered in hot magenta with a black drop shadow. The checkmark reads as a tick (correct-answer affirmation) and shapes the lower-right of the Q's counter; the mark is iconographic, not an initialism.
- Mascot: a friendly cartoon smartphone — pink/magenta body, big cartoon eyes, white-gloved waving hand, white shoes. Tone: playful, approachable, slightly retro game-show. Rigged once, reused across all four apps; each app picks the appropriate pose for its context (waving on Designer welcome, cheering on Host big reveals, sleepy on end-of-quiz). See Beta for when the rig actually lands.
Mood
A pub quiz on a Saturday night, but televised. High contrast, vibrant gradients, neon-tube edges. The cartoon mascot keeps it from tipping into pure neon arcade — there is warmth and humour underneath the energy. Closer to a game-show set than a productivity app.
Color palette
Hex values sampled from the brand banner (branding.jpg) and locked. The swatches printed beside each hex value are rendered in the PDF.
Core hues
| Token | Hex | Usage |
|---|---|---|
color.magenta |
#FF009F |
Primary brand accent; logomark; key calls-to-action; "big reveal" highlights. |
color.electric-blue |
#16B2EB |
Secondary brand accent; live-state indicators; secondary CTAs. |
color.deep-purple |
#961EEF |
Transitional gradient stop; high-energy backgrounds; big-reveal stages. |
color.white |
#FFFFFF |
Wordmark fill; primary text on dark backgrounds. |
color.near-black |
#0F0B1A |
Text shadows; primary text on light backgrounds; neutral surfaces. The slight purple tint reads brand-consistent on dark surfaces. |
Gradients
Brand gradient — linear, left → right, color.magenta → color.deep-purple → color.electric-blue. The signature backdrop. Reserve for hero surfaces — Host session-running screens, Designer launch/hero, Client onboarding.
Subtle backdrop — the brand gradient with a low-poly facet texture overlay at low opacity. Adds depth on content-heavy surfaces without competing with content.
Neon / glow
Neon glow borders and accents are part of the language. Implement as outer glows (high blur, brand-coloured, additive blending) on framed surfaces, on headings during big reveals, and on active leaderboard rows. Use sparingly — neon everywhere reads as cluttered.
Theming
The platform supports two layers of theming, both Beta scope:
- Studio operator-chrome theme designer host remote — calmer, professional, low-chroma chrome shared by Quiz.Designer, the Quiz.Host operator window, and Quiz.Remote. Each app ships a light and a dark variant; Designer defaults to light (long author sessions), Host operator and Remote default to dark (low-light venue rooms). The vibrant Showtime palette renders only inside each operator app's embedded canvas / audience-mirror region — never in chrome. Full Studio chrome tokens, brand-hue ration rules, and per-app component spec live in Design Specification — Studio. Only Quiz.Client and the Host's audience window ship the full Showtime palette during play.
- Per-quiz theme on Host / Client / Remote hostclientremote — the quiz manifest declares a theme that the Host, Client, and Remote render against during play. v1 supports an enum (e.g.
dark,light, brand presets) at minimum; richer per-quiz custom palettes are possible Stretch — see Stretch. The default is the dark brand theme.
The Designer chrome theme and per-quiz theme are independent — an author might author in light theme but ship a dark-themed quiz.
Typography
Locked picks (final, not provisional):
| Role | Family | Notes |
|---|---|---|
| Display / headings | Bebas Neue | Tall condensed sans matching the wordmark's character. Used uppercase, tight tracking, drop shadow on dark. |
| Numerals (scores, timers, countdowns) | Bebas Neue | The display face. Numbers carry a lot of meaning in a quiz — they earn impact. |
| Body / UI | Inter | Industry-standard geometric sans. Excellent at small sizes; pairs cleanly with Bebas Neue. |
| Mono (rare) | JetBrains Mono | Score readouts, codes, debug overlays. |
The candidate samples that informed this pick are preserved below for reference; the locked faces above are what the apps render.
Display face — Bebas Neue (locked)
| Family | Headline sample | Score sample |
|---|---|---|
| Bebas Neue (locked) | QUIZ NIGHT TONIGHT | 42 |
Body face — Inter (locked)
| Family | Body sample (12pt) |
|---|---|
| Inter (locked) | A quick brown fox jumps over the lazy dog. Pub quizzes are a popular social format. |
Mono face — JetBrains Mono (locked)
| Family | Mono sample |
|---|---|
| JetBrains Mono (locked) | core.multiple-choice-input v1.0.0 |
Typographic rules
- Headings: uppercase, bold, tight letter-spacing, heavy drop shadow on dark backgrounds (echo the wordmark).
- Body: sentence case, regular weight, generous line-height for phone readability.
- No more than two type families visible on one screen.
- Numbers (scores, timers, countdowns) use the display face for impact.
Visual motifs
- Neon glow borders. Rectangular frames with bright outer glow in the brand colors. For hero panels, leaderboards, and big-reveal stages.
- Low-poly facet textures. Subtle triangular overlays on gradients. Depth without distraction.
- Gradient backdrops. The signature pink → purple → blue sweep. Reserve full saturation for hero surfaces; tone down for content-heavy pages.
- Cartoon mascot. Featured on launch, empty states, loading, and end-of-quiz screens. Vary the pose to match context — waving on welcome, cheering on big reveals, sleepy on end-of-quiz.
Iconography and imagery
- Icons are bold and chunky, geometric, with weight matching the display typography. Avoid hairline styles that fight the brand weight.
- External imagery (round media — photos, screenshots, etc.) is presented inside framed cards with neon-glow borders so it sits within the brand language rather than against it.
Motion
- Confident and snappy. Spring-driven transitions, slight overshoot. Avoid lazy ease-in/ease-out.
- Big reveals. Combined scale + glow pulse + brief audio sting (see sound design). Reserve for genuine reveals — overuse dilutes them.
- Idle states. The mascot in subtle motion (idle bob, blink) instead of abstract spinners wherever possible.
- Performance budget. 60 fps on iPhone 12 / equivalent and above (see Non-Functional Requirements). Question transitions complete within 500 ms of trigger on the Host.
- Implementation. Host, Client, and Remote motion is implemented in Unity UGUI — Animator, Timeline, and DOTween for code-driven tweens, sequences, and easings. The Designer's chrome uses Blazor / Razor CSS animations and transitions (post-MAUI-Blazor commit); the embedded
Quiz.PreviewUnity WebGL canvas shares the UGUI + DOTween motion stack with Host/Client (same shared-assets package, same scenes). The mascot animation rig is rigged once and reused across all four Unity projects.
Sound design
A full audio language lands in Beta. Scope:
- Stings — short branded audio cues for specific events: correct answer, incorrect answer, time-up, lock, big reveal, end of round, end of quiz.
- Transitions — slide-advance whoosh, leaderboard reveal swell, round-change motif.
- Big-reveal audio language — the audio counterpart to the visual big-reveal motif (scale + glow pulse). A short branded sting that punctuates winning moments and final reveals.
- Ambient music bed (light) — optional low-level music between rounds; muted during questions. Author-controllable per quiz.
- Per-team buzzer jingles (Alpha — earlier than the rest of the audio language). Teams pick a jingle from the quiz's bundled set at join (F-CL-15); the Host plays it when that team wins a buzzer first-press (F-HO-27). The jingles themselves are author-supplied (avoids music-licensing exposure on the platform) with a small built-in Designer library of pre-licensed defaults (F-DE-29). Mixing should sit at the same loudness band as the branded stings so a buzzer-win doesn't unpleasantly spike against a correct-answer cue.
Licensing and music sourcing decisions for the Beta audio language belong to Beta-phase work, not this spec. The audio language is mixed for the venue: stings should cut through pub ambient noise without being intrusive.
Team identity client host
Each team has a visual identity bundled at join: name, colour (Beta), avatar (premade or captured photo, Alpha), and buzzer jingle (Alpha). The identity carries through every Host moment the team is featured in: leaderboard rows, big-reveal callouts, correct-answer pings, buzzer-win playback. Per-team photos render at a fixed circular crop at leaderboard-row scale and at a larger square crop on the join-screen team roster. Author-supplied premade avatars use the same crop frame so the leaderboard reads consistently whether a team chose their own photo or the bundled set.
Layout and spacing
The shared spacing scale and per-app layout primitives. Subsections marked *{app}* apply to that app specifically and appear in the per-app design-spec PDFs.
Spacing scale
8 px base — 4, 8, 16, 24, 32, 48, 64, 96. Use only these values across every app surface.
Host canvas host
Fixed virtual 1920×1080 (16:9) that scales to fit the connected display. Author places elements at absolute coordinates. Large type, generous spacing, readable from across a room. Information density low; visual impact high.
Client canvas client
Responsive layout — anchored regions and stacks rather than absolute coordinates — adapting across phone, tablet, portrait, and landscape. Primary actions in the thumb-reachable lower half. Tap targets ≥ 44×44 pt.
Designer chrome designer
Tablet/desktop layout outside the canvases. Master-detail panels, denser information density, designed for sustained authoring sessions. Renders against the Designer's chosen theme (light or dark — see Theming). The embedded preview surface inside the Designer renders Host and Client canvases identically to live play.
Remote panel remote
Phone-first layout. Top region: scaled-down mirror of the Host display (preserve aspect 16:9). Middle region: per-slide host-notes with comfortable line-height. Bottom region: control surface in the thumb-reachable area — advance / go-back, reveal triggers, lock toggle, timer override, scoring override. Action buttons at least 56×56 pt; primary action (advance) larger and visually distinct.
The dual-canvas split is load-bearing: a slide's Host face is a "TV show" composition; its Client face is a snug, one-handed phone composition. Author them as two distinct surfaces that share the slide's identity, not as one design squeezed into two viewports.
Voice and tone
- Friendly and confident — like a host who knows the room and is having fun.
- Concise — quiz nights have rhythm; copy that drags kills the energy.
- Playful, not silly — wit and mild theatre, never trying too hard.
- Inclusive — no in-jokes participants might not get, no jargon.
Studio operator chrome
This page is the operator-facing design specification — the "Studio" theme. It sits alongside the cross-cutting Design Specification and extends it for every surface an operator sees: the Quiz.Designer authoring shell, the Quiz.Host operator window, and the Quiz.Remote controller. Where this page and design-spec.md differ, this page wins for operator chrome surfaces (toolbars, panels, dialogs, properties inspector, control surfaces). Where it is silent, fall back to design-spec.md.
The three apps that use Studio face operators — authors at a desk, the host running the room, the quizmaster walking the room. Only the Quiz.Client — the team's phone — faces the audience and ships the full Showtime palette during play (pink reveals, sunshine halos, magenta-to-electric gradients). The Host's audience window — the projector / TV surface that the audience watches — also renders Showtime, because it shows the same quiz content the Client sees. Studio applies to the Host's operator window only.
The load-bearing principle: chrome calm, canvas loud. Operator surfaces stay calm. Anything that is "the quiz playing" — the Host audience window, the Client phone, the Designer's preview canvas, the Remote's mirror of the audience — renders full Showtime inside the canvas region.
Which surface gets which theme
| App | Surface | Theme |
|---|---|---|
| Quiz.Designer | Entire app (chrome + dialogs). Preview canvas renders Showtime inside. | Studio. |
| Quiz.Host | Audience window — the projector / TV. The slide canvas the room watches. | Showtime — see design-spec.md. |
| Quiz.Host | Operator window — the second display on the operator's laptop / iPad. Controls, HUD, host-notes. The audience preview region inside renders Showtime. | Studio. |
| Quiz.Client | Entire app. The team's phone, audience-facing throughout play. | Showtime — see design-spec.md. |
| Quiz.Remote | Entire app. The quizmaster's pocket controller. The audience-mirror region inside renders Showtime. | Studio. |
Relationship to the cross-cutting spec
| Surface | Authority |
|---|---|
Brand palette (color.magenta, color.electric-blue, color.deep-purple, color.white, color.near-black) |
design-spec.md — locked, unchanged here. |
| Brand gradient (magenta → deep-purple → electric-blue) | design-spec.md — renders inside the Designer / Host-operator / Remote audience-mirror regions, never in chrome. |
| Typography (Bebas Neue / Inter / JetBrains Mono) | design-spec.md — same families, Studio weights mono more for chrome metadata. |
| Motion (spring, snappy, big-reveal grammar) | design-spec.md — chrome motion is subset: quiet panel transitions, no reveal pulses in chrome itself. |
| Theming (light is operator default for Designer; dark recommended for Host operator + Remote at night) | This page + design-spec.md. |
| Chrome surface tokens (base, panel, paper, raised, hover, text levels) | This page. |
| Studio component rules (toolbar, side panels, list rows, properties inspector, statusbar, control bar) | This page. |
| Ration rules for brand hues inside Studio chrome | This page. |
Principle — chrome calm, canvas loud
The three Studio apps are long-session operator tools. Two consequences:
- Chrome surfaces sit at low chroma. Editor neutrals, hairline borders, mono labels. Bright brand hues fatigue at long exposure; the chrome must not.
- The canvas region inside each operator app renders Showtime. Designer's preview canvas, Host-operator's audience mirror, Remote's audience mirror — all render the actual quiz at full Showtime saturation. The operator sees exactly what the audience sees.
The rest of this page is what makes that work: which surface tokens carry the chrome, where each brand hue earns a place, and what each Studio-specific component looks like across the three apps.
Chrome surface tokens
Dark theme — slate-plum, low chroma
A brand-tinted neutral. The base is in the plum family so it harmonises with the audience-mirror gradient stop without competing.
| Token | Hex | Usage |
|---|---|---|
chrome.base |
#14111C |
Application window background; canvas / audience-mirror backdrop (the framing around the embedded vibrant region, not the region itself). |
chrome.panel |
#1C1828 |
Top toolbar; dialog body; popovers; primary inset surface. |
chrome.paper |
#211C2E |
Left and right side panels; titlebar; statusbar. |
chrome.raised |
#262134 |
Selected row; input fill; segment-control background. |
chrome.hover |
#312A42 |
Hover state for rows and buttons. |
chrome.border |
rgba(255,255,255,0.08) |
Hairline divider. 1 px, never thicker. |
chrome.border-strong |
rgba(255,255,255,0.14) |
Active border on focused or selected raised elements. |
chrome.text |
#F0EBF7 |
Primary copy, slide names, headings. |
chrome.text-muted |
#A89FC0 |
Secondary copy, helper text, panel headings. |
chrome.text-subtle |
#6E6585 |
Labels, metadata, monospace runs, statusbar text. |
Light theme — warm off-white (recommended Designer default)
Design-spec.md notes that Designer ships a light theme alongside dark because authors spend long sessions in the Designer. Light is the recommended default for Designer for that reason. Host operator and Remote default to dark — both run in low-light rooms during sessions — but ship light too for daytime / training use.
| Token | Hex | Usage |
|---|---|---|
chrome.base |
#F8F5F0 |
Application window; canvas / mirror backdrop. Warm off-white — never bone-white. |
chrome.panel |
#FFFFFF |
Top toolbar; card; input fill; dialog body. |
chrome.paper |
#F0EBE3 |
Side panels; statusbar; secondary surface. |
chrome.raised |
#E8E3DA |
Selected row; segment-control background; hover-into-selected. |
chrome.hover |
#DDD5C8 |
Strong hover; pressed state. |
chrome.border |
#DDD5C8 |
Hairline divider. Warm tan. |
chrome.border-strong |
#C5BBAA |
Active border on focused or selected raised elements. |
chrome.text |
#1F1933 |
Primary copy. Brand-tinted near-black — the locked color.near-black shifted slightly toward deep-purple so type harmonises with the brand. |
chrome.text-muted |
#5A536B |
Secondary copy, helper text. |
chrome.text-subtle |
#908AA0 |
Labels, metadata, monospace runs. |
Brand-hue ration in Studio chrome
The locked brand hues from design-spec.md remain available, but their roles in Studio chrome are restricted:
| Hue | Where it appears in chrome | Where it does not appear in chrome |
|---|---|---|
color.magenta |
Logomark tile in the toolbar (24×24 rounded square, magenta fill, white "Q"); primary CTA (Designer Push to Host / New Quiz / Save when unsaved; Host Start Session / Resume; Remote Advance); active-row left-edge indicator (2 px inset shadow); focus ring on text inputs only when the focused element is the primary action. | Panel fills, surface gradients, large area accents, hover backgrounds, or any decorative use. |
color.electric-blue |
Generic focus ring (input, button); inline links; secondary CTA (Designer Reconnect, Host Discover Hosts, Remote Re-pair); info badges. | Panel fills or hero gradients. |
color.deep-purple |
Inside the embedded canvas / audience-mirror region only (gradient stop in the canvas content's hero background). | Anywhere in chrome. The chrome's plum tint is a desaturated neutral, not the brand deep-purple. |
The Showtime warm-support hues (coral, sunshine, rose, peach) do not appear in Studio chrome. They render only inside the canvas / audience-mirror regions as part of live quiz content.
Status hues in Studio chrome
Cross-cutting semantic hues are used directly:
| Token | Hex | Role |
|---|---|---|
mint |
#36D17B |
Save / connection / pair success badge; auto-save status dot; "Saved ✓" or "Paired ✓" button; live indicator when a Host has clients connected. |
amber |
#FFA94D |
Unsaved-changes dot in titlebar (Designer); transfer-pending dot (Host); reconnecting dot (Remote); timer-low colour swatch in properties; caution states (close-without-save, abandon session). |
crimson |
#E63946 |
Destructive action (Delete Quiz, End Session, Unpair); validation error border on inputs; Push-to-Host / Pair failure banner. |
Typography in chrome
- Body / chrome copy — Inter, 13 px regular for primary chrome text, 12 px for tool buttons and panel headers, 11 px for panel titles.
- Display / chrome headings — Bebas Neue, used sparingly. Restricted to: dialog headlines (≥ 24 px), welcome / splash / discover surfaces, and section dividers in long dialogs. Body chrome stays in Inter.
- Mono / metadata — JetBrains Mono carries more weight here than in the play apps. Used for: slide indices (Designer), session codes (Host, Remote pair screens), file paths (Designer), version numbers (
v0.4), save timestamps, type labels (MULTIPLE CHOICE,BUZZER), panel-title labels (SLIDES · 20,PROPERTIES · SLIDE 04,TEAMS · 6 JOINED), keyboard shortcuts in menus, statusbar items. Mono is the structural signal: this is metadata, not content.
Statusbar formatting is uppercase mono throughout (AUTOSAVE 14:32, BUILD 2026.05.13, PAIRED · 2 MIN). Side-panel titles are uppercase mono with letter-spacing 3 px. Tool-button labels are sentence-case Inter.
Studio components — per-app notes
Designer-specific
- Toolbar (top) — 52 px,
chrome.panelbackground, logomark left, document name, tool-button groups, primary CTA right. - Left panel — slide list — 240 px,
chrome.paper, mono panel title, slide rows with index + thumbnail + meta. Active row:chrome.raisedbackground + 2 px magenta inset shadow left. - Canvas area (centre) —
chrome.basebackdrop with 24 px grid. Embedded 16:9 canvas renders full Showtime. Floating canvas toolbar bottom-centred. - Right panel — properties inspector — 280 px,
chrome.paper, mono panel title, property groups separated by 1 px borders. Inputschrome.raised. Segmented controls. Focus ringcolor.electric-blue. - Statusbar (bottom) — 28 px,
chrome.paper, mono items, mint / amber status dots.
Host operator window — additions
- Title bar — same vocabulary as Designer (logomark, doc name = session name, traffic lights). Mono session code (e.g.
7K2-9P) visible. - Audience-mirror region — sized to match the connected projector / TV aspect ratio (typically 16:9), framed by
chrome.basebackdrop, renders the current slide at full Showtime saturation. This is the operator's view of "what the audience is seeing right now". - Host-notes pane —
chrome.paperpanel, generous line-height for comfortable read at session-running distance. Body text in Inter; emphasis inchrome.text-mutedfor code refs. - Control bar (bottom) — replaces Designer's statusbar.
chrome.panelbackground. Primary actions (Advance, Reveal Answer, Lock, Timer, End Session). Mono session HUD on right (slide index, timer remaining, score totals). - Connected-clients list —
chrome.paperpanel showing each team's name + colour dot + connection status. Mint dot = connected; amber dot = recently dropped; crimson dot = disconnected. No team-colour bleed onto chrome.
Remote — phone-first chrome
- Phone-first layout. Top region: scaled-down audience-mirror (preserve 16:9), Showtime rendered inside. Middle: host-notes, Inter, comfortable line-height. Bottom: control surface in the thumb-reachable area.
- Top bar — 44 px,
chrome.panel, paired-Host name centre, pairing status dot right. Logomark optional (often hidden — operator already knows the app). - Audience-mirror region — 16:9 aspect, full Showtime inside, framed by
chrome.basebackdrop. - Host-notes pane —
chrome.paper, generous Inter line-height for read-while-walking. - Control surface —
chrome.panelbackground. Primary action (Advance) larger and visually distinct — magenta fill, 56×56 pt minimum. Secondary actions (back, reveal, lock, timer override, score override)chrome.raised44×44 pt minimum. Heavy mono labels above each control group (NAV,REVEAL,LOCK,TIMER). - Splash / discover — welcome surface for the controller. Brand gradient hero allowed here (welcome moment) per cross-cutting spec.
Light vs dark default per app
| App | Default | Why |
|---|---|---|
| Quiz.Designer | Light | Long authoring sessions — light is easier on the eyes for hours. Per design-spec.md. |
| Quiz.Host operator | Dark | Sessions usually run in low-light pub / venue rooms. Operator at the back of the room reads better off dark. |
| Quiz.Remote | Dark | Quizmaster walks a low-light venue. Dark reduces glare in the room. |
All three apps ship the other theme too, selectable in app settings. Per-quiz theme on the Host audience window and Client is independent of Studio chrome theme — an author might author in light Studio chrome but ship a dark-theme quiz.
See also
- Design Specification — cross-cutting brand identity, palette, typography, motion, voice; per-app design notes for the audience-facing surfaces.
- Applications — Designer — Designer's responsibilities, platform targets, and architectural model.
- Applications — Host — Host's responsibilities, dual-window mode, audience vs operator split.
- Applications — Remote — Remote's responsibilities and control-command set.
- Designer Shell — the .NET MAUI Blazor Hybrid scaffolding the Designer chrome runs on.
- UI Surfaces — Designer — enumerated list of Designer dialogs, panels, menus, and shortcuts.
- UI Surfaces — Host — enumerated list of Host surfaces.
- UI Surfaces — Remote — enumerated list of Remote surfaces.