muesli

design language system
PR #584 · updated October 8, 2026 · macOS native app

01 Color System

Adaptive colors with dark and light mode variants. Built on layered backgrounds for depth perception.

Backgrounds (Layered)

backgroundDeep
#0B0C0E / #F5F5F7
backgroundBase
#161719 / #FFFFFF
backgroundRaised
#202226 / #F0F0F2
backgroundHover
#232528 / #E8E8EC

Surfaces

surfacePrimary
#262830 / #E5E5EA
surfaceSelected
#2E3340 / #D6DFFE
surfaceBorder
White 7% / Black 8%

Text Hierarchy

TokenDark ModeLight ModeUsage
textPrimaryWhite 92%Black 88%Headings, body text
textSecondaryWhite 74%Black 66%Labels, metadata
textTertiaryWhite 56%Black 55%Hints, disabled, timestamps

Accent & Semantic

accent
#6BA3F7 / #2563EB
recording
#EF4444
transcribing
#F59E0B
success
#34D399
joinRecord
rgb(0.20, 0.72, 0.53)

02 Typography

The native interface uses system SF Pro through SwiftUI system fonts. Use monospaced digits for numeric statistics and a 15pt reading style for dictations, meeting notes, and transcripts. Browser examples use the local system font; no remote font dependency.

Type Scale

title1 · 26pt Bold
Meeting Summary
title2 · 20pt Semi
Dictations
title3 · 18pt Semi
No meetings yet
headline · 15pt Semi
Sprint Planning Call
body · 14pt Regular
The team discussed deployment timelines and reviewed outstanding bugs.
callout · 13pt Regular
Hold Left Cmd to dictate
caption · 12pt Regular
2026-03-16 09:41 • 1m 14s
reading · 15pt Regular
Clear notes should be comfortable to read. Use a 720pt maximum reading column and 5pt additional line spacing for meeting content; dictation previews use 3pt.

Special Variants

VariantUsageExample
Monospaced 13ptTimestamps; transcript editing uses the reading style2026-03-16 09:41
Rounded 24pt SemiboldHotkey display in onboardingLeft Cmd
Monospaced 12pt SemiboldVersion displayv0.4.0

03 Spacing & Grid

4pt base grid. Seven increments cover all layout needs.

4pt
spacing4
8pt
spacing8
12pt
spacing12
16pt
spacing16
20pt
spacing20
24pt
spacing24
32pt
spacing32

Corner Radii

6pt
Small
10pt
Medium
14pt
Large
20pt
XL
h/2
Pill

04 Iconography

SF Symbols for UI chrome, animated waveform bars for the floating indicator, custom MWaveformIcon for branding.

Sidebar Navigation

🕒
clock
Timeline
〜
waveform
Dictations
👥
person.wave.2
Meetings
📊
chart.bar.xaxis
Insights
📖
character.book.closed
Dictionary
💻
cpu
Models
⌘
command
Shortcuts
⚙
gearshape
Settings
ℹ
info.circle
About

Timeline (clock) leads: one chronological feed combining dictations and meetings. The Meetings row expands to reveal meeting folders, with children indented as a group (position carries nesting, not icon size). Insights is a first-class sidebar item. Models, Shortcuts, Settings, and About sit in the bottom section. The rail is fixed at 240pt expanded and collapses to a 68pt icon strip via the header toggle. Navigation labels are 14pt, medium normally and semibold when selected. Milestone-gated sharing links live in About.

Icons are outline-only at 14pt medium; .fill is reserved for selection state, keeping ink weight even across the column. The icon column is center-aligned and starts at the search field's inner padding, so row glyphs sit directly under the magnifier.

Floating Indicator Controls

GlyphStateContext
❚❚❚Idle, Preparing, RecordingAnimated MWaveformIcon bars — dictation states render live amplitude, not emoji
⏸Meeting recordingPause — click to pause recording (recordingControlSymbol())
▶Meeting pausedResume — click to continue recording
×Dictation recordingDiscard — cancel recording
⏹Meeting (menu/loading)Stop glyph in menu-style indicator contexts

MWaveformIcon (Brand Mark)

M-shaped waveform rendered as rounded bars. The full app icon uses ~21 bars forming a symmetrical "M" pattern with two peaks and a central valley. Simplified 9-bar preset for small contexts: [0.45, 0.65, 0.90, 1.0, 0.45, 1.0, 0.90, 0.65, 0.45]

Full Icon (as in app icon)

Simplified (9-bar, for small UI contexts)

05 Floating Indicator

Always-on-top frosted glass pill. Draggable (position persisted), clickable, with smooth animated transitions between states.

Material & Appearance

