Agentdeck Design System

Agentdeck's surface is split into two moods. The marketing site is a bold, unapologetically monospace experience over a warm off-white palette. The native macOS product is a three-panel dark workspace that manages parallel AI coding agents. Green is the only bright color allowed in either surface — it signals ready-to-merge state on a pill and a solid Merge button.

Source: · Platform: Next.js website + SwiftUI macOS app · Theme: warm off-white / warm dark

Design Principles

Monospace as identity. Marketing and app both use system monospace (SF Mono / Menlo) for body, headings, buttons, everything. The only exception is the pixel-mono hero wordmark.

Warm, not neutral. Every grey leans brown. Backgrounds: #fafaf9, #f8f7f6, #f0edea. Text: #2c2826, #795f5d, #8e8885. Dark surfaces: #141110, #1a1614, #211e1c.

Green = ready. #00c758 is reserved for success, merge, and version-bump pills. Red #fb2c36 is only used for diff-removes and error pills. Everything else stays in the warm-grey family.

Key Tokens

Primary Text#2c2826
Primary Button BG#2c2826
Border#eae8e6
Tip / Cream Surface#f8f7f6 / #f0edea
App Deep Surface#141110
App Panel / Row#1a1614 / #211e1c
Success / Merge#00c758
Font Stackui-monospace, SF Mono, Menlo
Base Spacing4px
Default Radius6px (marketing) / 4–6px (app)

Colors

The system is built around a warm off-white palette for the marketing site and a warm-charcoal palette for the app. Both share the same success green and error red.

Website — Core

#ffffff
background
#fafaf9
muted / secondary
#f8f7f6
tip-bg
#f3ece7
tip-border
#f0edea
cream
#eae8e6
border

Website — Text

#2c2826
foreground
#413030
primary
#7d5e59
tip-fg
#795f5d
text-secondary
#8e8885
muted-fg
#a5a09c
subtle
#a4847f
warm-tan

App — Surfaces

#0e0b0a
code-bg
#141110
surface-deep
#1a1614
surface-panel
#211e1c
surface-row
#241916
chat-user
#2a2624
hover
#332e2b
active
#2c2826
border
#3a3533
border-muted

App — Text

#f3f2f1
text-primary
#a5a09c
text-body
#795f5d
text-muted
#a4847f
text-accent

Semantic (shared)

#00c758
success / merge
#fb2c36
error / diff-del
#3080ff
info
#e0a060
working / conflict

App — Status Dots

Idle
#a5a09c
Working
#e0a060
Ready to merge
#00c758
Error
#fb2c36
Merge conflict
#e0a060

Typography

System monospace, everywhere. No proportional sans. The hero wordmark is a custom pixel-grid graphic — not a font — that mimics chunky monospace blocks.

Font Families

Primaryui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace
Mono(same stack)

Font Weights

Regular400
Medium500
Semibold600
Bold700

Website Scale

H1 — Run a team of coding agents on your Mac.
Size20px / 28px
Weight700
Tracking-0.5px
H2 / H3 — We built Agentdeck using Agentdeck.
Size14px / 20px
Weight600
Body Large — The quick brown fox jumps over the lazy dog.
Size16px / 24px
Weight400
Body — The quick brown fox jumps over the lazy dog.
Size14px / 20px
Weight400
Small — The quick brown fox jumps over the lazy dog.
Size12px / 16px
Weight400
Caption — Section Header
Size12px / 16px
Tracking0.05em
CaseUPPER

App Scale (compact)

titleBar / rowTitle / chatBody13px / 18-20px / 500
panelHeader12px / 16px / 600 / UPPER +0.05em
rowSubtitle / diffCount / pill11px / 14px / 400-600
tabLabel / code12px / 16-18px / 400-500

Spacing

4px base unit. Tailwind's default 0.25rem spacing grid. Most interior padding is in the 8-24px range; sections on the marketing site breathe at 96px vertical on desktop, 48px on mobile.

