# 12px Font Rebase Implementation Plan

> **For Agent:** REQUIRED SUB-SKILL: Use executing-plans to implement this plan task-by-task.

**Goal:** Shrink body text from 13px to 12px, override Tailwind v4's `@theme` font-size scale so standard classes (`text-xs`=10px, `text-sm`=11px, `text-base`=12px, `text-lg`=15px, `text-xl`=20px, `text-2xl`=24px) replace all arbitrary `text-[Npx]` values, bump md-content heading multipliers, and replace all inline `font-family: var(--font-brand)` with the `font-brand` Tailwind class.

**Architecture:** Override `--text-*` CSS variables in the existing `@theme {}` block in `style.css`. Change root font-size from 13px to 12px. Then do mechanical find-and-replace of arbitrary Tailwind classes across ~50 component files. Migrate plan-mode.css and style.css rem-based font-sizes to explicit px or Tailwind utilities. Replace inline brand font styles with the `font-brand` utility class.

**Tech Stack:** Tailwind CSS v4 (CSS-first config), Svelte 5, plain CSS

**Verification after each task:**
```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Reference docs:**
- `docs/ui-font-spacing-audit.md` — full audit of current values
- `docs/ui-12px-rebase-mockup.html` — visual mockup of proposed changes

---

### Task 1: Override @theme font-size scale and root font-size

**Files:**
- Modify: `src/lib/frontend/style.css`

**Step 1: Add font-size overrides to @theme block**

In `style.css`, inside the existing `@theme { }` block (which starts around line 5), add the font-size scale overrides after the existing font declarations (after `--font-sans`):

```css
/* ── Font Size Scale (overrides Tailwind defaults) ──── */
--text-xs:              10px;
--text-xs--line-height:  1.4;

--text-sm:              11px;
--text-sm--line-height:  1.4;

--text-base:            12px;
--text-base--line-height: 1.5;

--text-lg:              15px;
--text-lg--line-height:  1.4;

--text-xl:              20px;
--text-xl--line-height:  1.3;

