# UI Polish — Design Parity Follow-up > Follow-up to the islands rewrite. Closes visible gaps between the current state and the handoff mock. Execute with subagent-driven development; phases B/C/D can run in parallel. **Goal:** Bring the rewrite to pixel-level parity with `docs/UI Rewrite/design_handoff_claudedo/ClaudeDo-standalone.html`. **Tech stack:** Avalonia 12, CommunityToolkit.Mvvm. No new dependencies. **Reference files:** - Source of truth: `docs/UI Rewrite/design_handoff_claudedo/ClaudeDo-standalone.html` - CSS measurements: `docs/UI Rewrite/design_handoff_claudedo/styles.css` - JSX component structure: `docs/UI Rewrite/design_handoff_claudedo/islands.jsx`, `app.jsx` - Tokens: `src/ClaudeDo.Ui/Design/Tokens.axaml` - Styles: `src/ClaudeDo.Ui/Design/IslandStyles.axaml` **Rules for all phases:** - Use existing token brushes (`MossBrush`, `PeatBrush`, `AccentSoftBrush`, etc.) — do NOT hard-code hex. - Use `Classes="foo"` + selectors in `IslandStyles.axaml` for reusable styling; inline AXAML setters for one-off values only. - Icons: use `Projektion.Avalonia` `PathIcon` with `Data="{StaticResource IconKey}"`. Define new `StreamGeometry` resources in `IslandStyles.axaml` under an `` section when needed. Pull the SVG paths from the JSX reference. - Read the relevant JSX + CSS file in the handoff before implementing each component — those are the source of truth for exact measurements/paddings/colors. - Do not touch the data layer, Worker, SignalR, or command wiring. This is a view/style-only pass. --- ## Phase A — Shell + title bar (sequential, run first) One subagent. Small blast radius; prerequisite for the visual "feel." ### Task A1 — Custom title bar **Files:** - `src/ClaudeDo.Ui/Views/MainWindow.axaml` + `.axaml.cs` - `src/ClaudeDo.Ui/Design/IslandStyles.axaml` (add title-bar styles + window-control icon-button style) - [ ] Replace the current title bar Grid with a 3-section layout: - Left: brand block — checkbox-style green glyph + `CLAUDEDO` (mono, uppercase, tracking 1.4, 11px) + separator dot + current-list name eyebrow-style (mono uppercase, `TextDim`). Bind the list name to `Shell.Lists.SelectedList.Name.ToUpperInvariant()`. - Middle: draggable strip (`PointerPressed → BeginMoveDrag`). - Right: three frameless icon buttons (minimize / maximize-restore / close). Close button hover turns `BloodBrush`. Use `PathIcon` with inline `StreamGeometry` for the Lucide-style icons: `Minus`, `Square`, `X` — the exact SVG `d` strings are in `icons.jsx`. - [ ] Title bar height: 36px, background `DeepBrush`, bottom border 1px `LineBrush`. - [ ] Remove the character glyphs currently used for the window controls (`—`, `▢`, `✕`) — use PathIcons instead. - [ ] Commit: `style(ui): custom title bar with brand and window controls` ### Task A2 — Background + island shadow **Files:** - `src/ClaudeDo.Ui/Views/MainWindow.axaml` (background layer) - `src/ClaudeDo.Ui/Design/IslandStyles.axaml` (island shadow adjust) - [ ] Under the three-island Grid, add a `Border` filling the whole row with a subtle radial gradient from `DeepBrush` (center) to `VoidBrush` (edges). Use a `RadialGradientBrush` with 2 stops; keep opacity light. - [ ] In `IslandStyles.axaml`, bump the `Border.island` `BoxShadow` to match the token `IslandShadow` value exactly (`0 20 40 #59000000, 0 2 4 #4D000000`). Verify by inspecting the current style — if it's already set, no-op. - [ ] Commit: `style(ui): background gradient and stronger island shadow` --- ## Phase B — Lists island polish (parallel with C, D) ### Task B1 — Icon geometries + eyebrow rename + sections **Files:** - `src/ClaudeDo.Ui/Design/IslandStyles.axaml` (add `StreamGeometry` icon resources at the top) - `src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs` (map `IconKey` strings → resource keys, add section grouping) - `src/ClaudeDo.Ui/Views/Islands/ListsIslandView.axaml` - [ ] Extract the SVG path `d` strings from `icons.jsx` for: `Sun`, `Activity` (pulse), `Star`, `Calendar`, `Eye`, `Inbox`, `Folder`, `Search`, `Plus`, `MoreHorizontal`. Define each as an `x:Key="Icon.Sun"` `StreamGeometry` in `IslandStyles.axaml`. - [ ] Change Lists eyebrow from `WORKSPACE` to `NAVIGATOR`. - [ ] Add two section-header rows in the ItemsControl: `SMART LISTS` (above items of `Kind=Smart` + `Virtual`) and `MY LISTS` (above items of `Kind=User`). Simplest approach: two separate `ItemsControl`s bound to filtered subsets; or wrap items in a `CollectionViewSource` grouping. Pick the simplest working approach. - [ ] Per-item icon: bind `PathIcon Data="{DynamicResource Icon.{IconKey}}"` via a tiny `IconGeometryConverter` (takes `IconKey` string → looks up resource). Icon color: `TextMute` default; `AccentBrush` (moss) when `IsActive`. - [ ] User-list items: use a 6px circle with `MossBrush` / `PeatBrush` / `SageBrush` dot instead of folder icon (map per list index mod colors, or single color if simpler). - [ ] Active state: remove solid fill. Use `AccentSoftBrush` (~10% moss) + left 2px accent bar + `AccentBrush` icon + `TextBrush` text. - [ ] Commit: `style(ui): lists icons, section headers, active state` ### Task B2 — Search bar + keyboard hint + footer buttons **Files:** - `src/ClaudeDo.Ui/Views/Islands/ListsIslandView.axaml` - `src/ClaudeDo.Ui/Design/IslandStyles.axaml` (search style + kbd chip style) - [ ] Search `TextBox`: wrap in a `Grid ColumnDefinitions="Auto,*,Auto"` — left `PathIcon Data="{Icon.Search}"` (14px, `TextFaint`), middle TextBox, right `Border Classes="kbd"` with `⌘K` (or `Ctrl K` on Win). The `kbd` chip: mono 10px, `Surface2` bg, `LineBrush` border, padding `6,2`, radius 4. - [ ] Under the items list, add: - `+ New list` button — plain icon+text row, `PathIcon Data="{Icon.Plus}"`, hover tint. - User profile row — avatar circle (initials fallback, seed from `Environment.UserName`), name (`Environment.UserName`), subtitle `{MachineName} / local` mono dim, right `PathIcon Data="{Icon.MoreHorizontal}"`. - [ ] Commit: `style(ui): lists search icon, kbd hint, footer actions` --- ## Phase C — Tasks island polish (parallel with B, D) ### Task C1 — Header + add-task row styling **Files:** - `src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs` (subtitle format, header toolbar properties) - `src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml` - `src/ClaudeDo.Ui/Design/IslandStyles.axaml` (kbd-enter, add-task row) - [ ] Subtitle format: change from `{open} open · {running} running · {review} in review` to `{Weekday}, {Month} {Day} · {open} open` to match the mock. Keep the running/review counts visible but move them into a right-aligned mono pill row next to the title (or drop if cleaner). - [ ] Eyebrow: keep current `MONTAG · APR. 20` pattern. Title remains list name. - [ ] Right-side icon toolbar: three `Button Classes="icon-btn"` — `Sort` icon, `Eye` icon (toggle completed), `MoreHorizontal`. Icons: pull paths from `icons.jsx`. Wire `Eye` to an `IsShowingCompleted` observable (persist in a private field for now; no DB change). - [ ] Add-task row: wrap the `TextBox` in a `Border` with `Surface2` bg, rounded 8px, 14px padding. Prepend a circular `PathIcon Data="{Icon.Plus}"` (20px circle, `Surface3` bg). Append a `Border Classes="kbd"` with `ENTER` text (only visible when `NewTaskTitle` has focus — bind visibility to `TextBox.IsFocused`). - [ ] Commit: `style(ui): tasks header toolbar and add-task row` ### Task C2 — Task row chips + states **Files:** - `src/ClaudeDo.Ui/ViewModels/Islands/TaskRowViewModel.cs` (expose a few more flags: `IsOverdue`, `Tags`, `StepsCount`, `StepsCompleted`) - `src/ClaudeDo.Ui/Views/Islands/TaskRowView.axaml` - `src/ClaudeDo.Ui/Design/IslandStyles.axaml` (chip variants, selected accent, done state, live-tail meter) - [ ] Chip set per row (ItemsControl or StackPanel): - Status chip (already present) — ensure color maps per Status → token brush (idle/queued/running/review/error). - List chip — small colored bullet (6px circle in `MossBrush` or similar) + list name. - Branch chip — `PathIcon Data="{Icon.GitBranch}"` (12px) + branch name (mono 10px). - Diff chip — `+N` moss + ` ` + `−M` blood. - Tags — one chip per tag (`#refactor` style, `Surface2` bg, mono 10px, `TextDim`). - [ ] Selected state: add 2px `AccentBrush` left border on the row Border when `IsSelected=true` (style selector `Border.task-row.selected`). Background shifts to `AccentSoftBrush`. - [ ] Done state: strike-through title + fade opacity to 0.5. Add `Border.task-row:has(.done)` equivalent via the existing `Done` binding — simpler: a `TextBlock` style selector that flips `TextDecorations`. - [ ] Live-tail row (only visible when `Status == Running` and `LiveTail != null`): a `Border` under the chip row with mono 11px ellipsized text + a slim 3px progress `Rectangle` with `MossBrush`. For now the progress is static 30% — wire it to a future `ProgressFraction` property (leave as 0.3 fallback). - [ ] Ensure `task-row` Border has `Transitions` for `Background` + `Margin` (smooth hover + select). - [ ] Commit: `style(ui): task row chip set, selected/done states, live tail` ### Task C3 — Section dividers (OVERDUE / TASKS / COMPLETED) **Files:** - `src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs` (group the ObservableCollection into sections) - `src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml` (group headers) - [ ] Add grouping: transform `Items` into three sub-collections: - `OverdueItems` — tasks with `ScheduledFor < Today` and not Done. - `OpenItems` — remaining not-Done tasks. - `CompletedItems` — tasks with `Done=true`. - [ ] Expose as three `ObservableCollection` on the VM. Recompute inside `LoadForList`. - [ ] View: three `ItemsControl`s stacked in a `StackPanel`, each preceded by a section header `TextBlock` — `OVERDUE` (only if non-empty), `TASKS`, `COMPLETED · {N}`. Eyebrow style, `TextFaint`. - [ ] Commit: `style(ui): task section dividers overdue/tasks/completed` --- ## Phase D — Details island polish (parallel with B, C) ### Task D1 — Header + task row restyle **Files:** - `src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs` (expose `TaskIdBadge` like `#T1`, computed from task id prefix) - `src/ClaudeDo.Ui/Views/Islands/DetailsIslandView.axaml` - [ ] Top header block: - Eyebrow `LOGBOOK` + right-aligned `#T{shortId}` badge (first 3 hex chars of `Task.Id`, mono `TextFaint`). - Title: keep editable title `TextBox` but reduce size and match mock. - [ ] Under header, a new "task strip" row: `Ellipse` checkbox (bound to `Task.Done` toggle) + title + right-aligned star button. This is separate from the editable title (mock shows both title as editable heading AND a task-row-style strip with check/star). - [ ] Commit: `style(ui): details header with logbook eyebrow and task-id badge` ### Task D2 — Agent strip v2 **Files:** - `src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs` (add `Turns`, `TokensFormatted`, `ElapsedFormatted`, `DiffAdditions`, `DiffDeletions`, `CommitsOnBranch` if not present — most exist) - `src/ClaudeDo.Ui/Views/Islands/AgentStripView.axaml` - `src/ClaudeDo.Ui/Design/IslandStyles.axaml` (diff meter bar style) - [ ] Layout (three rows): - Row 1: pulsing status dot + status label (`RUNNING` etc.) + mono model name + right-aligned stop button (only visible when Running). - Row 2: `WORKTREE` section label + worktree path mono, with a copy-to-clipboard `PathIcon Data="{Icon.Copy}"` button at the end. - Row 3: Branch line — `PathIcon Data="{Icon.GitBranch}"` + branch mono + arrow `←` + `main` + commits count chip. - Row 4: `DIFF` label + `+{additions}` (moss) + `−{deletions}` (blood) + a slim 4px progress-meter `Rectangle` showing additions vs deletions ratio (moss-filled portion). - [ ] Action buttons row: `Open diff`, `Worktree`, external-link `→` (opens file:// to worktree path in OS explorer). - [ ] Agent strip should use `AgentStripStyle.Classes` bound to the running status so colors shift. - [ ] Commit: `style(ui): agent strip with worktree panel and diff meter` ### Task D3 — Session terminal styling **Files:** - `src/ClaudeDo.Ui/Views/Islands/SessionTerminalView.axaml` - `src/ClaudeDo.Ui/Design/IslandStyles.axaml` (terminal header, log-line columns, `LIVE` chip) - `src/ClaudeDo.Ui/ViewModels/Islands/LogLineViewModel.cs` (add `TimestampFormatted` property) - [ ] Top bar of the terminal `Border`: three colored dots (red/yellow/green, 8px `Ellipse`) + `claude-session · {branch}` mono text + right-aligned `LIVE` chip (moss bg, white text, pulsing animation when a task is actively running). - [ ] Log lines: two-column layout — timestamp (mono 10px, `TextFaint`, fixed 70px width) + kind marker (e.g. `TOOL`, `CLAUDE`, `OUT`) + text. Kind marker uses attribute selector `[Tag=log-tool]`, color-mapped. - [ ] Line number/timestamp: add `TimestampFormatted` to `LogLineViewModel` populated as `DateTime.Now.ToString("HH:mm:ss")` on construction. (If real timestamps arrive via SignalR later, swap source.) - [ ] Ensure auto-scroll still works (existing logic). - [ ] Commit: `style(ui): session terminal header, line columns, LIVE chip` ### Task D4 — Subtasks, notes, metadata footer **Files:** - `src/ClaudeDo.Ui/Views/Islands/DetailsIslandView.axaml` - `src/ClaudeDo.Ui/Design/IslandStyles.axaml` (subtask row style) - `src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs` (delete-task command, close-detail command) - [ ] Subtasks: each row is a compact `Border` with rounded 6px, hover background. Check is an `Ellipse` matching the task-row style (not default WinForms-style CheckBox). Completed items get strike-through + fade. - [ ] Notes `TextBox`: `Surface2` bg, 12px padding, watermark `Notes...`, auto-saves on `LostFocus` (call repository `Update`). - [ ] Bottom metadata bar (sticky at the bottom of the Details island — anchor via `DockPanel.Dock="Bottom"`): - Left: `PathIcon Data="{Icon.Trash}"` delete button (prompts confirmation before calling `TaskRepository.DeleteAsync`). - Middle: `Created {Month Day}` mono `TextFaint`. - Right: close-details `PathIcon Data="{Icon.X}"` (clears `SelectedTask` on `TasksIslandViewModel`). - [ ] Commit: `style(ui): subtasks, notes, details metadata footer` --- ## Execution order ``` Phase A (A1 → A2) [sequential, 1 subagent] ↓ Phase B, C, D [parallel, 3 subagents, one per phase] ↓ Final build + smoke ``` Phase A is sequential because it touches `MainWindow.axaml` and `IslandStyles.axaml` root setup. Phases B, C, D each own a distinct island. Only potential conflict: all three add icon geometries to `IslandStyles.axaml`. Mitigation: Phase B is responsible for adding the `StreamGeometry` icon resources (it needs the most). Phases C and D reference those keys without redefining. Final pass: run the app, eyeball against the mock, note remaining gaps.