dragon-iso/PRODUCT.md
Zac Gaetano 94b0a71edc docs: PRODUCT.md + DESIGN.md (ground-up GUI redesign brief)
Captures the impeccable context for the GUI redesign greenlit on 2026-05-12:

PRODUCT.md - register=product, primary persona=solo broadcast operator at
1:50am with a live show twenty minutes out. Strategic principles foreground
progressive disclosure over progressive density. Anti-references explicitly
name the "vibe-coded GUI" failure mode (cards-in-a-grid, hero-metric template,
Zoom pastel, generic SaaS dashboard) so the redesign can be measured against
what it must not become.

DESIGN.md - tokens for the WinUI 3 replatform target. Dark + light palettes
as ThemeDictionary entries, context-aware accent split (accent.cyan.surface
for fill, accent.cyan.text for the darker AA-passing variant on light bg).
Theming via {ThemeResource}; toggle in title bar + settings drawer; System/
Dark/Light tri-state persisted in UIPreferences.Theme.
2026-05-12 23:45:04 -04:00

174 lines
7.6 KiB
Markdown

# PRODUCT.md — TeamsISO
## Register
**Product.** This is a tool, not a destination. The design serves the operator
running a live broadcast. The UI is judged by how invisible it gets once the
show is rolling.
## Product purpose
TeamsISO is a per-participant NDI ISO controller for Microsoft Teams. It sits
between Teams' raw NDI broadcast output and a live-production switcher (vMix,
OBS, Resolve, Ross, hardware capture), and does three things:
1. **Routes** each guest as a clean, individually-addressable, normalized NDI
source (consistent framerate, resolution, aspect, audio routing — regardless
of what each participant's webcam is doing).
2. **Records** every active ISO to disk simultaneously — raw BGRA + manifest
+ ffmpeg convert script — so post-production gets a per-guest archive
ready to cut from.
3. **Orchestrates Teams itself** — launch/hide Teams windows, drive in-call
controls (mute, camera, share, leave, raise hand, quick-join) via
UIAutomation, so the operator never has to alt-tab away from the routing
table while the show is live.
External control surface (REST + WebSocket + OSC on localhost) lets a
Companion / Stream Deck / TouchOSC controller drive routing remotely.
## Users — the primary persona
**Solo operator.** One person, one Windows laptop or desk machine, often
running the show alone from a hotel room, conference green room, or home
studio. Picture them at 1:50am, twenty minutes before a live international
broadcast, ambient room lights down, the Teams call already started, four
guests joining staggered over the next ten minutes. They need to:
- See which participants are present, online, and producing NDI signal.
- Toggle each one's ISO on as they join.
- Confirm at a glance that recording is live, the disk has room, and the
control surface is reachable.
- Drop a marker if the host says something quotable.
- Mute themselves without alt-tabbing.
If the UI demands more than a glance for any of those, the show suffers.
### Secondary personas (informed, not designed-for)
- **TD at a broadcast desk** — multi-monitor, may use the OSC bridge to a
hardware control surface. Can tolerate a denser layout because their eyes
aren't the only thing on the surface.
- **Producer monitoring** — glances occasionally, mostly hands-off. Will see
this app over someone's shoulder; first read matters.
- **IT/AV admin** — installs it once, tunes config, walks away. Needs settings
to be findable, not present-at-all-times.
The design optimizes for the solo operator. Everyone else is downstream.
## Brand
**Wild Dragon LLC.** Reference: wilddragon.net.
Palette anchors:
- Canvas: near-black (`#0A0A0A`)
- Primary accent: cyan (`#97EDF0`)
- Secondary blue: (`#9AE0FD`)
- Coral (error / destructive): (`#FB819C`)
- Earth (warning): (`#423825`)
Typography:
- Sans: **Inter** (variable, bundled as a resource — not assumed installed).
- Mono: **JetBrains Mono** (also bundled).
The brand carries the surface but doesn't shout. Wild Dragon's authority is
in the restraint, not the saturation.
## Voice and tone
**Operator-first, terse, broadcaster-native.** The UI talks like a confident
peer, not a Slack bot.
- "Stop all" not "Are you sure you want to stop all ISOs?"
- "Disk low — 8.3 GB" not "Heads up! Your disk space is running low."
- "Joined call · 4 guests" not "You have successfully joined a Teams meeting!"
- Numbers carry their unit, no sentence wraps them.
- Never apologetic. Never bubbly. Never "Let's get started!"
When something goes wrong, name it: "NDI receiver dropped — restarting" beats
"Something went wrong, please try again."
## Strategic principles
These are the design's load-bearing commitments. Any choice that contradicts
one of these is wrong, even if it would otherwise be pretty.
### 1. One operator, one screen, one show.
The design is for someone running a live broadcast alone. Their attention
budget for chrome is roughly zero. Anything that's not the participants table
should fade until it's needed.
### 2. The participants table IS the product.
Everything else is support staff. Routing toggles, ISO state, and per-guest
signal health get the real estate, the contrast, and the typographic hierarchy.
### 3. Progressive disclosure, not progressive density.
The current GUI's failure mode is "every feature gets its own visible button."
The redesign's failure mode would be the opposite — burying important things
in menus. The discipline: surface the half-dozen actions an operator needs
mid-show; hide setup, presets, control-surface config, and exotic options
behind purposeful entry points.
### 4. At-a-glance status is sacred.
Recording state, disk health, control-surface reachability, session timer,
NDI signal-per-participant — these are the operator's situational awareness.
They must be readable in peripheral vision, in one place, without scanning.
### 5. Confident neutrality over decorative warmth.
This is a broadcast tool. It looks like one. No empty-state mascots, no
illustrated onboarding cards, no celebratory toasts. Restraint is the brand.
## Anti-references — what this is NOT
The "vibe-coded GUI" failure mode is the enemy. The redesign should never
read as AI-generated. Concretely, this means none of:
- **Generic SaaS dashboard.** No "hero metric + supporting stats + gradient
accent" cards. No "icon + heading + body text" card grids.
- **Cards-in-a-grid template.** Same-sized cards repeated endlessly is the
defining LLM-design tell. If a layout would benefit from cards-in-a-grid,
it benefits more from a table.
- **Card-with-icon-and-text rows.** The in-call control bar's current
"icon + label" buttons (Mute / Camera / Share / Marker / Notes / Leave)
read AI-generated. The redesign uses iconography differently.
- **Zoom pastel.** Soft purples, friendly mint greens, rounded everything,
Inter-at-low-weight.
- **Skeuomorphic broadcast hardware.** No woodgrain, no chrome bezels, no
fake LCD readouts, no metallic gradients. Wild Dragon's confidence is in
flat surfaces with real typography.
- **Tour-everything onboarding.** No "Let's get started!" wizards with cute
copy. The OnboardingWindow exists for first-launch config, not pageantry.
- **Modal-as-first-thought.** Settings, presets, help all currently live in
modals; some should be drawers or inline-progressive. Modal is a last resort.
## Technical constraints (informing design)
- Windows-only (Teams' NDI is Windows-only anyway).
- **WinUI 3 / Windows App SDK** is the new frontend target.
- Engine layer (.NET 8) is preserved verbatim — view-model surface is the
swap boundary.
- Bundled fonts via WinUI 3's `FontFamily` packaging (the WPF
`pack://...#Inter` resource URI doesn't translate; needs migration).
- MSIX-signed installer is on the v1.0 path; the new shell needs to package
cleanly through that pipeline.
- The external control surface (REST/WebSocket on `:9755`, OSC on `:9000`)
must not regress — its HTML control panel at `/ui` is a separate design
surface but shares brand tokens.
## What "done" looks like
The redesign is finished when:
1. A first-time operator can launch TeamsISO, join a Teams meeting, and
route their first ISO without reading documentation.
2. A returning operator at 1:50am can find the four things they need
(participant signal · ISO toggle · recording state · disk free) in under
half a second of glance.
3. Nothing on the surface reads as AI-generated. Show this to a working
broadcast engineer and they say "someone who knows the job built this."
4. The design system is documented in DESIGN.md tightly enough that a future
contributor can add a new view that looks like it belongs.