From a010333787e49d2919f3a225af1be91c8b96f295 Mon Sep 17 00:00:00 2001 From: Nexus Dev Date: Sat, 4 Apr 2026 01:53:32 +0000 Subject: [PATCH] docs(37): UI design contract for web-chat-voice-ui Co-Authored-By: Claude Sonnet 4.6 --- .../phases/37-web-chat-voice-ui/37-UI-SPEC.md | 207 ++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 .planning/phases/37-web-chat-voice-ui/37-UI-SPEC.md diff --git a/.planning/phases/37-web-chat-voice-ui/37-UI-SPEC.md b/.planning/phases/37-web-chat-voice-ui/37-UI-SPEC.md new file mode 100644 index 00000000..2f104b59 --- /dev/null +++ b/.planning/phases/37-web-chat-voice-ui/37-UI-SPEC.md @@ -0,0 +1,207 @@ +--- +phase: 37 +slug: web-chat-voice-ui +status: draft +shadcn_initialized: true +preset: new-york / neutral / tailwind-v4 +created: 2026-04-03 +--- + +# Phase 37 — UI Design Contract + +> Visual and interaction contract for frontend phases. Generated by gsd-ui-researcher, verified by gsd-ui-checker. + +--- + +## Design System + +| Property | Value | +|----------|-------| +| Tool | shadcn (new-york style) | +| Preset | new-york, baseColor: neutral, cssVariables: true | +| Component library | Radix UI (via shadcn) | +| Icon library | lucide-react | +| Font | System default (inherit from body) | + +Source: `components.json` detected + `npx shadcn info -c ui` confirmed. + +--- + +## Spacing Scale + +Declared values (must be multiples of 4): + +| Token | Value | Usage | +|-------|-------|-------| +| xs | 4px | Icon gaps, waveform bar gaps, badge inner padding | +| sm | 8px | Button icon padding, compact element spacing | +| md | 16px | Chat message padding, input field padding | +| lg | 24px | Panel section spacing | +| xl | 32px | Layout gaps between major sections | +| 2xl | 48px | Major section breaks | +| 3xl | 64px | Page-level spacing | + +Exceptions: +- Mic button and voice mode toggle touch target: 32px (h-8 w-8) to match existing VoiceRecordButton/TtsButton sizing pattern +- Waveform canvas height: 32px fixed (h-8) to stay within input row + +--- + +## Typography + +| Role | Size | Weight | Line Height | +|------|------|--------|-------------| +| Body | 14px (text-sm) | 400 (regular) | 1.5 | +| Label | 12px (text-xs) | 400 (regular) | 1.4 | +| Heading | 16px (text-base) | 600 (semibold) | 1.2 | +| Display | 20px (text-xl) | 600 (semibold) | 1.2 | + +Source: Existing chat components use `text-sm` for message content, `text-xs` for file labels and badges. Matches `ChatMessage.tsx` and `ChatInput.tsx` patterns. + +--- + +## Color + +| Role | Value | Usage | +|------|-------|-------| +| Dominant (60%) | `--background` (#eff1f5 light / #1e1e2e dark) | Chat surface, page background | +| Secondary (30%) | `--secondary` (#ccd0da light / #313244 dark) | User message bubbles, sidebar | +| Accent (10%) | `--primary` (#1e66f5 light / #89b4fa dark) | Active recording state, voice mode active indicator, audio player progress bar | +| Destructive | `--destructive` (#d20f39 light / #f38ba8 dark) | Stop-recording button state (Square icon when recording), delete confirmations | + +Accent reserved for: +1. VoiceMicButton border/ring when in active recording state +2. Voice mode toggle active-state highlight (currently selected mode pill) +3. Audio player progress fill while audio is playing +4. Waveform bars while recording is live + +Source: `src/index.css` CSS variable definitions. Existing `VoiceRecordButton` uses `text-destructive` for stop state — contract preserves this pattern. + +--- + +## Component Inventory + +New components to build for this phase: + +| Component | Location | Description | +|-----------|----------|-------------| +| `VoiceMicButton` | `ui/src/components/VoiceMicButton.tsx` | Replaces `VoiceRecordButton` — adds VAD auto-stop, waveform visualization, three visual states (idle / recording+waveform / processing) | +| `VoiceWaveform` | `ui/src/components/VoiceWaveform.tsx` | Canvas-based amplitude bars, 30-50 data points, 32px tall, animated during recording only | +| `VoiceModeToggle` | `ui/src/components/VoiceModeToggle.tsx` | Three-state pill toggle: "Text" / "Voice In" / "Full Voice" — persists via nexus-settings | +| `ChatVoicePlayer` | `ui/src/components/ChatVoicePlayer.tsx` | Inline `