Notes and LLM-generated summaries both render untrusted Markdown via
{@html} into a webview with an IPC bridge to the Rust backend, so the
DOMPurify sanitization step is a real security boundary, not cosmetic —
worth one shared implementation instead of a second inline copy that
could drift out of sync.
Traps focus in the recording-consent overlay the same way as Settings.
Adds a visually-hidden aria-live region announcing "Recording
started/paused/stopped" — previously nothing in the header was a live
region, so a non-visual user had no way to learn recording had begun.
Bold/Italic/Bullet-list/Checkbox buttons rendered a bare glyph with
only a title tooltip; add matching aria-label so a screen reader
announces the action rather than the raw Unicode character name.
Moves focus into the dialog on mount, cycles Tab/Shift+Tab within its
focusable elements, and restores focus to whatever had it before the
dialog opened once it closes.
Ctrl+Shift+R toggles recording, Ctrl+, toggles Settings, Escape closes
whichever overlay (consent notice, then Settings) is open. Shortcuts
never hijack typing in an input/textarea/select/contenteditable target;
Escape is exempt from that guard so it always closes an open modal.
"Template apply" from the roadmap item isn't included — there's no
template-selection UI yet (that lands with T8.1 in Phase 8).
A simple rms-fill + peak-marker bar rather than a scrolling waveform —
either satisfies the requirement with far less state. Shows a warning
banner while a capture device reconnect is in progress.
start_recording now creates the EventSink alongside the existing frame
channel and forwards Level/DeviceChanged onto a small fire-and-forget
thread that emits "recording://level" and "recording://device".
Adds AudioLevel (rms/peak per chunk, throttled to ~20Hz) and
CaptureEvent::DeviceChanged emitted through a new EventSink alongside
the existing FrameSink. On a capture read failure, reopens against
whatever is now the default render device and continues the same WAV
file if the new format is compatible; otherwise fails loudly rather
than silently corrupting the recording.
Resolves settings.theme against prefers-color-scheme for "system" and
updates live if the OS preference changes. Adds a theme selector next
to the settings gear. Also adds --danger/--warning/--success tokens
tuned per-theme for WCAG AA contrast (the prior fixed hex values failed
4.5:1 against the dark palette).
Shows the LLM endpoint's local/remote status, sync enabled state, the
derived egress allowlist, and enabled sync targets with third-party/TLS
labeling, so the UI can prove local-only handling to the user.
Reports LLM endpoint/local-only status and enabled sync targets so the
UI can prove local-only handling, per the shape fixed in
docs/04-api-contracts.md. Sync targets stay empty until Phase 9 lands
SyncManager; list_sync_targets' not_implemented error is swallowed
rather than failing the whole self-check.