PropertyValue
MaterialNSVisualEffectView with .hudWindow material, .withinWindow blending
Idle backgroundFrosted glass (vibrancy blur, no solid color)
Recording backgroundSolid accent color at 72% opacity (hides frost)
Corner radiusHalf of pill height (fully rounded)
Window level.floating
Accent colorUser-configurable via Settings — shared with dashboard controls and indicator previews; semantic success/error colors stay distinct
DraggableClick+drag to reposition. Anchor point persisted to config as indicatorAnchor
Idle (Compact)
🎤
44 × 28 · frosted glass · #1e1e2e 44% · alpha 0.85
Idle (Hover)
🎤Hold Left Cmd to dictate
220 × 36 · frosted glass · #1e1e2e 72% · alpha 1.0
Recording (Hold / Toggle)
×
76 × 22 · solid accent 85% (frost hidden)
Left zone (<30pt): X cancel · Right zone: stop square
Recording (Meeting)
⏹
76 × 22 · solid accent 85%
Left zone (<30pt): discard · Right zone: stop ⏹
Transcribing
✍️Transcribing
120 × 32 · frosted glass · #1e1e2e 62% · content bg #D99A11 92%

State Dimensions

StateWidthHeightTintAlphaFrost
Idle (compact)44pt28pt#1e1e2e 44%0.85Visible
Idle (hover)220pt36pt#1e1e2e 72%1.0Visible
Preparing44pt28pt#1e1e2e 62%1.0Visible
Recording76pt22ptrecordingColorHex 85%1.0Hidden (solid)
Transcribing120pt32pt#1e1e2e 62%1.0Visible
Warning260pt36pt—1.0—
Loading180pt36pt—1.0—

Meeting Indicator Click Zones

ZoneX RangeAction
Leftx < 30ptDiscard meeting (with confirmation alert)
Rightx ≥ 30ptStop meeting recording

Toggle/hands-free dictation uses the same zones: left = cancel, right = stop.

Border

StateBorder Color
Idle (compact)White 22%
Idle (hover)White 14%
Preparing / Recording / TranscribingWhite 16%

Waveform Specifications

PropertyValue
Bar width3pt
Bar spacing4pt
Min height5pt
Max height26pt
Bar colorWhite 85%
Stop square6×6pt, White 85%, 1pt radius
5-bar multipliers[0.6, 0.85, 1.0, 0.85, 0.6]
4-bar multipliers[0.7, 1.0, 1.0, 0.7]
AnimationScale Y, 0.6s, easeInEaseOut, autoreverses, 0.07s stagger
Amplitude smoothingExponential average, 0.5 weight, 30fps

Transition Timings

TransitionDurationEasing
Idle ↔ Hover0.24s in / 0.20s outeaseInEaseOut
Idle ↔ Active state0.18seaseInEaseOut
Between active states0.16seaseInEaseOut
Hover exit delay0.14s—

06 Component Library

Atomic components used across the app interface.

Buttons

Download Model
📋 Copy notes
📝 Copy transcript
✨ Re-summarize
✎ Edit
✓ Done
Download
Join & Transcribe
▾
Start Transcribing
VariantBackgroundTextPaddingRadius
PrimaryaccentWhiteH:20 V:86pt
Secondary / IconsurfacePrimarytextSecondaryH:8 V:56pt
Join & Transcribe (split)joinRecordWhite, 10pt semiH:10 V:5 + chevron 6pt5pt (split left/right)
Join & Transcribe (inline)joinRecordWhite, 10pt mediumH:8 V:45pt
DisabledsurfacePrimarytextTertiaryH:8 V:56pt

Disabled state: no border, not-allowed cursor, tooltip explains why. Used for actions unavailable on the current system (e.g. a model requiring a newer macOS) — see Models tab, issue #479.

History Rows

Sprint planning

Review deployment timelines and the next release.

Customer call

Capture decisions and follow-up work.

StateBackgroundSeparationRadius
DefaultTransparent1pt inset bottom divider6pt
Selected meetingAccent at 15%1pt inset bottom divider6pt
HoverbackgroundHover1pt inset bottom divider6pt

Meeting rows use 16pt padding; timeline/dictation rows use 20pt horizontal and 16pt vertical padding. Long dictations show a three-line preview with Show more / Show less. Copy always includes the complete text. Card outlines remain on statistics and grouped settings, where they establish a useful boundary.

Model Card — Incompatible State

