# Black Monochrome Theme Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Replace the red/crimson/chocolate accent color system with a unified black monochrome palette across all theme variants, matching the `openclaw-desktop-ui` reference design.

**Architecture:** All six theme blocks in `ui/src/styles/base.css` converge to two shared token sets — dark and light. Background/surface tokens are updated to match the reference design; accent tokens are replaced with black (light mode) / light-gray (dark mode); teal `accent-2` is replaced with neutral gray. Semantic colors (green, amber, red, blue) are preserved unchanged.

**Tech Stack:** CSS custom properties only. Single file edit.

---

### Task 1: Update `:root` dark mode tokens

**Files:**
- Modify: `ui/src/styles/base.css:1-127`

No unit tests exist for CSS variables. Verification is via dev server (Task 7).

- [ ] **Step 1: Replace background tokens in `:root`**

In `ui/src/styles/base.css`, find and replace the background block (lines 3–7):

```css
/* BEFORE */
  --bg: #0e1015;
  --bg-accent: #13151b;
  --bg-elevated: #191c24;
  --bg-hover: #1f2330;
  --bg-muted: #1f2330;

/* AFTER */
  --bg: #1a1a1a;
  --bg-accent: #141414;
  --bg-elevated: #242424;
  --bg-hover: #262626;
  --bg-muted: #262626;
```

- [ ] **Step 2: Replace card/surface tokens in `:root`**

```css
/* BEFORE */
  --card: #161920;
  --card-foreground: #f0f0f2;
  --card-highlight: rgba(255, 255, 255, 0.04);
  --popover: #191c24;
  --popover-foreground: #f0f0f2;

/* AFTER */
  --card: #242424;
  --card-foreground: #e5e7eb;
  --card-highlight: rgba(255, 255, 255, 0.04);
  --popover: #242424;
  --popover-foreground: #e5e7eb;
```

- [ ] **Step 3: Replace panel/chrome tokens in `:root`**

```css
/* BEFORE */
  --panel: #0e1015;
  --panel-strong: #191c24;
  --panel-hover: #1f2330;
  --chrome: rgba(14, 16, 21, 0.96);
  --chrome-strong: rgba(14, 16, 21, 0.98);

/* AFTER */
  --panel: #1a1a1a;
  --panel-strong: #242424;
  --panel-hover: #262626;
  --chrome: rgba(20, 20, 20, 0.96);
  --chrome-strong: rgba(20, 20, 20, 0.98);
```

- [ ] **Step 4: Replace text tokens in `:root`**

```css
/* BEFORE */
  --text: #d4d4d8;
  --text-strong: #f4f4f5;
  --chat-text: #d4d4d8;
  --muted: #838387;
  --muted-strong: #75757d;
  --muted-foreground: #838387;

/* AFTER */
  --text: #e5e7eb;
  --text-strong: #f9fafb;
  --chat-text: #d1d5db;
  --muted: #a1a1aa;
  --muted-strong: #71717a;
  --muted-foreground: #a1a1aa;
```

- [ ] **Step 5: Replace border and ring tokens in `:root`**

```css
/* BEFORE */
  --border: #1e2028;
  --border-strong: #2e3040;
  --border-hover: #3e4050;
  --input: #1e2028;
  --ring: #ff5c5c;

/* AFTER */
  --border: #2e2e2e;
  --border-strong: #3a3a3a;
  --border-hover: #4a4a4a;
  --input: #2e2e2e;
  --ring: #e5e7eb;
```

- [ ] **Step 6: Replace accent and primary tokens in `:root`**

```css
/* BEFORE */
  /* Accent - Punchy signature red */
  --accent: #ff5c5c;
  --accent-hover: #ff7070;
  --accent-muted: #ff5c5c;
  --accent-subtle: rgba(255, 92, 92, 0.1);
  --accent-foreground: #fafafa;
  --accent-glow: rgba(255, 92, 92, 0.2);
  --selection-bg: #005fcc;
  --selection-fg: #ffffff;
  --primary: #ff5c5c;
  --primary-foreground: #ffffff;

/* AFTER */
  /* Accent - Black monochrome */
  --accent: #e5e7eb;
  --accent-hover: #d1d5db;
  --accent-muted: #e5e7eb;
  --accent-subtle: rgba(229, 231, 235, 0.1);
  --accent-foreground: #1a1a1a;
  --accent-glow: rgba(229, 231, 235, 0.08);
  --selection-bg: #005fcc;
  --selection-fg: #ffffff;
  --primary: #e5e7eb;
  --primary-foreground: #1a1a1a;
```

