Product Designer & Builder · Personal project
Hold a key. Speak. Perfect text, anywhere.
And a memory of everything you hear.
Undertone is a macOS dictation and memory app I designed and am building myself: one hotkey to speak anywhere, and a local, on-device memory of every meeting, call, and dictation. It runs entirely on this Mac.
The system
One design language, held on purpose
CoScope tokens throughout: Geist for UI, Geist Mono for transcripts, hotkeys, and timestamps; a blurple accent reserved for interactivity and selection only; and fixed green, amber, and red for health and verdicts, never derived from the accent. The app follows macOS layout conventions: sidebar settings, a menu-bar popover, and non-activating HUD panels. Every screen carries a light and dark theme, and that choice persists across the app.
Speaker colors are hue-rotations of the accent: Matthew at +0°, Taylor at −80°, Ray at +70°, and each new speaker continuing around the wheel while skipping the semantic hues. Unverified speakers stay gray with a dashed chip, never a color, so a glance separates “named” from “guessed.” Past six participants, colors repeat and the initials carry the distinction.
Screen 1 · Dictation HUD
Try it anywhere
A non-activating floating pill, 280 by 64, with shadow-pop. Hold the hotkey, speak, and cleaned-up text pastes at your cursor. Every state is one recognizable motif.
Screen 2 · Menu bar popover
The whole app in a 320-pixel column
Status, sources health, quick controls, and the last dictation, all reachable from the menu bar without opening a window.
Let's move the CallGrid review to Thursday at 2. I'll send Ray the webhook retry doc before then.
Screens 11 + 12 · Timeline & session detail
One searchable memory of the day
Dictations, meetings, calls, and ambient audio land in one timeline. Click a session to push into its detail: a speaker-colored transcript and checkable action items.
Webhook retries block the CallGrid launch. Review moved to Thursday 2pm; Ray owns the retry doc.
Screen 14 · Action item inbox
Two tracks: confirmed, and “confirm this”
Commitments extracted from meetings and calls land here. Clean extractions get a checkbox; anything the model is unsure about gets a VERIFY badge with Confirm and Dismiss instead, so a guess never silently becomes a task.
Screen 9 · History
Every dictation, and what cleanup changed
A running list of dictations with clipboard and recovered badges. Open the raw-transcript disclosure to see exactly what the cleanup step removed and rewrote, an inline diff against the final text.
Sounds good. Let's move the CallGrid review to Thursday at 2. I'll send Ray the webhook retry doc before then.
Raw transcript
The rest of the surface
Setup, sources, and capture
Four steps, permission-gated
Welcome, then three permissions (Microphone, Accessibility, Input Monitoring) that each flip from a Grant… button to a green Granted badge, with a footnote that Screen Recording is only requested later if you turn on meeting capture. Then a model picker, and a hotkey step with a live “Try it now” sandbox.
“Right ⌘ works well. It does nothing else.” The model download is resumable: pause it and it resumes where it left off.
Two speech engines, honest degrade
Sidebar tabs carry amber or red dot badges when something is degraded. Models pairs Parakeet v3 (598 MB, recommended, instant) with Whisper large-v3-turbo (1.48 GB, optional), a primary radio, and automatic fallback. Cleanup runs on Apple on-device or Ollama, with a live reachability check.
“Ollama unreachable, dictations paste raw until it's back.” “Degraded shows the worst honest state at once, no dead ends.”
Meeting capture and command mode
A meeting-detection card (“Meeting detected · Google Meet · mic + system audio”) with Dismiss and Record, auto-dismissing in 15s. While recording, a pinned red indicator is never hidden. Command mode uses a tinted accent pill so it can't be mistaken for dictation.
“make this shorter” → replacement preview. Return replaces, Esc cancels, and the selection is untouched until Replace, and never touched on failure.
How the memory layer got its history
Years of history, imported in one pass
The timeline does not have to start empty. Undertone's memory layer can bootstrap from existing meeting-recording archives through a hash-verified importer. Where the same meeting exists in more than one archive, it dedupes by richest-copy-wins (transcript length → screenshot count → attendee count → calendar-event presence), so the fullest copy always survives.
Imports are strictly read-only on the source: media is verified by checksum, copied once into the local store, and every screenshot and audio reference is linked before a record is committed. The result is a single searchable timeline that reaches back years before the app's first launch.