# 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. **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. (Recording — previously the second pillar — was removed in the WPF rollback on 2026-05-13. The engine plumbing is intact for a future re-introduction, but no UI surface, view-model command, REST route, or OSC route exposes it.) 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. Disk free on the working volume, 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. (Recording state was a historical fifth field; it's removed.) ### 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). - **WPF .NET 8** is the supported frontend host. (A WinUI 3 rebuild was attempted in May 2026; it proved fragile — XAML parser crashes on DataTemplate, theme-glyph rendering issues — and was abandoned. The rollback commit `1d1ce6a` is the canonical baseline.) - Engine layer (.NET 8) is preserved verbatim — view-model surface is the swap boundary. - Fonts are bundled via WPF's `pack://application:,,,/Assets/Fonts/#Inter` resource URI so the operator's machine doesn't have to have Inter or JetBrains Mono installed. - 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.