- [ ] **Step 7: Replace secondary and accent-2 tokens in `:root`**

```css
/* BEFORE */
  --secondary: #161920;
  --secondary-foreground: #f0f0f2;
  --accent-2: #14b8a6;
  --accent-2-muted: rgba(20, 184, 166, 0.7);
  --accent-2-subtle: rgba(20, 184, 166, 0.1);

/* AFTER */
  --secondary: #262626;
  --secondary-foreground: #e5e7eb;
  --accent-2: #6b7280;
  --accent-2-muted: rgba(107, 114, 128, 0.7);
  --accent-2-subtle: rgba(107, 114, 128, 0.1);
```

- [ ] **Step 8: Replace focus token in `:root`**

```css
/* BEFORE */
  --focus: rgba(255, 92, 92, 0.2);

/* AFTER */
  --focus: rgba(229, 231, 235, 0.15);
```

(`--focus-ring` and `--focus-glow` use `var(--ring)` and `var(--accent-glow)` — they update automatically.)

---

### Task 2: Update `:root[data-theme-mode="light"]` tokens

**Files:**
- Modify: `ui/src/styles/base.css:130-212`

- [ ] **Step 1: Replace background tokens in light block**

```css
/* BEFORE */
  --bg: #f8f9fa;
  --bg-accent: #f1f3f5;
  --bg-elevated: #ffffff;
  --bg-hover: #eceef0;
  --bg-muted: #eceef0;
  --bg-content: #f1f3f5;

/* AFTER */
  --bg: #ffffff;
  --bg-accent: #f8f9fa;
  --bg-elevated: #ffffff;
  --bg-hover: #f3f4f6;
  --bg-muted: #f5f5f5;
  --bg-content: #f8f9fa;
```

- [ ] **Step 2: Replace card/popover tokens in light block**

```css
/* BEFORE */
  --card: #ffffff;
  --card-foreground: #1a1a1e;
  --card-highlight: rgba(0, 0, 0, 0.02);
  --popover: #ffffff;
  --popover-foreground: #1a1a1e;

/* AFTER */
  --card: #ffffff;
  --card-foreground: #111111;
  --card-highlight: rgba(0, 0, 0, 0.02);
  --popover: #ffffff;
  --popover-foreground: #111111;
```

- [ ] **Step 3: Replace panel/chrome tokens in light block**

```css
/* BEFORE */
  --panel: #f8f9fa;
  --panel-strong: #f1f3f5;
  --panel-hover: #e6e8eb;
  --chrome: rgba(248, 249, 250, 0.96);
  --chrome-strong: rgba(248, 249, 250, 0.98);

/* AFTER */
  --panel: #ffffff;
  --panel-strong: #f8f9fa;
  --panel-hover: #f3f4f6;
  --chrome: rgba(255, 255, 255, 0.96);
  --chrome-strong: rgba(255, 255, 255, 0.98);
```

- [ ] **Step 4: Replace text tokens in light block**

```css
/* BEFORE */
  --text: #3c3c43;
  --text-strong: #1a1a1e;
  --chat-text: #3c3c43;
  --muted: #6e6e73;
  --muted-strong: #545458;
  --muted-foreground: #6e6e73;

/* AFTER */
  --text: #374151;
  --text-strong: #111111;
  --chat-text: #374151;
  --muted: #6b7280;
  --muted-strong: #4b5563;
  --muted-foreground: #6b7280;
```

- [ ] **Step 5: Replace border tokens in light block**

```css
/* BEFORE */
  --border: #e5e5ea;
  --border-strong: #d1d1d6;
  --border-hover: #aeaeb2;
  --input: #e5e5ea;

/* AFTER */
  --border: #e5e7eb;
  --border-strong: #d1d5db;
  --border-hover: #9ca3af;
  --input: #e5e7eb;
```

- [ ] **Step 6: Replace accent/primary tokens in light block**

