# Conduit UI — Before / After

Component mockups showing current inconsistencies alongside the proposed standardized versions from `docs/ui-font-spacing-audit.md`. Each section isolates a specific problem area.

01 Font Size Scale

The current UI uses 18 distinct font sizes. The proposed scale reduces this to 7 well-defined stops. Sizes shown at actual rendered pixels (root = 13px).

Before — 18 sizes
8px Thumbnail name PastePreview
9px ESC · date groups SubagentBackBar, SessionList
9.75px text-xs — metadata, stats, hints ~30 components
10px Instance badge, context %, version ~12 components
11px Code headers, gutters, provider headers ~17 components
11.375px text-sm — buttons, instructions ~25 components
12px Variant options, add input ModelSelector, ProjectSwitcher
13px text-[13px] — body text, menu items ~30 components
13px text-base — textarea (same px!) InputArea
14px plan-mode.css plan banners PlanMode
14.6px text-lg — settings title, step title SettingsPanel, StepHeader
15px Project name in header Header
16px Dashboard project card name DashboardPage
16.25px text-xl — "All set!" heading StepDone
19.5px text-2xl — dashboard title DashboardPage
22px Setup / Pin page title SetupPage, PinPage
3 sizes compete for "small text" (9.75, 10, 11px).
text-[13px] and text-base are identical but used separately.
4 sizes for page headings (16, 16.25, 19.5, 22px).
After — 7 stops
10px Badges, thumbnails, tiny labels text-[10px]
11px Metadata, section headers, gutters text-[11px]
13px Body text, menu items, UI text text-[13px]
15px Section headings, project name text-[15px]
20px Page titles (secondary) text-xl
24px Page titles (primary) text-2xl
39px Display / decorative text-5xl
Consolidates 8px, 9px, 9.75px → 10px.
Consolidates text-xs, text-[10px], text-[11px] → text-[10px] + text-[11px] with clear roles.
Consolidates text-sm, text-[13px], text-base → text-[13px] as the single body size.
Consolidates text-lg, text-[15px], text-[16px] → text-[15px].
02 Chat Messages

Messages are mostly consistent already. The main issue is `leading-[1.7]` vs `leading-[1.55]` for thinking blocks, and the body text using `text-[13px]` while the textarea uses `text-base`.

Before
You

Can you refactor the authentication module to use JWT tokens instead of session cookies?

Assistant

I'll refactor the auth module. Let me start by examining the current implementation.

Thinking...
I need to check if there are any existing JWT utilities in the codebase and understand the session cookie implementation...
Thinking streaming uses leading-[1.55] but expanded thinking uses leading-[1.7].
Body text is text-[13px] but InputArea textarea is text-base (same px, different class).
After
You

Can you refactor the authentication module to use JWT tokens instead of session cookies?

Assistant

I'll refactor the auth module. Let me start by examining the current implementation.

Thinking...
I need to check if there are any existing JWT utilities in the codebase and understand the session cookie implementation...
Thinking uses leading-[1.7] in both streaming and expanded states.
All body text uses text-[13px] exclusively (drop text-base alias).
03 Uppercase Section Headers

The "uppercase semibold" section header is a core pattern used across the sidebar, dropdowns, and settings. Currently 5+ variations exist with different font sizes and tracking values.

Before — 5+ variations
SessionList "Sessions"
SESSIONS
SessionList date groups
TODAY
ProjectSwitcher instance headers
LOCALHOST:4096
SettingsPanel appearance
DARK
SettingsPanel instances
2 INSTANCES
StepHeader counter
STEP 1 OF 4
ModelSelector providers
ANTHROPIC
SidebarFilePanel
FILE BROWSER
Sizes: 9px, 9.75px, 10px, 11px.
Tracking: 0.3px, 0.5px, 0.05em, 0.1em, 1px.
Weights: 500 vs 600.
After — 2 tiers
Primary headers (sections, panels, providers)
SESSIONS
ANTHROPIC
FILE BROWSER
DARK
2 INSTANCES
STEP 1 OF 4
LOCALHOST:4096
Secondary headers (date groups, sub-sections)
TODAY
YESTERDAY
Primary: 11px / 600 / 0.5px — used for all panel/section/provider headers.
Secondary: 10px / 600 / 0.5px — used only for date groups and sub-categories.
All use font-semibold (never font-medium for headers).
04 Button Tiers

Currently, buttons use 4+ different size/weight/padding combinations for similar roles. The proposal standardizes to 3 tiers.

Before — inconsistent sizing
Setup CTA buttons
text-sm (11.375px) · font-semibold · px-6 py-3
Permission/Question action buttons
text-sm · font-medium · px-4 py-2 min-h-[48px]
Modal action buttons
text-[13px] · font-medium · py-1.5 px-4
Plan approval buttons (CSS, not Tailwind)
0.875rem (14px) · 600 · 0.5rem 1.5rem
Instance/small action buttons
text-xs (9.75px) · normal · px-3 py-1
After — 3 standardized tiers
Tier 1 — CTA / Primary
text-[13px] · font-semibold · px-6 py-3 · rounded-[10px]
Tier 2 — Secondary / Modal
text-[13px] · font-medium · px-4 py-2 · rounded-md
Tier 3 — Inline / Small
text-[11px] · font-medium · px-3 py-1.5 · rounded-md
05 Dropdown Menu Items