xxs
4px
xs
8px
sm
12px
md
16px
lg
20px
xl
24px
2xl
32px
3xl
48px
4xl
64px
5xl
96px

Layout Dimensions

Website header height101px (with announcement bar); 65px nav only
Website content max64rem
App toolbar height44px
App left sidebar width232px
App right panel width~360px
App workspace row height52px
App compact row (file diff)28px

Borders & Shadows

Hairline 1px borders throughout, in warm neutrals (light mode) or warm charcoals (app). Radii are small and restrained: 2-12px. Shadows are barely-there on the marketing site and heavy on the app window.

Radius

2pxxs
4pxsm
6pxmd (default buttons)
8pxlg (default cards)
10pxxl (app window)
12px2xl
pill9999px

Shadows (website)

card0 1px 2px rgba(44,40,38,.04)
popover0 8px 24px rgba(44,40,38,.08)

Shadows (app)

window0 24px 48px rgba(0,0,0,.45)
focus0 0 0 2px rgba(0,199,88,.35)

Website — Announcement Bar

Thin black bar above the primary header. Single line of centered mono text, usually a news or launch update.

We've raised a $22m Series A →
Background#000000
Foreground#ffffff
Height36px
Text14px / 500 / mono / centered

Website — Buttons

The primary button is near-black on white with a 6px radius. A "strong" variant bumps the weight to 700 and swaps padding for a more vertical shape. Secondary is the same shape in a white fill with a hairline border. All buttons are monospace.

Variants

Specs

Primarybg #2c2826, fg #fff, radius 6px, 12px 16px, 14px / 500
Primary Strongsame colors, 16px 12px, 14px / 700
Secondarybg #fff, fg #2c2826, 1px #eae8e6, radius 6px, 12px 16px
Ghosttransparent, fg #2c2826, hover color #8e8885
Inline kbd chipbg rgba(255,255,255,.12), radius 4px, 2px 6px, 11px / 500

Website — Inputs

Text inputs use a 6px radius, 1px warm border, and a soft focus ring in the foreground color.

Background#ffffff
Border1px solid #eae8e6
Padding10px 12px
Radius6px
Focus ring0 0 0 3px rgba(44,40,38,0.08)

Website — Cards & Pills

