* feat(dictation): recording deck with timer, waveform, pause, retry and send modes
* fix(dictation): remove stray pulse ring and let waveform shrink on narrow composers
* test(systemd): scrub ambient OMP_WEB_OMP_BIN so install test is hermetic
* feat(dictation): mic becomes cancel while recording, composer Send transcribes+queues, deck keeps only pause and stop
* fix(dictation): apply review findings — theme tokens, audio lifecycle, attachment staleness, dynamic waveform width
- Use the theme's --status-error token instead of undefined --danger
custom properties so dictation colors follow light/dark themes.
- Close the AudioContext and release the analyser when capture finishes,
not only on cleanup, so transcription no longer holds the mic graph.
- Read attachments through refs inside handleSend/sendQueued so files
attached mid-recording are included when the transcript dispatches.
- Surface 'No speech detected' when a capture yields no audio instead of
failing silently.
- Stretch the waveform canvas to the free composer width (dynamic bar
count, newest samples at the buttons) and freeze it gray while paused.
- Make the transcribe-and-send wiring test assert the contiguous branch.
- Drop the orphaned chatInput.stopDictation i18n key.
* fix(dictation): address coderabbit findings — audio context ownership, state-gated finish, enter passthrough
* feat(dictation): play recording before transcribe
Stop enters review with playback instead of sending immediately.
Paused capture keeps a left-side preview play button.
* feat(dictation): fix audio playback lifecycle, timeslice, and replay reset
* fix(dictation): address review findings (timer corruption, audio leak, icon, test honesty)
* fix(dictation): restore setIsRecording(true) on capture start and add behavioral test suite
* fix(dictation): allow blob: media in CSP so preview playback works; mic icon for resume
* fix(dictation): draw recorded bars and playback progress in review-mode waveform
* fix(dictation): stop replaced preview audio; neutral confirm label
* chore(ci): retrigger windows verify after flaky MessageView copy test