Open-source conversation memory. Local, private, free forever.
- What this is: Local-first conversation memory layer for developers — captures meetings and voice memos via Whisper.cpp, makes them queryable via MCP tools for Claude, Codex, Gemini CLI
- Who it's for: Developers and power users who run AI assistants and care about privacy
- Space: Developer tools, AI tooling, local-first computing
- Project type: Two unified surfaces — marketing landing site (Next.js) + macOS menu bar app (Tauri)
- Direction: Terminal With a Soul — Unix precision meets editorial humanity
- Decoration level: Minimal — the transcript output is the decoration
- Mood: The product should feel like it was built by someone who would never ship something embarrassing. Ink & Switch energy, not Notion energy. Archival permanence, not ephemeral SaaS.
- Key design bet: Light cream as the default (paper-like, archival) with warm-dark as the dark mode. Every other tool in this category defaults to dark — this is the deliberate departure.
- Display/Hero: Instrument Serif — literary gravitas for a product about human conversations. The italic weight is used for emphasis within headings (e.g. "conversation memory."). No other tool in this category uses a serif; this is intentional.
- Body/UI: Geist — Vercel's clean, technical sans-serif. Pairs naturally with Geist Mono. Used for all body text, labels, buttons, and navigation.
- Transcript/code/mono: Geist Mono — for all diarized output, timestamps, speaker labels, action items, YAML frontmatter, CLI examples, keyboard shortcuts.
- Loading (landing site): Google Fonts CDN for Instrument Serif + Geist + Geist Mono
- Loading (Tauri app): Bundled WOFF2 files in
tauri/src/fonts/— offline-safe, no network dependency
Scale (landing site):
| Role | Font | Size | Weight |
|---|---|---|---|
| Hero heading | Instrument Serif | 56-58px | 400 |
| Section heading | Instrument Serif | 28-32px | 400 |
| Feature title | Instrument Serif | 18-20px | 400 |
| Body | Geist | 15-17px | 400 |
| UI/labels | Geist | 13-14px | 400-600 |
| Mono labels | Geist Mono | 10-12px | 400-500 |
| Transcript | Geist Mono | 11-12px | 400 |
Scale (Tauri app):
| Role | Font | Size | Weight |
|---|---|---|---|
| Meeting titles | Geist | 14px | 600 |
| Headings | Instrument Serif | 18-22px | 400 |
| Body | Geist | 13px | 400 |
| Timestamps/metadata | Geist Mono | 11-12px | 400 |
| Transcript output | Geist Mono | 11-12px | 400 |
Two-mode system. Light is the default on the landing site. The Tauri app respects system preference.
--bg: #F8F4ED; /* warm cream, paper-like */
--bg-elevated: #EFEBE2; /* card/panel lift */
--bg-hover: #E8E2D8; /* deeper surface, input backgrounds */
--border: rgba(0,0,0,0.07);
--border-mid: rgba(0,0,0,0.13); /* more visible borders */
--text: #1A1916; /* near-black, warm undertone */
--text-secondary: #8C8880; /* labels, metadata */
--text-tertiary: #BDB9B0; /* placeholders, timestamps */
--accent: #C96B4E; /* coral — CTAs, links, italic heading, speaker labels */
--accent-hover: #B85A3E; /* accent hover state */
--accent-soft: rgba(201,107,78,0.10); /* accent background tint */
--red: #C0392B; /* recording indicator, errors, destructive */
--green: #2E7D46; /* success, complete */--bg: #0D0D0B; /* warm near-black, not pure #000 */
--bg-elevated: #141412; /* card/panel lift (Tauri: --bg-elevated) */
--bg-hover: #1C1C1A; /* elevated panels, Tauri primary surface */
--border: rgba(255,255,255,0.06);
--border-mid: #2A2924; /* warm stone, more visible */
--text: #E8E4DA; /* cream off-white */
--text-secondary: #6B6760; /* labels, metadata */
--text-tertiary: #3D3B38; /* placeholders, timestamps */
--accent: #30D158; /* green — CTAs, links, speaker labels */
--accent-hover: #4ADE70; /* accent hover state */
--accent-soft: rgba(48,209,88,0.10);
--red: #FF453A; /* recording indicator, errors, destructive */
--red-bg: rgba(255,69,58,0.12);
--green: #30D158; /* success (doubles as accent in dark mode) */
--live: #30D158; /* live transcript indicator */
--purple: #BF5AF2; /* AI/assistant state */
--orange: #D4832A; /* processing/pending state */Accent usage — restrained. The accent should appear only on:
- Italic or emphasized text in the hero heading
- Speaker labels in transcript output
- Feature/section label text (the small uppercase mono labels)
- CTA button fill (primary action only)
- Nav link hover state
- Active/focus states on interactive elements
Never use the accent as a background for large areas or as decoration. It earns its attention by being rare.
Recording red is separate. The red (--red) is strictly semantic — recording state, errors, destructive actions. Never use it as a general accent.
- Base unit: 8px
- Density: Comfortable on landing, compact in the Tauri app
| Token | Value | Use |
|---|---|---|
| 2xs | 4px | Icon gaps, inline spacing |
| xs | 8px | Between list items, small gaps |
| sm | 12-16px | Section padding, card interiors |
| md | 24px | Between sections, card-to-card |
| lg | 32-40px | Page sections |
| xl | 56-72px | Hero spacing, major section breaks |
| Page margin | 32px | Window/viewport edge to content |
| Max content width | 800px | Landing site |
- Approach: Grid-disciplined — single column, centered, 800px max width on the landing site. The Tauri app uses a two-panel layout (list + detail) where applicable.
- Composition first: The landing page opens as a poster, not a document. Hero heading is the first thing that lands; the transcript card is the second. No above-the-fold feature grids.
- Transcript as hero visual: The actual diarized output (speaker labels, timestamps, action items) rendered in Geist Mono is the primary product demo. Competitors hide raw output. Minutes celebrates it.
| Context | Value |
|---|---|
| Landing buttons | 5px — sharp, developer-coded |
| App buttons | 8px |
| Cards, panels | 8px (landing) / 10-12px (app) |
| Input fields | 6-8px |
| Pills, badges | 999px |
| Inline code | 3px |
Consistent rounding. Landing is slightly sharper than the app. Never fully squared, never fully bubbly.
- Approach: Minimal-functional — only transitions that aid comprehension
- Theme toggle: 0.25s ease on background/color changes — the whole page transitions together
- Hover states: 0.15-0.2s ease
- Panel open/close: 0.2s ease-out
- Recording pulse: 1s ease-in-out, infinite — the only animation that loops
No bounces, no entrance animations, no scroll-driven effects. Utility-grade motion.
Primary: bg: --accent, text: white (light) / #0D0D0B (dark), radius: 5px (landing) / 8px (app)
Ghost: bg: transparent, text: --text-secondary, border: --border-mid, radius: same
Icon-only: 28×28px, hover: --bg-hover
Container: bg: --bg-elevated, border: 1px solid --border, radius: 8px
Header: padding: 12px 18px, border-bottom: 1px solid --border
Body: padding: 16-18px, font: Geist Mono 11-12px
Speaker: color: --accent
Timestamp: color: --text-tertiary
Action item: ☐ glyph, color: --accent
Divider: 1px solid --border between body and action items
Grid: 2-column, 1px gap, background: --border (creates border-like lines)
Cell: bg: --bg, padding: 22-24px
Label: Geist Mono 10px uppercase, color: --accent
Title: Instrument Serif 18-20px, color: --text
Description: Geist 13px, color: --text-secondary
Background: --bg-hover
Border: 1px solid --border-mid
Radius: 6-8px
Padding: 6px 10px
Font: Geist 13px
Background: --accent-soft
Text: --accent
Radius: 999px
Padding: 2px 8px
Font: Geist Mono 10-11px
Background: --bg-hover
Border: 1px solid --border-mid
Backdrop-filter: blur(12px)
Radius: 12-14px
Shadow: 0 8px 32px rgba(0,0,0,0.3) — light / 0.5 — dark
IDLE → tray icon: default
RECORDING → tray icon: red dot, pulsing --red indicator, timer in Geist Mono
PROCESSING → spinner with stage label in --text-secondary
COMPLETE → --green check, file path in Geist Mono
ERROR → --red indicator, error message, preserved capture path
Every state must be visible in every surface (tray, app, CLI output).
- No custom icon set. System emoji for status indicators.
- Recording:
●(--red) - Success:
✓(--green) - Error:
✗(--red) - Voice memo:
📱 - Action item:
☐/☑ - Ghost context:
👻
- Minimum contrast: WCAG AA (4.5:1 for body text, 3:1 for large text)
- Light mode: #1A1916 on #F8F4ED = ~16:1. Coral #C96B4E on #F8F4ED = ~3.8:1 (acceptable for large text/UI elements; avoid for small body copy)
- Dark mode: #E8E4DA on #0D0D0B = ~14:1. Green #30D158 on #0D0D0B = ~8.5:1
- All interactive elements keyboard-accessible
- Focus indicators: 2px solid --accent outline
- No information conveyed by color alone — always paired with text or icon
| Date | Decision | Rationale |
|---|---|---|
| 2026-04-08 | Light cream (#F8F4ED) as landing default | Every tool in this category defaults to dark. Cream signals archival permanence and differentiates. |
| 2026-04-08 | Instrument Serif for headings | Only serif in the category — signals "conversations" not "code." Both voices in design consultation independently agreed. |
| 2026-04-08 | Coral accent in light (#C96B4E), green in dark (#30D158) | Warm/human for light mode, terminal/alive for dark mode. Accent is used only in 5 specific spots — never decoratively. |
| 2026-04-08 | Transcript output as hero visual | Real diarized output in Geist Mono replaces the existing DemoPlayer gif. The product's output is the aesthetic. |
| 2026-04-08 | Warm near-black (#0D0D0B) not pure black | Slightly warm undertone unifies dark mode with the cream light mode surfaces. |
| 2026-04-08 | No gradients, no glows, no illustration | Information density is the aesthetic. The only decoration is well-set type. |