--text-2xl:             24px;
--text-2xl--line-height: 1.2;
```

**Step 2: Change root font-size from 13px to 12px**

At line 195, change:
```css
font-size: 13px;
```
to:
```css
font-size: 12px;
```

**Step 3: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

Expected: All pass. The `@theme` overrides redefine what existing `text-xs`, `text-sm`, `text-base` classes mean — existing usages shift slightly (text-xs: 9.75→10px, text-sm: 11.375→11px, text-base: 13→12px).

**Step 4: Commit**

```bash
git add src/lib/frontend/style.css
git commit -m "feat(ui): override @theme font-size scale, rebase root to 12px"
```

---

### Task 2: Update md-content headings and code sizing

**Files:**
- Modify: `src/lib/frontend/style.css`

**Step 1: Bump heading em multipliers**

At line 470, change `text-[1.35em]` to `text-[1.65em]` (h1: 12px * 1.65 = 19.8px).
At line 473, change `text-[1.2em]` to `text-[1.3em]` (h2: 12px * 1.3 = 15.6px).
At line 476, change `text-[1.1em]` to `text-[1.15em]` (h3: 12px * 1.15 = 13.8px).

**Step 2: Change inline code from 0.87em to 1em**

At line 538, change `text-[0.87em]` to `text-[1em]`:
```css
.md-content code {
    @apply font-mono text-[1em] rounded-[6px] px-[7px] py-[2px];
```

**Step 3: Change pre code from text-[13px] to text-base**

At line 548, change `text-[13px]` to `text-base`:
```css
.md-content pre code {
    @apply block px-[18px] py-4 text-base leading-[1.55] whitespace-pre overflow-x-auto;
```

**Step 4: Change table from text-[13px] to text-base**

At line 554, change `text-[13px]` to `text-base`:
```css
.md-content table {
    @apply my-3.5 text-base w-full;
```

**Step 5: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 6: Commit**

```bash
git add src/lib/frontend/style.css
git commit -m "feat(ui): bump md-content heading multipliers and code sizing for 12px base"
```

---

### Task 3: Migrate plan-mode.css from rem to px

**Files:**
- Modify: `src/lib/frontend/plan-mode.css`

**Step 1: Replace all three 0.875rem font-size declarations**

Line 10 (`.plan-banner`): change `font-size: 0.875rem;` to `font-size: 12px;`
Line 51 (`.plan-card-title`): change `font-size: 0.875rem;` to `font-size: 12px;`
Line 87 (`.plan-approval button`): change `font-size: 0.875rem;` to `font-size: 12px;`

Rationale: These were 11.375px at 13px root (body-tier text). At 12px root they'd become 10.5px which is too small. Setting them to 12px aligns with the new body tier.

**Note:** plan-mode.css also has 15 rem-based spacing values (padding, margin, gap, border-radius) that will shrink ~7.7% when root changes. This is intentional — the slight tightening is acceptable and keeps spacing proportional.

**Step 2: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 3: Commit**

```bash
git add src/lib/frontend/plan-mode.css
git commit -m "fix(ui): migrate plan-mode.css from rem to explicit px for 12px rebase"
```

---

### Task 4: Migrate style.css rem-based font-sizes

**Files:**
- Modify: `src/lib/frontend/style.css`

**Step 1: Replace rem-based font-size values**

These are all small utility text in the diff, rewind, and file-history sections. Replace each with `10px` (aligning with the new text-xs tier):

- Line 928 (`.rewind-timeline-marker`): `font-size: 0.6875rem;` → `font-size: 10px;`
- Line 976 (`.diff-split-view`): `font-size: 0.75rem;` → `font-size: 10px;`
- Line 997 (`.diff-ln`): `font-size: 0.6875rem;` → `font-size: 10px;`
- Line 1062 (`.diff-toggle-btn`): `font-size: 0.75rem;` → `font-size: 10px;`
- Line 1098 (`.file-history-badge`): `font-size: 0.625rem;` → `font-size: 10px;`
- Line 1119 (`.file-history-compare-btn`): `font-size: 0.75rem;` → `font-size: 10px;`

**Note:** style.css also has 19 rem-based spacing values in these sections that will shrink ~7.7% when root changes. This is intentional — the slight tightening is acceptable and keeps spacing proportional.

**Step 2: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 3: Commit**

```bash
git add src/lib/frontend/style.css
git commit -m "fix(ui): migrate style.css rem font-sizes to explicit px for 12px rebase"
```

---

### Task 5: Replace text-[13px] → text-base across all components

**Files to modify (50 instances across ~30 files):**

This is a mechanical find-and-replace. In every `.svelte` file listed below, replace the string `text-[13px]` with `text-base` within Tailwind class attributes.

**Note on JS contexts:** Some matches are inside JavaScript strings (e.g., `document.createElement` className assignments or template literals). These are safe to replace — Tailwind v4 scans all source strings for class names. Notable JS-context instances:
- `AgentSelector.svelte:131` — inside `buildDropdownHTML()` template literal. Safe to replace.
- `AssistantMessage.svelte:175, 182` — inside `document.createElement` className assignments. Safe to replace.

Files with `text-[13px]` (from ripgrep results):

| File | Lines |
|------|-------|
| `components/chat/AssistantMessage.svelte` | 396 |
| `components/chat/UserMessage.svelte` | 24 |
| `components/chat/SystemMessage.svelte` | 21 |
| `components/chat/ThinkingBlock.svelte` | 63, 91 |
| `components/chat/QuestionCard.svelte` | 189 |
| `components/chat/ToolQuestionCard.svelte` | 218 |
| `components/chat/SubagentBackBar.svelte` | (check if any) |
| `components/layout/Sidebar.svelte` | 176, 192, 203, 214 |
| `components/session/SessionItem.svelte` | 80 |
| `components/session/SessionContextMenu.svelte` | 104, 113, 126, 135 |
| `components/model/ModelSelector.svelte` | 90, 169 |
| `components/model/AgentSelector.svelte` | 131 |
| `components/permissions/PermissionNotification.svelte` | 62 |
| `components/permissions/PermissionCard.svelte` | 118 |
| `components/project/ProjectSwitcher.svelte` | 272, 311 |
| `components/shared/ConduitLogo.svelte` | 26 |
| `components/todo/TodoItemRow.svelte` | 27 |
| `components/input/CommandMenu.svelte` | 133, 144 |
| `components/input/FileMenu.svelte` | 112, 118, 144 |
| `components/file/FileViewer.svelte` | 193 |
| `components/file/FileTreeNode.svelte` | 58 |
| `components/overlays/RewindBanner.svelte` | 153, 159 |
| `components/overlays/ConfirmModal.svelte` | 48, 54 |
| `components/overlays/SettingsPanel.svelte` | 324 |
| `components/setup/StatusBox.svelte` | 24 |
| `components/setup/StepPwa.svelte` | 38, 46, 206, 219 |
| `components/setup/StepPush.svelte` | 41, 72 |
| `pages/DashboardPage.svelte` | 157, 166 |
| `pages/SetupPage.svelte` | 292 |
| `pages/PinPage.svelte` | 132 |

All paths are relative to `src/lib/frontend/`.

**Step 1: Run the replacement**

For each file above, replace all occurrences of `text-[13px]` with `text-base`.

**Step 2: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 3: Grep to confirm no remaining instances**

```bash
rg "text-\[13px\]" src/lib/frontend/ --include="*.svelte"
```

Expected: 0 matches (the 2 style.css instances were already handled in Task 2).

**Step 4: Commit**

```bash
git add -u src/lib/frontend/
git commit -m "feat(ui): replace text-[13px] with text-base across all components"
```

---

### Task 6: Replace text-[11px] → text-sm across all components

**Files to modify (38 instances across ~20 files):**

Replace `text-[11px]` with `text-sm` in all `.svelte` files:

| File | Lines |
|------|-------|
| `components/chat/AssistantMessage.svelte` | 175, 182, 395 |
| `components/chat/UserMessage.svelte` | 23 |
| `components/chat/ThinkingBlock.svelte` | 83 |
| `components/chat/SubagentBackBar.svelte` | 42, 47 |
| `components/chat/ToolGenericCard.svelte` | 152 |
| `components/chat/ToolGroupItem.svelte` | 86 |
| `components/chat/DiffView.svelte` | 132, 137, 156, 177 |
| `components/chat/PastePreview.svelte` | 44 |
| `components/session/SessionItem.svelte` | 224 |
| `components/session/SessionList.svelte` | 258, 268, 292 |
| `components/model/ModelSelector.svelte` | 177 |
| `components/project/ProjectSwitcher.svelte` | 194, 206, 230, 358, 364, 372 |
| `components/todo/TodoHeader.svelte` | 34 |
| `components/file/FileViewer.svelte` | 206 |
| `components/file/FileTreeNode.svelte` | 86, 109 |
| `components/file/SidebarFilePanel.svelte` | 126 |
| `components/terminal/TerminalPanel.svelte` | 157, 207, 218, 227 |
| `components/layout/Sidebar.svelte` | 252 |
| `components/debug/DebugPanel.svelte` | 247 |
| `components/setup/StepHeader.svelte` | 20 |
| `pages/DashboardPage.svelte` | 204 |

**Step 1: Run the replacement**

For each file, replace all `text-[11px]` with `text-sm`.

**Step 2: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 3: Grep to confirm**

```bash
rg "text-\[11px\]" src/lib/frontend/ --include="*.svelte"
```

Expected: 0 matches.

**Step 4: Commit**

```bash
git add -u src/lib/frontend/
git commit -m "feat(ui): replace text-[11px] with text-sm across all components"
```

---

### Task 7: Replace text-[10px] → text-xs across all components

**Files to modify (27 instances across ~15 files):**

Replace `text-[10px]` with `text-xs` in all `.svelte` files:

| File | Lines |
|------|-------|
| `components/chat/SubagentBackBar.svelte` | 42, 47 (responsive `max-md:text-[10px]` → `max-md:text-xs`) |
| `components/session/SessionItem.svelte` | 214 |
| `components/model/ModelSelector.svelte` | 201, 208, 216 |
| `components/model/ModelVariant.svelte` | 91, 114, 129, 138 |
| `components/project/ProjectSwitcher.svelte` | 242 |
| `components/todo/TodoItemRow.svelte` | 35, 40 |
| `components/todo/TodoHeader.svelte` | 38 |
| `components/input/ContextBar.svelte` | 19 |
| `components/file/FileTreeNode.svelte` | 91 |
| `components/terminal/TerminalPanel.svelte` | 225 |
| `components/layout/Sidebar.svelte` | 260 |
| `components/layout/Header.svelte` | 127, 232 |
| `components/overlays/SettingsPanel.svelte` | 312, 385 |
| `components/debug/DebugPanel.svelte` | 274, 281, 288 |

**Note on SubagentBackBar:** Lines 42 and 47 have `max-md:text-[10px]` as a responsive override. Replace with `max-md:text-xs`.

**Step 1: Run the replacement**

Replace `text-[10px]` with `text-xs` in all contexts, including inside responsive prefixes like `max-md:text-[10px]` → `max-md:text-xs`.

**Step 2: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 3: Grep to confirm**

```bash
rg "text-\[10px\]" src/lib/frontend/ --include="*.svelte"
```

Expected: 0 matches.

**Step 4: Commit**

```bash
git add -u src/lib/frontend/
git commit -m "feat(ui): replace text-[10px] with text-xs across all components"
```

---

### Task 8: Replace remaining arbitrary font-size classes

**Files to modify:**

**text-[15px] → text-lg (2 instances):**
- `pages/PinPage.svelte:117` — `placeholder:text-[15px]` → `placeholder:text-lg`
- `components/layout/Header.svelte:121` — `text-[15px]` → `text-lg`

**text-[22px] → text-2xl (3 instances):**
- `pages/SetupPage.svelte:289` — `text-[22px]` → `text-2xl`
- `pages/PinPage.svelte:102` — `text-[22px]` → `text-2xl`
- `components/shared/ConduitLogo.svelte:23` — `text-[22px]` → `text-2xl` (the "standard" preset)

**text-[16px] → text-lg (1 instance):**
- `pages/DashboardPage.svelte:180` — `text-[16px]` → `text-lg`

**text-[12px] → text-base (6 instances):**
- `components/model/ModelVariant.svelte:110, 125`
- `components/project/ProjectSwitcher.svelte:341, 349`
- `components/todo/TodoHeader.svelte:26`
- `components/chat/SubagentBackBar.svelte:51`

**text-[9px] → text-xs (5 instances):**
- `components/session/SessionList.svelte:364, 385, 406`
- `components/overlays/SettingsPanel.svelte:427`
- `components/chat/SubagentBackBar.svelte:53`

**text-[8px] → text-xs (1 instance):**
- `components/chat/PastePreview.svelte:55`

**Intentional exceptions (no standard Tailwind equivalent — leave as arbitrary values):**
- `components/shared/ConduitLogo.svelte:24` — `text-[28px]` (loading preset, decorative)
- `components/shared/ConduitLogo.svelte:25` — `text-[14px]` (sidebar preset, decorative)

**Step 1: Apply all replacements above (excluding the 2 exceptions)**

**Step 2: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 3: Grep to confirm only expected exceptions remain**

```bash
rg "text-\[\d+px\]" src/lib/frontend/ --include="*.svelte"
```

Expected: 2 matches in `ConduitLogo.svelte` (the `text-[28px]` and `text-[14px]` exceptions).

**Step 4: Commit**

```bash
git add -u src/lib/frontend/
git commit -m "feat(ui): replace all remaining arbitrary text-[Npx] with standard Tailwind classes"
```

---

### Task 9: Replace inline font-family: var(--font-brand) with font-brand class

**Files to modify (49 inline style instances across 12 files):**

For each instance of `style="font-family: var(--font-brand);"` (or as part of a larger style attribute), remove the `font-family: var(--font-brand);` from the inline style and add `font-brand` to the element's class list.

**Approach by file:**

If the element's `style=` attribute ONLY contains `font-family: var(--font-brand);`, remove the entire `style` attribute and add `font-brand` to the class.

If the element's `style=` has OTHER properties too, remove only the `font-family: var(--font-brand);` part and add `font-brand` to the class. There is exactly **one compound case**: `ConnectOverlay.svelte:195` has `style="font-family: var(--font-brand); background: linear-gradient(...); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;"` — remove only the `font-family` part, keep the gradient/clip properties in the inline style. All other 47 template instances have `font-family: var(--font-brand);` as the sole style property.

| File | Instance count |
|------|---------------|
| `components/overlays/SettingsPanel.svelte` | 14 |
| `components/session/SessionList.svelte` | 9 |
| `components/layout/Sidebar.svelte` | 7 |
| `components/session/SessionItem.svelte` | 3 |
| `components/overlays/ConnectOverlay.svelte` | 3 |
| `components/model/ModelVariant.svelte` | 2 |
| `components/model/ModelSelector.svelte` | 2 |
| `components/project/ProjectSwitcher.svelte` | 2 |
| `components/input/AttachMenu.svelte` | 2 |
| `components/model/AgentSelector.svelte` | 1 (template, not innerHTML) |
| `components/todo/TodoOverlay.svelte` | 1 |
| `components/shared/ConduitLogo.svelte` | 1 |
| `components/layout/Header.svelte` | 1 |

**Step 1: Apply replacements file by file**

Work through each file. For each `style="font-family: var(--font-brand);"`, remove it and add `font-brand` to the element's Tailwind classes.

**Step 2: Handle the AgentSelector innerHTML case**

In `components/model/AgentSelector.svelte:144`, the `buildDropdownHTML()` function has `font-family:var(--font-brand)` inside a JS template string. This cannot use a Tailwind class since it's raw HTML. Leave this one as-is for now (it will be addressed when the portal is migrated to a Svelte component in a future task).

**Step 3: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 4: Grep to confirm**

```bash
rg "font-family: var\(--font-brand\)" src/lib/frontend/ --include="*.svelte"
```

Expected: Only 1-2 matches remaining (AgentSelector innerHTML).

**Step 5: Commit**

```bash
git add -u src/lib/frontend/
git commit -m "feat(ui): replace inline font-family brand styles with font-brand Tailwind class"
```

---

### Task 10: Migrate ThemePicker scoped CSS to Tailwind utilities

**Files:**
- Modify: `src/lib/frontend/components/overlays/ThemePicker.svelte`

**Step 1: Identify scoped CSS font values**

The `<style>` block (lines ~109-199) contains:
- `.theme-picker-header`: `font-size: 10px` → should use `text-xs` class
- `.theme-picker-item`: `font-size: 12px` → should use `text-base` class
- `.theme-picker-item.active`: `font-weight: 500` → should use `font-medium` class
- `.theme-picker-check`: `font-size: 14px` → keep as `text-[14px]` or round to `text-base` (this is a checkmark symbol, visual sizing)

**Step 2: Move font-size, font-weight, and letter-spacing from scoped CSS to Tailwind classes on the template elements**

For each selector in the `<style>` block that has font-size, font-weight, or letter-spacing, remove those properties from the CSS and add the equivalent Tailwind utility classes to the element in the template.

Remove from scoped CSS and add to template elements:
- `.theme-picker-header`: remove `font-size`, `font-weight`, `letter-spacing`, `text-transform` → add `text-xs font-semibold tracking-[0.05em] uppercase`
- `.theme-picker-item`: remove `font-size` → add `text-base`
- `.theme-picker-item.active`: remove `font-weight` → this is state-dependent; use the existing `class:active` condition (`themeState.currentThemeId === id`) to conditionally apply `font-medium`, e.g. `class:font-medium={themeState.currentThemeId === id}`
- `.theme-picker-check`: remove `font-size` → keep in scoped CSS as it's a special visual element

**Step 3: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 4: Commit**

```bash
git add src/lib/frontend/components/overlays/ThemePicker.svelte
git commit -m "refactor(ui): migrate ThemePicker font styles from scoped CSS to Tailwind"
```

---

### Task 11: Update AgentSelector portal inline styles

**Files:**
- Modify: `src/lib/frontend/components/model/AgentSelector.svelte`

**Step 1: Update font-size and class values in buildDropdownHTML()**

In the `buildDropdownHTML()` function:
- Line ~131: change `text-[13px]` to `text-base` in the empty-state div's class attribute (this is a Tailwind class inside a JS template string — safe to replace)
- Line ~144: change `font-size:13px` to `font-size:12px` in the inline style (align with new text-base)
- Line ~141: `font-size:10px` — already matches text-xs, no change needed

**Note:** A full migration of this portal to a Svelte component is out of scope for this plan. This task only updates the font sizes to match the new scale.

**Step 2: Run verification**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 3: Commit**

```bash
git add src/lib/frontend/components/model/AgentSelector.svelte
git commit -m "fix(ui): update AgentSelector portal font sizes for 12px rebase"
```

---

### Task 12: Final verification and cleanup

**Step 1: Run full grep for any remaining arbitrary text sizes**

```bash
rg "text-\[\d+px\]" src/lib/frontend/ --include="*.svelte"
```

Expected: 2 matches in `ConduitLogo.svelte` (`text-[28px]` and `text-[14px]` — intentional exceptions for decorative logo presets). The only other remaining `text-[Nem]` values should be em-based heading/code sizes in `style.css`.

**Step 2: Run full grep for remaining inline font-brand**

```bash
rg "font-family.*font-brand" src/lib/frontend/ --include="*.svelte"
```

Expected: 1-2 matches (AgentSelector innerHTML only).

**Step 3: Run full grep for rem-based font-sizes**

```bash
rg "font-size:.*rem" src/lib/frontend/ --include="*.css"
```

Expected: 0 matches.

**Step 4: Run full verification suite**

```bash
pnpm check && pnpm lint && pnpm test:unit
```

**Step 5: Visual check**

Open the running conduit instance at http://localhost:2633/ and verify:
1. Chat messages render at the new smaller body size
2. Tool items are visibly smaller than message text (11px headers, 10px output)
3. Sidebar actions, session items, and dropdowns look proportional
4. Headings in markdown content (h1/h2/h3) are clearly distinct from body text
5. Code blocks in messages match body text size
6. Plan mode banners and cards render correctly
7. Diff view and file viewer render correctly
8. Settings panel, modals, and overlays look correct

**Step 6: Commit any fixups if needed, then final commit**

```bash
git add -u
git commit -m "chore(ui): final cleanup after 12px rebase"
```