```css
/* BEFORE */
  --accent: #dc2626;
  --accent-hover: #ef4444;
  --accent-muted: #dc2626;
  --accent-subtle: rgba(220, 38, 38, 0.08);
  --accent-foreground: #ffffff;
  --accent-glow: rgba(220, 38, 38, 0.1);
  --primary: #dc2626;
  --primary-foreground: #ffffff;

/* AFTER */
  --accent: #111111;
  --accent-hover: #242424;
  --accent-muted: #111111;
  --accent-subtle: rgba(17, 17, 17, 0.06);
  --accent-foreground: #ffffff;
  --accent-glow: rgba(17, 17, 17, 0.06);
  --primary: #111111;
  --primary-foreground: #ffffff;
```

- [ ] **Step 7: Replace secondary and accent-2 tokens in light block**

```css
/* BEFORE */
  --secondary: #f1f3f5;
  --secondary-foreground: #3c3c43;
  --accent-2: #0d9488;
  --accent-2-muted: rgba(13, 148, 136, 0.75);
  --accent-2-subtle: rgba(13, 148, 136, 0.08);

/* AFTER */
  --secondary: #f8f9fa;
  --secondary-foreground: #111111;
  --accent-2: #9ca3af;
  --accent-2-muted: rgba(156, 163, 175, 0.75);
  --accent-2-subtle: rgba(156, 163, 175, 0.08);
```

- [ ] **Step 8: Replace focus token in light block**

```css
/* BEFORE */
  --focus: rgba(220, 38, 38, 0.15);

/* AFTER */
  --focus: rgba(17, 17, 17, 0.1);
```

(The `--ring` token is not explicitly set in the light block — it inherits `#e5e7eb` from `:root`. Add it here to override to black for light mode.)

After the `--input` line, also add:

```css
  --ring: #111111;
```

---

### Task 3: Replace `openknot` dark block

**Files:**
- Modify: `ui/src/styles/base.css:226-297`

The entire openknot dark block is replaced with the unified dark token set. Since all values become identical to `:root`, only the tokens that differ from `:root`'s new values need to be listed — but for explicitness, we restate all changed tokens.

- [ ] **Step 1: Replace the entire openknot block body**

Replace everything between `{` and `}` of `:root[data-theme="openknot"]` with:

```css
:root[data-theme="openknot"] {
  /* Unified black monochrome — identical to claw dark */
  --bg: #1a1a1a;
  --bg-accent: #141414;
  --bg-elevated: #242424;
  --bg-hover: #262626;
  --bg-muted: #262626;

  --card: #242424;
  --card-foreground: #e5e7eb;
  --card-highlight: rgba(255, 255, 255, 0.04);
  --popover: #242424;
  --popover-foreground: #e5e7eb;

  --panel: #1a1a1a;
  --panel-strong: #242424;
  --panel-hover: #262626;
  --chrome: rgba(20, 20, 20, 0.96);
  --chrome-strong: rgba(20, 20, 20, 0.98);

  --text: #e5e7eb;
  --text-strong: #f9fafb;
  --chat-text: #d1d5db;
  --muted: #a1a1aa;
  --muted-strong: #71717a;
  --muted-foreground: #a1a1aa;

  --border: #2e2e2e;
  --border-strong: #3a3a3a;
  --border-hover: #4a4a4a;
  --input: #2e2e2e;
  --ring: #e5e7eb;

  --accent: #e5e7eb;
  --accent-hover: #d1d5db;
  --accent-muted: #e5e7eb;
  --accent-subtle: rgba(229, 231, 235, 0.1);
  --accent-foreground: #1a1a1a;
  --accent-glow: rgba(229, 231, 235, 0.08);
  --primary: #e5e7eb;
  --primary-foreground: #1a1a1a;

  --secondary: #262626;
  --secondary-foreground: #e5e7eb;
  --accent-2: #6b7280;
  --accent-2-muted: rgba(107, 114, 128, 0.7);
  --accent-2-subtle: rgba(107, 114, 128, 0.1);

  --focus: rgba(229, 231, 235, 0.15);
  --focus-ring:
    0 0 0 2px var(--bg),
    0 0 0 3px color-mix(in srgb, var(--ring) 70%, transparent);
  --focus-glow:
    0 0 0 2px var(--bg), 0 0 0 3px var(--ring), 0 0 16px var(--accent-glow);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.4);

  --grid-line: rgba(255, 255, 255, 0.03);
}
```