Models tab: a model gated to a newer macOS than the current system is marked Incompatible — the title, status badge, description text, Download/Set Active button, and any language picker all read as disabled (textTertiary), with an inline reason instead of a doomed download attempt (issue #479). No progress bar is ever shown for this state. The Incompatible badge takes priority even when the model happens to be downloaded or active already (e.g. downloaded on a newer macOS, then this system was downgraded).

Nemotron 3.5 Multilingual ~665 MB
Live text appears as you speak in more than 100 locales, with language auto-detection and punctuation.
Incompatible
⚠️ Nemotron 3.5 Multilingual requires macOS 15 or later (you're on macOS 14.8).
Download
Cohere Transcribe ~3.8 GB
The most deliberate option for difficult accents and tricky audio.
Incompatible
Language
French ▾
⚠️ Cohere Transcribe requires macOS 15 or later (you're on macOS 14.8).
Set Active

Meeting Notification Panel

Top-right floating notification for upcoming and in-progress calendar meetings.

Upcoming meeting
Sprint Planning · starts in 3 min
Join & Record
▾
PropertyValue
Size360 × 70pt
PositionTop-right of screen containing mouse cursor, 16pt margin
Window levelCGShieldingWindowLevel() + 1 (above fullscreen apps)
Auto-dismiss15s (default), 30s for "starting now"
Progress bar3pt blue bar at bottom, drains left-to-right over dismiss duration
Fade in0.25s alpha 0→1
Fade out0.2s alpha 1→0
Platform iconsZoom (PNG), Google Meet (PNG) — 26×26pt, 14pt left offset
Chevron dropdownNSMenu with "Join Only" + "Transcribe Only" — darker green (#2a9e74), 24pt wide
No URL fallbackSingle blue "Start Transcribing" button (126×30pt)

Join & Transcribe Button (Coming Up)

▶ Join & Transcribe
PropertyValue
BackgroundjoinRecord (#33B888)
TextWhite, 10pt medium
PaddingH:8 V:4
Radius5pt
VisibilityHidden when isMeetingRecording
ActionjoinAndRecord(title:meetingURL:endDate:)

Folder Row

📁 Engineering 5
📁 Customer Calls 3

07 Animation & Interaction

Consistent easing and timing across all interactive elements.

ContextDurationEasing
Hover state changes (buttons, cards)0.15seaseInOut
Indicator state transitions0.16–0.18seaseInEaseOut
Onboarding page navigation0.20seaseInOut
Permission grant animation0.25seaseInOut
Waveform pulse cycle0.60seaseInEaseOut
Stat number transitionsSystem default.numericText()

Interaction Patterns

ElementClickRight-clickOption+clickDrag
Indicator (idle)———Reposition
Indicator (recording)Stop & save——Reposition
Indicator (toggle)Left=discard, Right=saveDiscardDiscardReposition
Indicator (meeting)Stop & saveDiscard confirmDiscard confirmReposition
Meeting cardSelectMove to folder——
Folder rowFilterRename / Delete——

08 App Structure

A stable global sidebar with page-specific content. Meeting details retain their compact layout below 600pt when a meeting is open.

Window Dimensions

PropertyValue
Default size1120 × 790
Minimum size520 × 600pt
Sidebar width240pt expanded / 68pt collapsed
Meeting list pane280–380pt
Detail paneFlexible (fills remaining)

Column Layout

Sidebar
Timeline
Dictations
Meetings
Settings
List
Sprint Call
Customer
Sprint Planning Call
Meeting notes and transcript...

Coming Up Section

Calendar events grouped by day in the meetings browser. Shown when upcomingCalendarEvents is non-empty.

PropertyValue
ContainerbackgroundRaised, 12pt radius, 1pt surfaceBorder, 20pt padding
Header"Coming Up" — Cormorant Garamond 22pt medium
Date column60pt wide — day number (24pt light), label (11pt medium), weekday (10pt)
Event row3pt accent bar (today) or 40% secondary bar · title 13pt medium · time 11pt secondary
Join & RecordGreen button, shown when meetingURL present and not recording
Add to folderMenu button, 10pt medium, surfacePrimary background
Google Calendar link"Add Google to macOS Calendar for real-time sync" — accent color, opens System Settings > Internet Accounts

Notification Panel Positioning

PropertyValue
Screen selectionNSEvent.mouseLocation → NSMouseInRect against all screens
PositionTop-right of screen.visibleFrame, 16pt margin from edges
Collection behavior.canJoinAllSpaces, .fullScreenAuxiliary, .stationary
Window levelCGShieldingWindowLevel() + 1
BorderlessNo shadows on content, opaque false, clear background

Status Bar Menu

ItemAction
Open muesliShow dashboard window
Next meeting countdownTitle + time until start (updates every 30s)
Upcoming Meetings →Submenu with today's events, start recording from menu
Start/Stop Meeting RecordingToggle meeting session
Discard Recording...Abandon with confirmation (shown only when recording)
Recent Dictations →Submenu with last 10
Recent Meetings →Submenu with last 5
STT Backend →Model selection submenu (dictation)
Meeting Backend →Model selection submenu (meetings, independent)
Meeting Summary →OpenAI / OpenRouter / ChatGPT
Settings...Open settings tab
Check for Updates...Sparkle update check
QuitTerminate app

09 Dashboard & Notch Patterns

Current PR #584 reference. Values follow the native components; web examples illustrate geometry and hierarchy rather than reproducing AppKit rendering.

Stacked, Outlined Statistics

2day streak
15.6kwords dictated
134avg WPM
37meetings

Stack the icon, value, and caption vertically, all centered within each card. Use 8pt between items, 16pt card gaps, 16pt inner padding, 10pt corners, and 1pt surface borders. Icons use 20pt SF Symbols in the app. Values use 20pt semibold monospaced digits; captions use 12pt secondary text. The cards open their corresponding Insights section. The native four-column layout still needs a narrow-window adaptation; horizontal scrolling here only preserves the desktop specimen.

Reading & Alignment

Useful content has the strongest contrast. Meeting notes and transcripts use 15pt text in a centered 720pt maximum column, with the text itself left-aligned.

Show more — example interaction

Long dictation previews expand in place. Copy and history actions continue to work on the full record, regardless of the preview state.

Page edges use 32pt insets. Source filters stay left-aligned with the list and Apps filter; labels stay centered inside their segments. Recording-indicator choice titles, captions, and the notch explanatory text are centered under the previews.

Default Accent & Selection

Blue
Red
Amber
Green
Purple
Pink
✓Default

Default is adaptive blue: #6BA3F7 in dark mode, #2563EB in light mode. Its stored legacy value, 1e1e2e, is a sentinel, never a dark swatch. Custom colors use their literal hex. A white checkmark plus ring indicates selection; accessibility announces the name and selected state.

Supporting Actions

Insights sharing
Share

Insights uses a large native bordered-prominent Share button, tinted with the chosen accent. Always show both the icon and the Share label. At narrow widths, move actions below the range picker instead of compressing the label. Disable sharing until a snapshot loads; activating it opens the existing anonymous-image preview.

Sync with iPhone or iPad
Set up sync
✓ Signed in

Sync uses subtle accent fill without an enclosing card. Account status and Sign Out are separate. Destructive maintenance actions keep red labels and confirmation, but use compact controls with quiet borders. These specimens are non-interactive; they do not perform account or data actions.

Centered Notification Dismiss

Correction and meeting notifications

Production uses an image-only SF Symbol xmark at 10pt medium in a 22pt circular NSButton. Do not use a text multiplication sign: its baseline shifts the mark down. The accessibility label and tooltip are Dismiss. Native 1×/2× rendering was verified; this SVG is only a browser specimen.

Single-Line Notch — First Clearance Pass

RegionBehavior
Camera gapUses detected hardware geometry; never shifted to center the asymmetric panel. The example uses 192pt.
Left / right wingsNormally 110pt / 78pt. Height remains the display's top inset. Stop and Cancel retain 20pt and 22pt widths.
WaveformShrinks to remaining width before controls; right padding is 6pt per side, gaps 4pt. Instruction disclosure moves left.
Clearance32pt less coverage at the usual right edge. This is a fixed first pass, not live detection of the system mic indicator. Other display and menu-bar layouts need validation.

Computer-Use Expansion

Center the expanded panel beneath the visible asymmetric bar, 16pt left of the camera center for the usual 110pt/78pt wings. Keep the camera gap fixed. Instruction text uses 13pt; up to three recent tool summaries use 10pt and at most two lines each. The panel starts at 100pt and adds 30pt per response, to 190pt. Summaries describe the operation and outcome (for example, “Read page text”); full responses, observations, and tool arguments remain in Timeline.

Instruction

Can you open Twitter on Google Chrome?

Working…

✓ Opened app

✓ Navigated to page

Provider Logos & Sharing

Provider marks occupy a consistent 32×32pt slot. Apple and the existing OpenAI vector use a 23pt primary-color mark; other provider assets use a 24pt image on a white 32pt badge with 8pt corners. Preserve original brand colors. Social sharing moves from the sidebar to About, retaining the existing word-milestone eligibility.

Insights Session Vocabulary

App/model rankings count one saved, non-deleted dictation record as one session within the selected date range, including synced dictations. Duration and streaming chunks do not multiply the count. Meetings, Quill, and computer-use records are excluded from these rankings. Rank by session count, then word count.

Known counting inconsistency: the overview's Dictation sessions total uses the broader history cache, which still includes saved Quill/computer-use records. This reference documents current behavior; this PR does not change the aggregation policy.

muesli design language system · PR #584 · October 8, 2026

Source of truth: MuesliTheme.swift · FloatingIndicatorController.swift · SidebarView.swift