Plain cards are white with a hairline border. The distinctive "tip" card carries a warm cream background (#f8f7f6) with a slightly warmer border (#f3ece7). Pills are always fully rounded.

Tip Card

Agentdeck signs in using your existing Claude Code and OpenAI keys — no separate account required. API usage is billed to the key you provide.

Pills

v0.48.5 Ready to merge Coming soon
Success pillbg rgba(0,199,88,0.1), fg #00c758, radius 9999px, 2px 8px, 12px / 500
Neutral pillbg #fafaf9, fg #8e8885

Website — Hero Pattern

Pixel-mono wordmark floats centered above a 20px/700 H1. Below that, a muted body paragraph, then two buttons side by side: primary solid + secondary outline. A ghost "See what's new" link with an arrow sits above the wordmark.

See what's new in 0.48.5 →
[ A g e n t d e c k ]

Run a team of coding agents on your Mac.

Create parallel Codex + Claude Code agents in isolated workspaces. See at a glance what they're working on, then review and merge their changes.

App — Window Shell

Rounded 10px window. Standard macOS traffic-lights top-left. Single-line title bar in the muted text color. A heavy drop shadow lifts the window off the desktop.

Agentdeck — workspaces / kampala-v3
All changes 18
Debugging ReferenceError
Review branch changes
archive-in-repo-details / kampala-v3 · Open PR #432 Ready to merge
ReferenceError: Can't find variable: useDefaultOpenInApp in @RepositoryDetailsDialog.tsx
Perfect — I added the missing imports. Now let me run the validation to make sure everything compiles correctly.
13 tool calls, 7 messages.
Changes 18Review
src/App.tsx+3-5
src/core/deck/WorkspaceAPI.ts+23-1
src/ui/components/FileBadge.tsx+2-2
src/ui/components/RepositoryDetailsDialog.tsx+63-47
src/ui/components/ToolRenderers.tsx+45-21
src/ui/components/git/GitDiffFileHeader.tsx+17-3
src/hooks/useWorkspaceContext.ts+11-1

App — Left Sidebar

232px wide. Grouped by top-level section (workspace / personal). Each section header is a muted-brown UPPER caption. The "+ New workspace" action is inline below the header, in the body text color.

workspaces
+ New workspace
archive-in-repo
Ready to merge
+12-3
working-branch
Running tests…
+4

App — Workspace Row

The signature component of the app. A single row communicates: live agent state (dot color), name (branch or task), sub-status phrase, and the delta size of its pending changes. The active row adds a 2px left border in the body text color and lifts its background to the row tone.

Padding8px 12px
Min height52px
Grid[dot 12px] [body 1fr] [diff auto]
Dot size8px (radius 9999px)
Title13px / 500 / #f3f2f1
Subtitle11px / 400 / #795f5d, 2px top gap
Diff add11px / 500 / #00c758
Diff remove11px / 500 / #fb2c36
Active bg#211e1c with 2px left border #a5a09c
Hover bgrgba(243,242,241,0.04)

App — Tabs & Breadcrumb

Active review sessions live as tabs under a branch breadcrumb. Active tab gets a 2px bottom border in the primary text color. The breadcrumb uses slash separators between segments and pushes status pill + Merge button to the right.

All changes 18
Debugging ReferenceError
Review branch changes
archive-in-repo-details / kampala-v3 · Open PR #432 Ready to merge

App — Chat Surface

User messages are bubbles with a slightly warmer red-leaning charcoal background and a hairline border; assistant output is unboxed over the panel tone. Inline file mentions (@path/to/file.tsx) are rendered in warm-tan on a soft tint.

ReferenceError: Can't find variable: useDefaultOpenInApp in @RepositoryDetailsDialog.tsx
cool works now — i was thinking it could be nice to use a version of @command.tsx in @RepositoryDetailsDialog.tsx instead of trying to reinvent the wheel of searching/navigating with keyboard.
Perfect. The returning is consistent — let me summarize what was done.
User bubblebg #241916, 1px #3a3533, radius 6px, padding 10px 12px, 13px
Assistantbg #1a1614, no border, radius 6px, padding 10px 12px, 13px / #a5a09c
Mentioncolor #a4847f, bg rgba(164,132,127,0.15), 3px radius
Strong emphasiscolor #f3f2f1, weight 600

App — File Diff Rows

28px compact rows. Directory prefix in the muted-brown, filename in body color, add/remove counts right-aligned in green/red. Hovering lightens the row 4%.

Changes 18Review
src/App.tsx+3-5
src/core/deck/WorkspaceAPI.ts+23-1
src/ui/components/FileBadge.tsx+2-2
src/ui/components/ToolRenderers.tsx+45-21
src/hooks/useWorkspaceContext.ts+11-1

App — Buttons, Pills & Toggles

The only saturated control in the app. Merge is the solid success button; the matching status pill uses the same green at 20% alpha.

Ready to merge Merge conflicts

Specs

Merge buttonbg #00c758, fg #fff, radius 4px, 5px 12px, 12px / 600
Danger buttonbg rgba(251,44,54,0.12), fg #fb2c36, radius 4px, 5px 12px
Ghost toolbartransparent, fg #a5a09c, hover bg rgba(243,242,241,0.06), hover fg #f3f2f1
Success pillbg rgba(0,199,88,0.2), fg #00c758, radius 4px, 2px 8px, 11px / 600
Toggle (off)bg #3a3533, thumb #f3f2f1
Toggle (on)bg #00c758

App — Status Dots

A colored 8px dot communicates the live state of every workspace. The working dot pulses opacity 1.2s infinite; others are solid.

Idle
#a5a09c
Working (pulses)
#e0a060
Ready to merge
#00c758
Error
#fb2c36
Merge conflict
#e0a060

App — Code Block

Deep black-coffee background under the panel surface. Line numbers in border-muted, code in primary text. Added lines tint at 8% success green; removed lines at 8% error red.

42function useDefaultOpenInApp() {
43- return openInTerminal;
44+ const { preference } = useSettings();
45+ return preference === 'editor' ? openInEditor : openInTerminal;
46}
Background#0e0b0a
Border1px solid #2c2826
Radius6px, padding 12px
Font12px / 18px mono
Line number#3a3533
Add row bgrgba(0,199,88,0.08)
Remove row bgrgba(251,44,54,0.08)

App — PR Status Bar

Rail at the top of the right panel. Its background color shifts with workflow state — dusty-pink when there are uncommitted changes, saturated-green when the PR is ready to merge. The phrase text inside uses the sans family; the PR number pill and tab strip below it use monospace.

State — Uncommitted
PR #2198 ↗ Uncommitted changes ↻ Commit and push
Changes 3 All files Checks ◉ Review
State — Ready to merge
PR #64 ↗ Ready to merge ◉ Review
Changes 1 All files Deployments 1
Height52px header + 36px tab strip
Font familysans for phrase text, mono for PR pill / tabs / button label
Uncommitted bg#3a2e2a
Ready bg#0e2b18 (dark green tint)
Merge buttonsolid #00c758 / #fff, 6px radius, 6px 14px, 12px / 600

App — Checks & Git Status

Beneath the PR bar, two stacked sections. Git status surfaces the count of uncommitted / behind-main commits with inline actions. The checks list shows CI state per check with a circular indicator.

Git status
1 uncommitted change Commit and push
14 commits behind main Pull
Checks
review2m ↗
lint1m ↗
format44s ↗
build-main1m ↗
build-sidecar22s ↗
validate2s ↗
Indicator in-progress#e0a060 spinner
Indicator passed#00c758 check
Indicator queued#3a3533 ring
Indicator failed#fb2c36 ×
Row height28px
Duration color#795f5d

App — Model Picker

Dropdown anchored to the model chip under the chat input. Rows are sans-serif (human names), keyboard numbers on the right give a quick-pick. NEW badge uses warm-tan text on a warm-tan tint.

Codex
GPT-5.4 NEW 4
GPT-5.3-Codex-Spark 5
GPT-5.3-Codex 6
Claude
Opus 4.7 1M 1
Row fontsans, 14px / 500 / #f3f2f1
Row height36px
Active background#3a2e2a (warm pink-brown)
Keyboard numbermono 12px / #795f5d
NEW badgemono 10px uppercase, bg rgba(164,132,127,0.25), color #a4847f

App — Terminal Preset Modal

Opened when creating a new terminal tab. Each row pairs a bold sans-serif agent name with the monospace command it auto-runs. The active preset takes the warm pink-brown tint + warm-tan border.

New tab preset
Command to auto-run when creating a new terminal tab.
Claude claude --dangerously-skip-permissions
Codex codex -c model_reasoning_effort="high" --sandbox danger-full-access
OpenCode opencode
Gemini gemini -y
None

App — MCP Status Dialog

Each MCP server is a full-width pill with a colored status icon on the left, mono UPPERCASE name, and optional muted suffix. The footer row is two sans-serif links separated by flex space.

MCP status
Refresh to check current server status.
PAPER
CLAUDE.AI GOOGLE DRIVE (NEEDS AUTH)
CLAUDE.AI GMAIL
↻ Refresh status ↗ Read the MCP docs

App — Submit-Prompt Dialog

The general modal pattern. Big sans title, muted sans subtitle, sans field label, sans textarea with a warm-pink focus border, primary button with an inline keyboard hint.

Submit a prompt
Prompt a coding agent to build what you want to see in Agentdeck. If we like your prompt, we'll run it and merge the result.
Prompt
Describe what you'd like to see built…

App — Chat Input & Chips

Multi-line textarea with a dashed warm-pink border on focus. Underneath: four chip controls for model, speed, reasoning effort, and mode. Each chip is monospace, pill-rounded with a hairline border, tinted warm pink-brown when active.

Ask to make changes, @mention files, run /commands
◌ GPT-5.4 ⚡ Fast 🧠 Medium 🗺 Plan
Focus border1px dashed rgba(164,132,127,0.8)
Placeholdermono 13px / #795f5d
Chip activeborder 1px #a4847f, bg #3a2e2a
Chip idleborder 1px #3a3533, bg transparent
Chip fontmono 12px / 500 / #f3f2f1
Speed valuesFast / Balanced / Careful
Effort valuesLow / Medium / High / Extra high
Mode valuesPlan / Act / Vibe

App — Persona Picker

Dropdown above the chat input. Each row is bold sans name + muted sans description. The current persona is highlighted with the warm pink-brown tint.

Default
FriendlyWarm, collaborative, and helpful
PragmaticConcise, task-focused, and direct

App — Onboarding / Survey Card

Used for first-run preferences and in-app polls. Sans question heading, ranked list of options with a rank number + checkbox, pagination dots, and an arrow submit button.

Which programming languages do you use most?
1JavaScript/TypeScript
2Python
3Go
4Rust

App — File Tree & Attachments

Collapsible folder tree inside the left sidebar. File rows show a type icon + monospace filename. Hover reveals a sans-serif "Attach to chat" floating button plus inline + and options.

📁.context
📁attachments
📄[LINEAR]-CON-498.md Attach to chat +

Tailwind Mapping Reference

This design system ships a tailwind section inside the paired design-system.json. Extend your Tailwind config's theme.extend with the mapping below, then use the component recipes to build screens that match the reference.

Tokens (paste into tailwind.config.js)

theme: {
  extend: {
    colors: {
      deck: {
        bg:        '#ffffff',
        fg:        '#2c2826',
        primary:   '#413030',
        primaryFg: '#f3f2f1',
        muted:     '#fafaf9',
        mutedFg:   '#8e8885',
        border:    '#eae8e6',
        cream:     '#f0edea',
        tipBg:     '#f8f7f6',
        tipBorder: '#f3ece7',
        tipFg:     '#7d5e59',
      },
      app: {
        deep:        '#141110',
        panel:       '#1a1614',
        row:         '#211e1c',
        hover:       '#2a2624',
        active:      '#332e2b',
        chatUser:    '#241916',
        border:      '#2c2826',
        borderMuted: '#3a3533',
        fg:          '#f3f2f1',
        body:        '#a5a09c',
        muted:       '#795f5d',
        accent:      '#a4847f',
      },
      status: {
        success: '#00c758',
        error:   '#fb2c36',
        info:    '#3080ff',
        warning: '#e0a060',
      },
    },
    fontFamily: {
      sans: ['ui-monospace', 'SFMono-Regular', '"SF Mono"', 'Menlo', 'Consolas', 'monospace'],
      mono: ['ui-monospace', 'SFMono-Regular', '"SF Mono"', 'Menlo', 'Consolas', 'monospace'],
    },
    fontSize: {
      xs:   ['11px', { lineHeight: '14px' }],
      '2xs': ['12px', { lineHeight: '16px' }],
      sm:   ['13px', { lineHeight: '18px' }],
      body: ['14px', { lineHeight: '20px' }],
      lg:   ['16px', { lineHeight: '24px' }],
      h1:   ['20px', { lineHeight: '28px', letterSpacing: '-0.025em', fontWeight: '700' }],
    },
    spacing: {
      xxs: '2px', xs: '4px', sm: '8px', md: '12px',
      lg: '16px', xl: '20px', '2xl': '24px', '3xl': '32px',
      '4xl': '48px', '5xl': '64px', '6xl': '96px',
    },
    borderRadius: { xs: '2px', sm: '4px', md: '6px', lg: '8px', xl: '10px', pill: '9999px' },
    boxShadow: {
      card:    '0 1px 2px rgba(44,40,38,0.04)',
      popover: '0 8px 24px rgba(44,40,38,0.08)',
      window:  '0 24px 48px rgba(0,0,0,0.45)',
      focus:   '0 0 0 2px rgba(0,199,88,0.35)',
    },
  },
}

Component Recipes

Marketing site:

siteButtonPrimary:    "inline-flex items-center justify-center gap-2 rounded-md bg-deck-fg text-white font-mono font-medium text-body px-4 py-3 hover:bg-black transition-colors"
siteButtonSecondary:  "inline-flex items-center justify-center gap-2 rounded-md bg-white text-deck-fg border border-deck-border font-mono font-medium text-body px-4 py-3 hover:bg-deck-muted"
siteAnnouncementBar:  "h-9 flex items-center justify-center bg-black text-white font-mono text-body font-medium"
siteCard:             "rounded-lg bg-white border border-deck-border p-2xl"
siteTipCard:          "rounded-lg bg-deck-tipBg border border-deck-tipBorder p-lg text-deck-tipFg font-mono text-body"
siteInput:            "w-full rounded-md border border-deck-border bg-white px-md py-2.5 font-mono text-body text-deck-fg placeholder:text-deck-mutedFg focus:outline-none focus:ring-2 focus:ring-deck-fg/10"
sitePillSuccess:      "inline-flex items-center rounded-pill bg-status-success/10 text-status-success font-mono text-xs font-medium px-2 py-0.5"

App / portal:

appWindow:             "rounded-xl bg-app-deep border border-app-border shadow-window overflow-hidden"
appSidebar:            "w-[232px] bg-app-deep border-r border-app-border py-2 overflow-y-auto"
appWorkspaceRow:       "flex items-start gap-sm px-md py-2 min-h-[52px] border-l-2 border-transparent hover:bg-white/[0.04] data-[active=true]:bg-app-row data-[active=true]:border-l-app-body cursor-pointer"
appStatusDot:          "w-2 h-2 rounded-full mt-1.5 shrink-0"
appRowTitle:           "font-mono text-sm font-medium text-app-fg truncate"
appRowSubtitle:        "font-mono text-xs text-app-muted mt-0.5 truncate"
appDiffAdd:            "font-mono text-xs font-medium text-status-success"
appDiffRemove:         "font-mono text-xs font-medium text-status-error"
appTabBar:             "h-10 flex items-center border-b border-app-border bg-app-deep"
appTab:                "h-full px-3.5 flex items-center font-mono text-xs font-medium text-app-muted hover:text-app-fg border-b-2 border-transparent data-[active=true]:text-app-fg data-[active=true]:border-app-fg"
appChatUser:           "rounded-md bg-app-chatUser border border-app-borderMuted px-3 py-2.5 font-mono text-sm text-app-fg max-w-[640px]"
appChatAssistant:      "rounded-md bg-app-panel px-3 py-2.5 font-mono text-sm text-app-body"
appMergeButton:        "inline-flex items-center gap-1.5 rounded-sm bg-status-success text-white font-mono text-2xs font-semibold px-3 py-1 hover:brightness-110 transition"
appStatusPillSuccess:  "inline-flex items-center rounded-sm bg-status-success/20 text-status-success font-mono text-xs font-semibold px-2 py-0.5"
appFileDiffRow:        "flex items-center justify-between gap-md px-md h-7 hover:bg-white/[0.04] font-mono text-2xs text-app-body cursor-pointer"
appCodeBlock:          "rounded-md bg-[#0e0b0a] border border-app-border p-md font-mono text-2xs leading-[18px] text-app-fg"

The exported JSON also contains the full list of recipes under tailwind.componentRecipes. Treat them as the canonical starting point when implementing new screens.