---

### Task 4: Replace `openknot-light` block

**Files:**
- Modify: `ui/src/styles/base.css:299-363`

- [ ] **Step 1: Replace the entire openknot-light block body**

```css
:root[data-theme="openknot-light"] {
  /* Unified black monochrome — identical to claw light */
  --bg: #ffffff;
  --bg-accent: #f8f9fa;
  --bg-elevated: #ffffff;
  --bg-hover: #f3f4f6;
  --bg-muted: #f5f5f5;
  --bg-content: #f8f9fa;

  --card: #ffffff;
  --card-foreground: #111111;
  --card-highlight: rgba(0, 0, 0, 0.02);
  --popover: #ffffff;
  --popover-foreground: #111111;

  --panel: #ffffff;
  --panel-strong: #f8f9fa;
  --panel-hover: #f3f4f6;
  --chrome: rgba(255, 255, 255, 0.96);
  --chrome-strong: rgba(255, 255, 255, 0.98);

  --text: #374151;
  --text-strong: #111111;
  --chat-text: #374151;
  --muted: #6b7280;
  --muted-strong: #4b5563;
  --muted-foreground: #6b7280;

  --border: #e5e7eb;
  --border-strong: #d1d5db;
  --border-hover: #9ca3af;
  --input: #e5e7eb;
  --ring: #111111;

  --accent: #111111;
  --accent-hover: #242424;
  --accent-muted: #111111;
  --accent-subtle: rgba(17, 17, 17, 0.06);
  --accent-foreground: #ffffff;
  --accent-glow: rgba(17, 17, 17, 0.06);
  --primary: #111111;
  --primary-foreground: #ffffff;

  --secondary: #f8f9fa;
  --secondary-foreground: #111111;
  --accent-2: #9ca3af;
  --accent-2-muted: rgba(156, 163, 175, 0.75);
  --accent-2-subtle: rgba(156, 163, 175, 0.08);

  --focus: rgba(17, 17, 17, 0.1);
  --focus-ring:
    0 0 0 2px var(--bg),
    0 0 0 3px color-mix(in srgb, var(--ring) 70%, transparent);
  --focus-glow:
    0 0 0 2px var(--bg), 0 0 0 3px var(--ring), 0 0 12px var(--accent-glow);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.06);
  --shadow-lg: 0 12px 28px rgba(0, 0, 0, 0.08);

  --grid-line: rgba(0, 0, 0, 0.04);
}
```

---

### Task 5: Replace `dash` dark block

**Files:**
- Modify: `ui/src/styles/base.css:365-434`

- [ ] **Step 1: Replace the entire dash dark block body**

```css
:root[data-theme="dash"] {
  /* Unified black monochrome — identical to claw dark */
  --bg: #1a1a1a;
  --bg-accent: #141414;
  --bg-elevated: #242424;
  --bg-hover: #262626;
  --bg-muted: #262626;

  --card: #242424;
  --card-foreground: #e5e7eb;
  --card-highlight: rgba(255, 255, 255, 0.04);
  --popover: #242424;
  --popover-foreground: #e5e7eb;

  --panel: #1a1a1a;
  --panel-strong: #242424;
  --panel-hover: #262626;
  --chrome: rgba(20, 20, 20, 0.96);
  --chrome-strong: rgba(20, 20, 20, 0.98);

  --text: #e5e7eb;
  --text-strong: #f9fafb;
  --chat-text: #d1d5db;
  --muted: #a1a1aa;
  --muted-strong: #71717a;
  --muted-foreground: #a1a1aa;

  --border: #2e2e2e;
  --border-strong: #3a3a3a;
  --border-hover: #4a4a4a;
  --input: #2e2e2e;
  --ring: #e5e7eb;

  --accent: #e5e7eb;
  --accent-hover: #d1d5db;
  --accent-muted: #e5e7eb;
  --accent-subtle: rgba(229, 231, 235, 0.1);
  --accent-foreground: #1a1a1a;
  --accent-glow: rgba(229, 231, 235, 0.08);
  --primary: #e5e7eb;
  --primary-foreground: #1a1a1a;

  --secondary: #262626;
  --secondary-foreground: #e5e7eb;
  --accent-2: #6b7280;
  --accent-2-muted: rgba(107, 114, 128, 0.7);
  --accent-2-subtle: rgba(107, 114, 128, 0.1);

  --focus: rgba(229, 231, 235, 0.15);
  --focus-ring:
    0 0 0 2px var(--bg),
    0 0 0 3px color-mix(in srgb, var(--ring) 80%, transparent);
  --focus-glow:
    0 0 0 2px var(--bg), 0 0 0 3px var(--ring), 0 0 16px var(--accent-glow);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.4);

  --grid-line: rgba(255, 255, 255, 0.03);
}
```