Dropdown items vary in font size and padding across CommandMenu, FileMenu, ModelSelector, ProjectSwitcher, SessionContextMenu, and Header dropdowns.

Before — 6 variations
CommandMenu / FileMenu
/compact Toggle compact mode
/theme Change theme
py-2 px-3.5
ModelSelector
claude-sonnet-4-20250514 ✓
gpt-4o
py-1.5 px-3.5
ProjectSwitcher
conduit
my-app
px-3 py-2.5
Header instance dropdown
localhost:4096
text-xs · px-3 py-1.5 (different size!)
Vertical padding ranges from py-1.5 to py-2.5.
Horizontal padding: px-3 vs px-3.5.
Header dropdown uses text-xs while all others use text-[13px].
After — unified item pattern
CommandMenu / FileMenu
/compact Toggle compact mode
/theme Change theme
py-2 px-3.5 text-[13px]
ModelSelector
claude-sonnet-4-20250514 ✓
gpt-4o
py-2 px-3.5 text-[13px]
ProjectSwitcher
conduit
my-app
py-2 px-3.5 text-[13px]
Header instance dropdown
localhost:4096
py-2 px-3.5 text-[13px] — matches all others
Every dropdown item: py-2 px-3.5 text-[13px] gap-2.
Font family varies by context (mono for code, brand for UI) — that's intentional, not a bug.
06 Sidebar Components

Sidebar horizontal padding varies (`px-1` through `px-3.5`) across different sections. Brand font is applied via inline style everywhere.

Before
Horizontal padding: header px-3, switcher px-1, actions px-2.5, sessions px-2, footer px-3.5.
Brand font applied via style="font-family:..." on every element.
After
All sidebar sections use px-2.5 as the container padding.
Inner items remain py-1.5 px-2.5 for action buttons and session items.
Brand font via font-brand Tailwind class (not inline style).
Brand name: text-[11px] (was text-sm / 11.375px — negligible visual change, consistent scale).
07 Tool Items & Result Areas

ToolItem uses different padding and max-height for its result area vs SkillItem and ToolGroupItem.

