Skip to content

[chat-ux] Mic button pulses while recording; normalize composer icon optics #14331

Description

@lalalune

Problem

Every sibling surface pulses when the mic is hot (grabber bar, collapsed pill, kiosk composer, HomePill) — but the overlay's own mic button, the one users press on the primary surface, only turns accent-colored and never pulses. Color and motion disagree. There is also a minor optical inconsistency: lucide icons render at 26px while hand-drawn glyphs render at 30px, so the '+' glyph looks larger than the mic/send icons.

Current state (file refs)

  • SoftButton (packages/ui/src/components/shell/ContinuousChatOverlay.tsx:309-369): borderless 44×44 hit target (WCAG 2.5.5), lucide icons at h-[26px] w-[26px] (:363), hand-drawn glyphs at h-[30px] w-[30px] (:365). active renders text-accent only — no pulse (:358).
  • Overlay mic button call site: ContinuousChatOverlay.tsx:4400-4427active={recording || handsFree || transcriptionMode} (:4420), static accent, NO pulse.
  • Sibling surfaces that DO pulse: grabber bar animate-pulse bg-accent (:509-513, glow :3703); collapsed pill same pulse via glow={listening || responding} (:582-586, :4445); kiosk ChatSurface mic active && "animate-pulse" (glass-composer.tsx:108); HomePill animate-pulse bg-warn/70 on listening (HomePill.tsx:66-68).
  • Reduced-motion pattern already in the file: motion-reduce:animate-none at :512.

Proposed change

  1. Pulse the overlay mic button on the SAME predicate that already sets activerecording || handsFree || transcriptionMode (:4420) — so color and motion never disagree. Reuse the existing animate-pulse + motion-reduce:animate-none pattern (:512); orange accent only, no background/border change, no blue.
  2. Normalize composer icon optics: bring the lucide 26px and glyph 30px sizing to a single optically-balanced size so the '+', mic, and send read at the same visual weight. Keep the 44×44 hit target intact (do NOT shrink the hit area, only the visible glyph metrics).

Acceptance criteria

  • The overlay mic button visibly pulses (accent) whenever recording || handsFree || transcriptionMode is true, and stops when it clears — matching the grabber/pill.
  • motion-reduce:animate-none is respected: with reduced motion the button stays statically accent, no pulse.
  • The '+', mic, and send icons read at the same optical weight; the 44×44 hit target is unchanged (WCAG 2.5.5 preserved).
  • The already-done pill-pulse-when-collapsed behavior is unregressed AND now has a regression test (it currently has none).
  • A ContinuousChatOverlay.test.tsx (or e2e) case asserts the mic button carries the pulse class exactly when the recording predicate is true and drops it otherwise.

Evidence required (post INLINE in the PR)

  • MP4 walkthrough: start listening → mic button pulses; stop → pulse stops; with OS reduced-motion on → no pulse. Desktop AND mobile.
  • JPG before (mic static while recording — the wrong behavior) + after (mic pulsing) screenshots, plus a side-by-side of the '+'/mic/send optical sizing before/after.
  • The new regression-test output (pass).
  • Frontend console logs from the voice session showing the recording state transitions.

Workstream: Chat window UX · design doc · MVP board

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Important for MVPbugSomething isn't workingmvpLifeOps Personal Assistant MVP work (project board 15)uivoice

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions