# 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.
