Skip to content
Undertone

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.

0:12

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.

0:12
Listening · while hotkey held
Transcribing
Transcribing (~0.7s)
Pasted
Done · flash <400ms, then dismiss
Can't paste into password fields
Blocked · 2s
Saved · on your clipboardAlso in History
Saved, not pasted · 2s
0:12
cleanup off
Degraded · cleanup unavailable
Listening · double-tap ⌘ to stopHands-free

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.

Ready
Parakeet v3 · English
R⌘
DictationMeetingsPocketLimitless
Hands-free mode
ToneAutoFormalCasual
Mute
Last dictationCopy

Let's move the CallGrid review to Thursday at 2. I'll send Ray the webhook retry doc before then.

Timeline
History
Settings⌘,
Quit Undertone⌘Q
All on this Mac

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.

Timeline · 900 × 580
Timeline
4 sessions3 commitments made5 open action itemsOpen inbox →
Weekly pipeline review
09:00 · 42m
Webhook retries block the CallGrid launch; Ray owns the retry doc.
MRS2
4
Coffee with Taylor
08:10 · 26m
Pendant battery drain traced to BLE sync interval, not the mic.
MT
2
Call with Abe
16:30 · 18m
Thursday works for the review; Abe wants the RTB spec beforehand.
MA
1
𝄞
Dictations
all day · 14 items
Mostly Slack replies and the migration-plan note.
Session detail
← Weekly pipeline review
MatthewRaySpeaker 2 · unverified
0:04Matthew: Let's move the CallGrid review to Thursday at 2.
0:11Ray: I'll own the webhook retry doc and send it before then.
screenshot at 14:32
0:33Speaker 2unverified: Retries are what's blocking the launch, not the payload.
audio kept 30 days
AI summary

Webhook retries block the CallGrid launch. Review moved to Thursday 2pm; Ray owns the retry doc.

Action items
Send Ray the webhook retry doc
Move review to Thursday 2pm
Details
AppGoogle Meet
Channelsmic + system
Screenshots7
SourceMeetings

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.

Action Items · 640 × 520
Action Items
All sourcesMeetingsCallsAmbientDictationCopy as markdown
New 3
Send Ray the webhook retry doc
Weekly pipeline review · today
3h
Update migration plan for the 48h dual-write window
Weekly pipeline review · today
3h
VERIFY
Loop hardware in on pendant battery findings
Coffee with Taylor · today
ConfirmDismiss
Open 4
Send Abe the RTB spec before Thursday
Call with Abe · yesterday
1d
File the RTB spec feedback
Dictation · yesterday
1d
Book the offsite room for the platform review
Standup · Jun 26
6d
VERIFY
Reply to the Wispr export question
Call with Mateo · Jun 25
ConfirmDismiss
Done this week 2
Share the qwen cleanup prompt with Taylor
Coffee with Taylor · Mon
2d
Confirm Thursday review with Abe
Call with Abe · yesterday
1d

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.

History · 720 × 520
History
Keep 30 days7 daysforeverCopy
Today
Let's move the CallGrid review to Thursday…
SSlack14:32 · 24w
recoveredDraft the dual-write migration note…
NNotes11:08 · 61w
Yesterday
Reply to Abe about the RTB spec…
MMail16:45 · 38w
Slack · 14:32 · on clipboard · never pasted
Final

Sounds good. Let's move the CallGrid review to Thursday at 2. I'll send Ray the webhook retry doc before then.

Raw transcript
um so sounds good uh: let's Let's move the CallGrid call grid CallGrid review to Thursday at 2 thursday at two 2. i'll i'll I'll send Ray the webhook retry doc before then.
removed by cleanuprewritten by cleanup

The rest of the surface

Setup, sources, and capture

Screen 3 · Onboarding

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.

GrantedGrant…Right ⌘

“Right ⌘ works well. It does nothing else.” The model download is resumable: pause it and it resumes where it left off.

Screens 4-8 + 10 · Settings

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.

OffLightFull

“Ollama unreachable, dictations paste raw until it's back.” “Degraded shows the worst honest state at once, no dead ends.”

Screens 13 + 15 · Capture & command

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.

0:42Listening for an instruction

“make this shorter” → replacement preview. Return replaces, Esc cancels, and the selection is untouched until Replace, and never touched on failure.

Settings · Sources · four feeds, one local memory
Dictation
214 items this week
Meetings
9 items · synced 2h ago
Pocket
API unreachable since Jul 1
Limitless
31 items · synced 18m ago

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.

Built in the open, one Mac at a time.

Back to all work →