# UI Research Implementation Report - Task: 20260831-105824-plan-code-ui-audit - Agent: coder (UI/UX research pass) - Model: litellm-lan/qwen3.8-27b (the fixed model this agent runs on; note the user asked for a "cheap local qwen3.8-27b" — this is exactly that model, routed via LiteLLM LAN) - Date: 2026-08-31 - Status: complete ## Summary Research-only pass: located and analyzed the square Hope visual element in the reference projects, audited every SwiftUI source file in `voice-ios`, extracted the web design-token system, and produced a full redesign specification. **No product code was modified** — the only files written are this report and `ui-ux-spec.md`. ### The square Hope element (resolved) The square Hope element is the **LED-wall avatar** in the web UI: a 320×320 px square (`border-radius: 26px`) containing a 21×21 dot matrix that blooms with audio. Evidence: - `hope-voice-api/web/style.css` L331–346 — `.led-wall { width: 320px; height: 320px; display: grid; grid-template-columns: repeat(21, 1fr); border-radius: 26px }` - `hope-voice-api/web/style.css` L349–359 — glass panel backing (radial iris gradient + border) - `hope-voice-api/web/style.css` L361–372 — `.led-dot` (base 5 px, 90 ms linear transitions) - `hope-voice-api/web/style.css` L376–392 — state palette: idle `#56739E`, connecting/thinking `#D99A6C`, listening `#6F8FF7`, speaking `#9DC2FF` + drop-shadow - `hope-voice-api/web/app.js` L265–341 — build (21×21, per-dot radial + phase) and per-frame render (gaussian falloff, ripple, audio-reactive sizing, listening dimmed to 0.55×) - `hope-voice-api/web/index.html` L61–62 — wall is `aria-hidden`, separate `aria-live="polite"` label Two related marks documented for the redesign: - **Favicon glyph** (`hope-voice-api/web/favicon.svg`): 64×64 rounded square, plate `#08111F`, iris circle + tilted orbit ellipse + warm dot — compact identity mark. - **Companion icon** (`hope_companion/resources/icon.png`, generated by `scripts/gen-icons.mjs`): 1024² rounded square (r≈22.3%), indigo→violet diagonal gradient, white two-node + arc + ring mark. Verified 1024×1024 RGBA via `sips`. The current iOS app uses **none** of these: `OrbView.swift` L45–47 is a plain 120 pt system-color `Circle()`, and `Resources/Assets.xcassets/AppIcon.appiconset/Contents.json` has no images. ## Files Changed Product code: **none** (research-only mandate). Artifacts written: - `.artifacts/20260831-105824-plan-code-ui-audit/ui-ux-spec.md` — full audit + redesign spec (asset provenance, current-state findings N1–N3/C1–C11, navigation hierarchy, color/shape/ motion tokens with exact values, per-component specs incl. LED-wall formulas, accessibility, app-icon plan, 4-phase rollout, acceptance criteria, risks) - `.artifacts/20260831-105824-plan-code-ui-audit/ui-research-implementation.md` — this report ## Paths Inspected ### voice-ios (all SwiftUI sources read in full) - `Sources/App/VoiceApp.swift`, `Voices.swift`, `SettingsStore.swift` - `Sources/Features/Conversation/ConversationView.swift`, `OrbView.swift` (incl. TranscriptListView) - `Sources/Features/Settings/SettingsView.swift`, `ConnectionTestView.swift` - `Sources/Features/Tasks/TaskPanelView.swift` - `Sources/Features/Media/MediaPanelView.swift` - `Sources/LiveKit/VoiceSession.swift`, `ConversationState.swift`, `TranscriptHandler.swift`, `TranscriptHistory.swift`, `ControlChannel.swift`, `TaskStore.swift`, `AgentMonitor.swift` - `Sources/Media/MediaPlayerController.swift`, `PinnedMediaResourceLoader.swift`, `MediaAPI.swift` - `Sources/Networking/TokenClient.swift`, `ServerConfig.swift`, `TLSPinning.swift` - `project.yml`, `Resources/Info.plist`, `Resources/Assets.xcassets/AppIcon.appiconset/Contents.json` - `PLAN.md`, `UPDATE_PATH.md`, `AGENTS.md` ### hope-voice-api (reference) - `web/style.css` — token block L1–26, brand glyph L125–166, LED wall L316–429, buttons L431+, message bubbles L702–764, task dots L1120–1150, keyframes L427/L709/L1133 - `web/app.js` — LED wall build/render L265–341, mic level smoothing L343–354, state setter L389 - `web/index.html` — ARIA structure (L18–107) - `web/favicon.svg` — full file (square Hope glyph) ### hope_companion (reference) - `scripts/gen-icons.mjs` — full SDF icon generator (plate, gradient, mark geometry) - `resources/icon.png` — metadata via `sips` (1024×1024 RGBA) - `package.json`, `electron-builder.yml` — icon usage ## Verification Commands run (research-only; no build performed since no code changed): - `sips -g all hope_companion/resources/icon.png` → 1024×1024, RGBA, hasAlpha: yes ✓ - `rg "led-wall|led-dot|orb" hope-voice-api/web/style.css` → located all LED-wall rules (L317–1563) ✓ - `rg "square" voice-ios/` → no hits; confirmed the term maps to the LED-wall container, not a literal "square" identifier ✓ - Read-based verification of every cited line range above. No build/test commands were run because the brief restricts this pass to research and specification; the spec's Phase A–D implementation will carry its own verification per `ui-ux-spec.md` §11 (XcodeBuildMCP simulator build + the PLAN.md Phase 8 reconnect matrix). ## Design Decisions (recorded for the implementer) 1. LED wall is procedural (Canvas + TimelineView ≤30 fps), not a raster asset — matches web implementation and keeps the asset catalog clean. 2. Exact port of app.js formulas (falloff/ripple/sizing) rather than an approximation — the spec includes the verbatim math so behavior matches the reference pixel-for-pixel in intent. 3. System colors fully replaced by a `HopeColor` token enum derived from web `:root`; semantic mapping (mint=success, danger=error, warm=thinking) documented in spec §5.1. 4. Accessibility mirrors web ARIA: wall hidden from VO, separate live status element, announcements throttled to meaningful transitions only. 5. Four-phase rollout (tokens/assets → LED wall → transcript/composer → polish) so each phase is independently reviewable and revertible. ## Risks And Limitations - Simulator mic is dead (-4010, PLAN.md Phase 2): listening-side wall reactivity is device-only; speaking-side verifiable in sim via agent TTS. Recorded as R1 in the spec. - No automated tests exist in the repo (also noted in manifest Open Risks); verification for the implementation phases will be simulator-based + Instruments profiling for the wall. - `Color(hex:)` helper does not exist yet — required prerequisite for Phase A (spec R3). ## Follow-up For Reviewer 1. Confirm the "square Hope element" identification (LED wall) matches the user's intent; if they meant the favicon glyph or companion icon instead, spec §9 already covers both as secondary assets and only §6.1/§10-B would need re-scoping. 2. Review spec §5.1 token table for any brand values that should differ from web (e.g., if a lighter iOS-native surface treatment is preferred over the dark canvas). 3. Approve Phase A–D sequencing before coder implementation begins; each phase has exit criteria in §10 and global acceptance criteria in §11.