---

### Task 6: Replace `dash-light` block

**Files:**
- Modify: `ui/src/styles/base.css:436-498`

- [ ] **Step 1: Replace the entire dash-light block body**

```css
:root[data-theme="dash-light"] {
  /* Unified black monochrome — identical to claw light */
  --bg: #ffffff;
  --bg-accent: #f8f9fa;
  --bg-elevated: #ffffff;
  --bg-hover: #f3f4f6;
  --bg-muted: #f5f5f5;
  --bg-content: #f8f9fa;

  --card: #ffffff;
  --card-foreground: #111111;
  --card-highlight: rgba(0, 0, 0, 0.02);
  --popover: #ffffff;
  --popover-foreground: #111111;

  --panel: #ffffff;
  --panel-strong: #f8f9fa;
  --panel-hover: #f3f4f6;
  --chrome: rgba(255, 255, 255, 0.96);
  --chrome-strong: rgba(255, 255, 255, 0.98);

  --text: #374151;
  --text-strong: #111111;
  --chat-text: #374151;
  --muted: #6b7280;
  --muted-strong: #4b5563;
  --muted-foreground: #6b7280;

  --border: #e5e7eb;
  --border-strong: #d1d5db;
  --border-hover: #9ca3af;
  --input: #e5e7eb;
  --ring: #111111;

  --accent: #111111;
  --accent-hover: #242424;
  --accent-muted: #111111;
  --accent-subtle: rgba(17, 17, 17, 0.06);
  --accent-foreground: #ffffff;
  --accent-glow: rgba(17, 17, 17, 0.06);
  --primary: #111111;
  --primary-foreground: #ffffff;

  --secondary: #f8f9fa;
  --secondary-foreground: #111111;
  --accent-2: #9ca3af;
  --accent-2-muted: rgba(156, 163, 175, 0.75);
  --accent-2-subtle: rgba(156, 163, 175, 0.08);

  --focus: rgba(17, 17, 17, 0.1);
  --focus-ring:
    0 0 0 2px var(--bg),
    0 0 0 3px color-mix(in srgb, var(--ring) 70%, transparent);
  --focus-glow:
    0 0 0 2px var(--bg), 0 0 0 3px var(--ring), 0 0 12px var(--accent-glow);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.06);
  --shadow-lg: 0 12px 28px rgba(0, 0, 0, 0.08);

  --grid-line: rgba(0, 0, 0, 0.04);
}
```

---

### Task 7: Visual verification and commit

**Files:**
- No code changes

- [ ] **Step 1: Start the dev server**

```bash
pnpm dev
```

Open the app at the local dev URL (typically `http://localhost:5173` or as printed).

- [ ] **Step 2: Verify dark mode (default theme)**

In the app, check:
- Background is dark gray `#1a1a1a` (not blue-black)
- Sidebar/rail is `#141414` (slightly darker than background)
- Buttons/active states use light gray `#e5e7eb` (not red)
- Focus ring around interactive elements is gray, not red
- Success badges still show green, warning amber, errors red

Open browser DevTools → Elements → `:root` → verify `--accent` reads `#e5e7eb`.

- [ ] **Step 3: Switch to light mode and verify**

In app settings, toggle to light mode. Check:
- Background is white `#ffffff`
- Primary buttons are black `#111111`
- Text is `#374151` (not pure black, readable gray)
- Borders are `#e5e7eb`
- Semantic colors unchanged

Verify `--accent` reads `#111111` in DevTools.

- [ ] **Step 4: Cycle through knot and dash themes**

Switch to knot and dash themes in both dark and light mode. Confirm they look identical to the default claw theme (unified palette working correctly).

- [ ] **Step 5: Commit**

```bash
scripts/committer "feat(ui): black monochrome theme — unified across all theme variants" ui/src/styles/base.css
```
