docs(design): DESIGN.md becomes the visual standard (tokens merged, controls rejected)

Merges the 2026-10-29 Stitch export into the existing 2026-10-26 token sheet and promotes the
file from "redesign exploration" to the normative standard:

- type scale (32→10px), spacing, radii and elevation levels — the three scales the old
  DESIGN.md listed as missing
- meter thresholds: cyan ≤ -12 dB, amber -12..-3, red > -3
- interaction rules: focus ring, hover step, 150ms/90ms easing, no springs

Four export tokens rejected as Material-3 warm-seed artifacts (recorded with reasons):
tertiary #4cd7f6 (kept #38bdf8), outline #ab8986, outline-variant #5b403e,
on-surface-variant #e4beba (kept slate #94a3b8).

Product rulings recorded: #e94560 retired as the app's general accent (blue takes every
interactive role, red is live/record only, wordmark artwork untouched); error gets its own
surface (#93000a) so it cannot be mistaken for on-air red.

The export's dock, four bays, page-nav sidebar, CPU/GPU/NVENC readouts and acrylic blur are
explicitly marked exploratory, not spec — the design principle is a simpler surface, not
hardware cosplay. On-stream output styling stays outside this theme.

Falsified facts fixed in the same commit: product.md brand section now points at DESIGN.md for UI
tokens (MARCOM.md stays the marketing palette), and ui-surface.md no longer calls DESIGN.md an
unreconciled exploration.

Docs-only unit: scope-check run, no build.
This commit is contained in:
2026-10-30 07:41:43 -07:00
parent 5a102a4a37
commit 565b8dbd6f
3 changed files with 143 additions and 29 deletions
+135 -25
View File
@@ -1,10 +1,16 @@
# DESIGN.md — LlamaCasty visual design tokens (redesign exploration)
# DESIGN.md — LlamaCasty visual design standard
> Source: Google Stitch export, 2026-10-26, from the proposed edit-screen mockup. Colors and type
> only — no layout decisions are captured here. This is a design reference for the UX redesign
> in progress; it is not yet wired into the app's theme (`Themes/Controls.xaml`).
> **Status: the standard** (decided 2026-10-30). Token values here are normative;
> `Themes/Tokens.xaml` is the implementation, and no other file may hardcode a hex once the sweep
> lands. Two Google Stitch exports feed it (2026-10-26 edit screen, 2026-10-29 audio dock).
>
> **The exports' layouts and control drawings are exploratory, not spec.** The dock, the four
> bays, the page-nav sidebar and the skeuomorphic faders are *not* adopted — the product's design
> principle is a surface so obvious that a right-brained person can use it without a manual, and
> hardware cosplay is the opposite of that. Only the colour, type, spacing, radius and elevation
> system is adopted.
## Color
## Colour
### Surfaces (dark navy scale, darkest to lightest)
@@ -18,7 +24,7 @@
| `surface-container-highest` | `#2d3449` | Selected/active row background |
| `surface-bright` | `#31394d` | Lightest surface, rare use (strong hover) |
| `outline` | `#334155` | Borders, dividers |
| `outline-variant` | `#1e293b` | Subtle dividers, inactive VU meter segments |
| `outline-variant` | `#1e293b` | Subtle dividers, inactive meter segments |
### Text
@@ -26,42 +32,146 @@
|---|---|---|
| `on-surface` | `#dae2fd` | Primary text |
| `on-surface-variant` | `#94a3b8` | Secondary / label text |
| `on-surface-disabled` | `#5b6478` | Disabled text and icons |
### Accent — one role each, never mixed
| Token | Hex | Role |
|---|---|---|
| `tertiary` (electric blue) | `#38bdf8` | The one interactive accent: selection, focus, sliders, primary buttons, transform handles |
| `primary` (red) | `#ff5451` | **Reserved for on-air/recording state only** — LIVE badge, program border, End/Go Live |
| `tertiary` (electric blue) | `#38bdf8` | **The** interactive accent: selection, focus, sliders, primary buttons, transform handles |
| `on-tertiary` | `#0b1326` | Text/icon on a blue fill |
| `primary` (red) | `#ff5451` | **On-air / recording only** — LIVE badge, program border, End/Go Live |
| `primary-container` | `#b91a24` | Red pressed/hover state |
| `secondary` (amber) | `#ffb95f` | Game audio channel, Super Chat highlight |
| `secondary-container` | `#ee9800` | Amber pressed/hover state |
| `error` | `#ef4444` | Error states only (distinct from the on-air red) |
| `attention` (orange) | `#ff8c3a` | Dropped frames, the live-screen indicator, blinking warnings |
| `error` | `#ef4444` | Error text and icons |
| `error-container` | `#93000a` | Error surface (health banner, toast) — keeps error visually distinct from on-air red |
| `on-error` | `#ffdad6` | Text on an error surface |
**Rule carried from the critique sessions:** red must mean "live or recording" and nothing else.
Don't reuse it for a Send button, a delete action, or any other control — that was the defect in
the first Stitch draft of the live screen.
**The rule:** red means "live or recording" and nothing else. Never a Send button, a delete action,
a brand flourish, or a general accent — that was the defect in the first Stitch draft.
**`#e94560` is retired** as the app's general accent (it was in 15 files). Blue takes over every
interactive role; red keeps only live/record. The brand/wordmark *artwork* is unchanged — those
assets are the creator's art, not a theme value.
### Meter thresholds (both meters, all bays)
| Band | Range | Brush |
|---|---|---|
| Nominal | −∞ … −12 dB | `#38bdf8` |
| Caution | −12 … −3 dB | `#ffb95f` |
| Peak / clip | −3 … 0 dB+ | `#ff5451` |
Meters are **measured, never decorative** (see `docs/ai/output.md`): the ladder shows the live
level scaled by the current gain, not the gain setting.
## Typography
| Token | Family | Use |
|---|---|---|
| `sans` | Inter (400/500/600/700) | All UI text — labels, buttons, panel titles |
| `mono` | JetBrains Mono (500/600) | All numeric/telemetry values — bitrate, FPS, dB, coordinates, timers. Keeps digits from shifting width as values change. |
| `mono` | JetBrains Mono (500/600) | Numeric/telemetry values — bitrate, FPS, dB, coordinates, timers. Tabular figures stop digits shifting width as values change |
Icons: Material Symbols Outlined.
Icons: Material Symbols Outlined (bundled, not fetched).
## Color roles (decided 2026-10-26)
### Scale
- **Red `#ff5451`:** YouTube references, on-air/GO LIVE, and record only.
- **Attention orange `#ff8c3a`:** dropped packets, the live screen indicator, and blinking warning lights.
- **Amber `#ffb95f`:** game audio and Super Chat only.
- **`error` `#ef4444`:** unchanged for now; it sits close to the on-air red and may need revisiting.
| Token | Size / line | Weight | Tracking | Use |
|---|---|---|---|---|
| `headline-lg` | 32 / 40 | 700 | −0.02em | Landing/empty-state titles only |
| `headline-md` | 24 / 32 | 600 | −0.015em | Dialog titles |
| `headline-sm` | 18 / 24 | 600 | −0.01em | Panel and section headers |
| `body-lg` | 15 / 22 | 400 | — | Default body, chat |
| `body-md` | 13 / 18 | 400 | — | Panel rows, form text |
| `body-sm` | 12 / 16 | 400 | — | Secondary text, hints |
| `label-lg` | 13 / 16 | 600 | 0.02em | `mono` — primary telemetry values |
| `label-md` | 11 / 14 | 500 | 0.04em | `mono` — labels, hotkey chips |
| `label-sm` | 10 / 12 | 500 | 0.05em | `mono` — dense telemetry only |
## Open questions for the next pass
**Floors and implementation notes**
- These tokens have not been reconciled against the app's current WPF theme
(`Themes/Controls.xaml`). That comparison should happen once the redesign direction is locked,
not before — do not retrofit the current theme to these values yet.
- No elevation/shadow scale, corner-radius scale, or spacing scale has been captured yet. Add them
here as they're decided, rather than letting them live only in Stitch exports.
- **11px is the default label size; 10px is the absolute floor** and only for dense readouts that
sit beside a larger value. Nothing readable at 100% zoom may be smaller than 10px.
- **WPF has no letter-spacing.** Tracking values above are design intent, not a property; implement
as-is (no tracking) rather than faking it with padded strings.
- Mono numerics use `Typography.NumeralAlignment="Tabular"` so widths stay stable.
## Spacing
| Token | px | Use |
|---|---|---|
| `space-xs` | 4 | Inside a chip, icon-to-text |
| `space-sm` | 8 | Between related controls |
| `space-md` | 12 | Default gap inside a panel |
| `space-lg` | 16 | Panel padding, section separation |
| `space-xl` | 24 | Dialog padding, major separation |
| `gutter` | 12 | Between page columns |
| `margin` | 16 | Window edge to content |
| `margin-docked` | 8 | Edge to content when a rail/drawer is docked |
## Shape
| Token | px | Use |
|---|---|---|
| `radius-sm` | 4 | Chips, badges, keycap tags |
| `radius-md` | 8 | Buttons, inputs, cards, scene tiles |
| `radius-lg` | 16 | Preview viewport, drawers, dialogs |
| `radius-full` | pill | Status chips (LIVE, EDIT), toggles |
Recessed controls (fader wells, inputs) use the same outer radius as their housing so the seams
line up — do not mix a 4px well inside an 8px card.
## Elevation
| Level | Use | Implementation |
|---|---|---|
| −1 recessed | Fader wells, input fields, table headers | inset top shadow + `surface-container-lowest` |
| 0 panel | The default chassis | `surface-container*` + **1px `outline` border**, no shadow |
| 1 raised | Scene tiles, floating chips, action buttons | subtle drop shadow, 0 1px 2px |
| 2 floating | Drawers, popups, dialogs | larger spread + 1px top highlight |
**Budget rule:** `DropShadowEffect` is software-rendered in WPF. Shadows on small controls only —
**never** on the preview viewport, the scene strip, or either wing. Depth on large surfaces comes
from the surface scale and the 1px border, not from effects.
## Interaction
- Focus ring: 1px `#38bdf8` outside a 1px gap — visible against every surface level.
- Hover: step one surface level up; active: step two. No colour change on hover except for
destructive actions.
- Motion: 150ms `CubicEase(EaseOut)` for drawers/popovers; 90ms for hover/press. No springs —
WPF has no spring easing and hand-rolled overshoot reads as jank at 60Hz.
- Every action produces a visible outcome. No dead ends, no silent failures.
## Not in this standard
- The audio dock, its four bays, per-bay faders, 24-segment ladders, transport controls, lip-sync
slider and master telemetry strip — **exploratory**. The controls they re-house already exist in
the app; whether any of them gets a dock is a separate product decision.
- The page-nav sidebar (Broadcast Studio / Audio Mixer / Scene Matrix / Telemetry / Hotkeys) — the
app is one surface with an EDIT toggle and drawers, not a page router.
- CPU / GPU / NVENC readouts — no telemetry exists, and none of it changes a live decision.
- Acrylic/backdrop blur — WPF has no sub-region backdrop blur; panels are solid.
- **On-stream output** (chat box, social bar, alerts, brand flash) is styled by its own renderers,
not by this theme. Do not apply UI tokens to the broadcast picture.
## Rejected from the 2026-10-29 export
The export is a Material-3 dump from a warm seed; four tokens came out tinted by that seed and are
rejected in favour of the values above.
| Export value | Token | Why rejected |
|---|---|---|
| `#4cd7f6` | `tertiary` | Neon cyan beside the amber reads "toy"; `#38bdf8` is calmer and already used in-app |
| `#ab8986` | `outline` | Warm pink borders from the seed — wrong for a navy chassis |
| `#5b403e` | `outline-variant` | Same seed artifact |
| `#e4beba` | `on-surface-variant` | Pink secondary text; slate `#94a3b8` is legible and neutral |
## Implementation status
- **Not yet wired.** `Themes/Controls.xaml` still carries the legacy palette and the dozens of
hardcoded hexes; `Themes/Tokens.xaml` lands next, then surfaces are converted one at a time.
- Target end state: every colour, radius and spacing value resolves from `Tokens.xaml`; a guard
test fails on any raw `#hex` outside it.
+7 -3
View File
@@ -5,9 +5,13 @@ Read before branding, marketing, pricing, licensing or packaging work.
## Brand
Brand palette and official assets live in `MARCOM.md` (gitignored — read it for hex values,
asset file names, and marketing copy). The brand red `#e94560` is the primary accent used
throughout the UI.
**The UI design standard is [`DESIGN.md`](../../DESIGN.md)** — colours, type scale, spacing, radii
and elevation, all normative, implemented by `Themes/Tokens.xaml`. Accent blue `#38bdf8` is the only
interactive accent; red `#ff5451` means live/record and nothing else. The old brand red `#e94560` is
retired from app chrome (the wordmark/logo artwork is unchanged).
Marketing palette, official assets and copy live in `MARCOM.md` (gitignored — read it before any
branding or marketing work).
### Product name vs repo/assembly branding (2026-09-14)
+1 -1
View File
@@ -110,7 +110,7 @@ The app is a **director's control surface**, not an editor. This replaces the OB
- **Edit safety:** edit availability follows `EditingActive`; it is no longer a hard lock derived from "offline and not recording." Keep the explicit toggle and output/edit behavior distinct.
- **Selected-layer preview access:** a draggable layer selected from the list temporarily gets the highest preview `Panel.ZIndex` and first priority in the preview's custom hit test, so it can be grabbed even underneath a higher scene layer. Clearing/replacing selection restores the preview stack; `Scene.Elements` order is untouched, so output and saved z-order do not change. Guard: `ytLive.Tests/SelectedLayerPreviewHitTestingTests.cs`.
**Scene thumbnails:** `Scene.Snapshot` is a 320×180 compositor render. The strip uses per-scene `ThumbnailAssetId`, then background art, then a placeholder; existing saved `OnAirImageAssetId` can still replace the staged tile. The old hardcoded CRT-thumbnail and on-air seed paths are empty, so a fresh layout no longer imports that artwork. Minis never render live captures. `DESIGN.md` records exploratory Stitch color/type tokens only; it is not a layout spec and has not been reconciled into `Themes/Controls.xaml`.
**Scene thumbnails:** `Scene.Snapshot` is a 320×180 compositor render. The strip uses per-scene `ThumbnailAssetId`, then background art, then a placeholder; existing saved `OnAirImageAssetId` can still replace the staged tile. The old hardcoded CRT-thumbnail and on-air seed paths are empty, so a fresh layout no longer imports that artwork. Minis never render live captures. `DESIGN.md` is the visual standard (tokens — `Themes/Tokens.xaml` implements them); it is not a layout spec.
## Global hotkeys (TASK 20 — step 1 shipped 2026-08-24)