# Design

## Theme

A Truchet tile board: a full-frame grid of quarter-circle arc tiles forming winding paths, like a puzzle quietly rearranging itself. Graphic and print-like rather than photographic. Every second or so a single tile flips with a snappy 90-degree rotation and a brief rose flash, reshaping the paths; occasionally a short cascade of flips ripples across the board. Between events the frame is still.

## Color

Strategy: restrained field, committed accent. Cool throughout; no amber.

- Base field: dark slate-indigo, near-flat vertical gradient (#12151f to #181d2b), dithered with baked static noise to prevent banding on stream.
- Arc strokes at rest: muted slate blue (#39435e) with per-tile alpha variation (0.55-0.95) for texture.
- Accent: rose (#ff608d family; status line tint #ff7ba6), a Rose City nod. Appears only in flip flashes and the status line. It carries the energy; use it nowhere else. The base field stays cold so the rose reads as a pop, not as warmth.
- Text: cool off-white (#eef1f8); supporting lines in slate greys. No #fff, no warm tints.

## Typography

Embedded as woff2 data URIs so OBS Browser Sources work offline and render identically on any host OS. No external fetches.

- Display: Bricolage Grotesque 700 (latin subset) for the event name. Characterful grotesk; indie-venue energy without costume.
- Supporting: Sometype Mono 400 (latin subset) for status, date/time, handle, and chat. Status line uppercase with wide letter-spacing, tinted accent.
- Emoji: Noto Color Emoji, all ten unicode-range subsets embedded (~2.7MB, decoded lazily per range). Pinned deliberately: the streaming host is Linux, where CEF has no dependable system emoji font, and pinning also makes emoji look the same regardless of host.
- Fallback stacks: "Arial Black"/Arial for display; "Cascadia Mono", Consolas for mono.
- Scale contrast between title and supporting lines >= 4x.

## Layout

- 1920x1080 fixed. 120px tiles, 16x9 grid, exact fit.
- Text block lower-left (96px margin), upper-right stays calm for webcam/OBS overlays.
- Tiles near the text block are dimmed by distance (not hidden) and excluded from flip scheduling so the action reads elsewhere; a soft scrim adds legibility without a photographic vignette.

## Motion

- Discrete events, not drift: a tile flip is a 500ms ease-out-quint rotation; the flash decays over ~1.8s; then stillness. Starting Soon flips roughly every 1.2s with a playful multi-tile ripple every 7-12s; Thank You slows to ~2.6s flips and rare ripples; the text-free background mode sits between.
- Most frames are identical between events, which is exactly what the stream encoder wants.
- 30fps cap via frame-delta gating; first frame painted synchronously at load (OBS may throttle rAF until the source is visible).
- prefers-reduced-motion: render the static board, no flips.

## OBS integration

One page (index.html) serves the whole stream via the `window.obsstudio` API; it stays resident rather than reloading per scene.

- `obsSceneChanged` maps the scene name to a mode (keyword match) and swaps the copy block with the staggered text entrance. The text-zone tile dimming and scrim ease in/out with the text (textWeight 0..1).
- `obsStreamingStarted` is the big moment: a wavefront of rose flips radiates from board center while the text replays its entrance.
- On page load the text appears instantly with no animation: the editor already shows the scene, so entrances are reserved for events viewers can see.
- Outside OBS everything degrades to URL params plus keyboard test controls (1/2/0 modes, r ripple, l go-live, c demo chat).

## Live chat

A typographic chat column at bottom-right, shown only in the text modes. Fed by stream.place chat records (place.stream.chat.message) over Jetstream, filtered by the channel's streamer DID.

- No avatars, no cards: handle colored by the chatter's own place.stream.chat.profile color (falling back to accent rose), message text in slate, both Sometype Mono. Chatter colors are lifted to a relative-luminance floor of ~150 so every name reads on the slate field; this is the one sanctioned exception to the single-accent rule, since the colors are the community's own.
- Messages slide in with the house rise easing; the column masks to transparent at its top so old messages dissolve rather than scroll.
- Max 8 messages, 4 lines each (clamped). Firehose deletions remove messages (moderation-friendly).
- The board treats the chat column like the copy block: tiles behind it dim and stop flipping while it's visible, with its own scrim, all easing with a chatWeight 0..1.