Before
ToolGroupItem / SkillItem result
$ npm run build > conduit@0.8.2 build > vite build vite v6.0.0 building for production... ✓ 142 modules transformed. dist/index.html 0.42 kB │ gzip: 0.27 kB dist/assets/index-DfKg4.js 285.42 kB │ gzip: 82.1 kB
py-2 px-2.5 max-h-[300px]
ToolItem generic result (different!)
$ npm run build > conduit@0.8.2 build > vite build vite v6.0.0 building for production... ✓ 142 modules transformed. dist/index.html 0.42 kB │ gzip: 0.27 kB dist/assets/index-DfKg4.js 285.42 kB │ gzip: 82.1 kB
py-3 px-4 max-h-[200px] — larger padding, smaller max-height
Same visual role, different padding (8/10 vs 12/16) and max-height (300 vs 200).
After
All tool result areas (unified)
$ npm run build > conduit@0.8.2 build > vite build vite v6.0.0 building for production... ✓ 142 modules transformed. dist/index.html 0.42 kB │ gzip: 0.27 kB dist/assets/index-DfKg4.js 285.42 kB │ gzip: 82.1 kB
py-2 px-2.5 text-[11px] max-h-[300px]
Same pattern everywhere
Read file: src/lib/auth.ts (42 lines) 1: import { sign, verify } from 'jsonwebtoken'; 2: import type { JWTPayload } from './types'; 3: 4: export function createToken(payload: JWTPayload) { 5: return sign(payload, process.env.JWT_SECRET!);
py-2 px-2.5 text-[11px] max-h-[300px] — identical to above
Unified: py-2 px-2.5 max-h-[300px] text-[11px] font-mono for all tool results.
Text size bumped from text-xs (9.75px) to text-[11px] for readability.
08 Line-Height Tiers

Currently 10 distinct line-height values. The proposal reduces to 4 semantic tiers.

Before — 10 values
The quick brown fox jumps over the lazy dog. This text demonstrates leading-none, used on close buttons and badges.
The quick brown fox jumps over the lazy dog. This text demonstrates leading-[1.2], used only on PastePreview thumbnail names.
The quick brown fox jumps over the lazy dog. This text demonstrates leading-[1.3], used on TodoOverlay descriptions and md-content headings.
The quick brown fox jumps over the lazy dog. This text demonstrates leading-[1.4], used on InputArea textarea, ModelSelector items, and TodoOverlay subjects.
The quick brown fox jumps over the lazy dog. This text demonstrates the root default line-height of 1.5, inherited by most elements.
The quick brown fox jumps over the lazy dog. This text demonstrates leading-[1.55], used on ThinkingBlock streaming, FileViewer code, and md-content pre code.
The quick brown fox jumps over the lazy dog. This text demonstrates leading-relaxed (1.625), used on setup instructions and DebugPanel.
The quick brown fox jumps over the lazy dog. This text demonstrates leading-[1.7], used on AssistantMessage body, UserMessage body, and PlanMode markdown.
1.2, 1.3, 1.4, 1.5, 1.55, 1.625, 1.7 all used for body-like text.
After — 4 tiers
Badges, close buttons, status indicators.
The quick brown fox jumps over the lazy dog. Menu items, form inputs, todo subjects, model selector items, dropdowns — all interactive UI text.
The quick brown fox jumps over the lazy dog. Code blocks, file viewer, thinking blocks (streaming and expanded), tool results — monospaced content.
The quick brown fox jumps over the lazy dog. Chat message bodies, markdown content, setup instructions, plan mode text — anything meant to be read as prose.
leading-none — compact/badges.
leading-[1.4] — UI elements (absorbs 1.2, 1.3, 1.4).
leading-[1.55] — code/mono content (absorbs 1.5, 1.55).
leading-[1.7] — prose (absorbs 1.625, 1.7).
09 Letter-Spacing

Uppercase section headers alone use 5+ different tracking values. Brand text uses two different values.

Before — mixed tracking
0.3px TODAY SessionList date
0.5px SESSIONS SessionList
0.05em DARK ThemePicker (scoped)
0.1em DARK Settings appearance
1px STEP 1 OF 4 StepHeader
1.5px ASSISTANT Role labels
0.08em conduit Header project
0.14em conduit Sidebar brand
After — 3 tracking values
Uppercase headers — tracking-[0.5px]
0.5px TODAY
0.5px SESSIONS
0.5px DARK
0.5px STEP 1 OF 4
Role labels — tracking-[1.5px]
1.5px ASSISTANT
1.5px YOU
Brand text — tracking-[0.14em]
0.14em conduit
0.14em conduit
0.5px — all uppercase section headers.
1.5px — role labels (wider to distinguish from headers).
0.14em — brand text (em-based, scales with font size).
10 Gap Scale

Gaps currently range from `gap-px` to `gap-4` with 10+ distinct values. The proposal defines 4 semantic tiers.

Before — 10+ gap values
gap-px
Sidebar actions
gap-0.5
SidebarFilePanel btns
gap-[2px]
AgentSelector, ModelSelector
gap-1
InputArea, SessionItem
gap-1.5
ThinkingBlock, ToolItem subtitle
gap-2
Header, Sidebar, ToolItem, ~20 more
gap-2.5
Tool headers, InputArea attach
gap-3
DiffView stats, ConnectOverlay
gap-4
SettingsPanel cards, QrModal
gap-px, gap-0.5, gap-[2px] are visually indistinguishable. gap-1.5 and gap-2 compete for "standard row" spacing. gap-2.5 and gap-3 compete for "spacious" spacing.
After — 4 semantic tiers
gap-1
Tight — inline badges, icon+label, sidebar actions
gap-2
Standard — flex rows, headers, dropdowns, tool headers
gap-3
Spacious — card sections, settings rows
gap-4
Wide — page sections, dialogs
gap-px, gap-0.5, gap-[2px] → gap-1.
gap-1.5, gap-2 → gap-2 (standard).
gap-2.5, gap-3 → gap-3 (spacious).
gap-4 stays.
11 Modal Dialogs

Modal body text and button sizing differ between ConfirmModal, RewindBanner, and QrModal.

Before
ConfirmModal / RewindBanner

Are you sure you want to delete this session? This action cannot be undone.

Body: text-sm (11.375px) · Buttons: text-[13px] py-1.5 px-4
QrModal

## Share via QR Code

Title: text-base (13px) · URL button: text-sm (11.375px)
Body text: text-sm vs title text-base — only 1.6px difference.
Padding: py-5 px-6 vs p-6.
URL button uses text-sm, main buttons use text-[13px].
After
ConfirmModal / RewindBanner

Are you sure you want to delete this session? This action cannot be undone.

Body: text-[13px] leading-[1.4] · Buttons: Tier 2 — text-[13px] py-2 px-4
QrModal

## Share via QR Code

Title: text-[15px] — clear hierarchy. URL: Tier 2 button.
All modals: py-5 px-6 padding, text-[13px] body, text-[15px] title.
All buttons follow Tier 2 pattern.
• Summary of Changes

Property | Before (count) | After (count) | Reduction
--- | --- | --- | ---
Font sizes | 18 values | 7 values | -61%
Line-heights | 10 values | 4 tiers | -60%
Letter-spacings | 11 values | 3 values | -73%
Section header variants | 9 variants | 2 tiers | -78%
Button patterns | 5+ patterns | 3 tiers | -40%
Dropdown item patterns | 6 patterns | 1 pattern | -83%
Gap values | 10+ values | 4 tiers | -60%
Inline font-family styles | 30+ instances | 0 (use font-brand class) | -100%