- {rows.map(a => (
+ {aliasRows.map(a => (
{a.id}
{a.display_name}
@@ -461,4 +469,61 @@ export default function ClaudeCode({ apiBase }: { apiBase: string }) {
)}
>
);
+
+ const sections = [
+ { id: "settings", label: t("claude.workspace.settings"), body: settingsSection },
+ { id: "quickstart", label: t("claude.quickstart"), body: quickstartSection },
+ { id: "smallFast", label: t("claude.smallFastModel"), body: smallFastSection },
+ { id: "modelMap", label: t("claude.modelMap"), body: modelMapSection },
+ { id: "aliases", label: t("claude.aliases"), body: aliasesSection },
+ ];
+
+ if (workspaceView) {
+ const selected = sections.find(s => s.id === selectedSection) ?? sections[0];
+ return (
+
+
+
{t("claude.pageTitle")}
+
+
{t("claude.subtitle")}
+ {status &&
{status}}
+
+
+
+
+
+ );
+ }
+
+ return (
+ <>
+
{t("claude.pageTitle")}
+
{t("claude.subtitle")}
+ {status &&
{status}}
+ {settingsSection}
+ {quickstartSection}
+ {smallFastSection}
+ {modelMapSection}
+ {aliasesSection}
+ >
+ );
}
diff --git a/gui/src/styles-claudecode-workspace.css b/gui/src/styles-claudecode-workspace.css
new file mode 100644
index 000000000..091a09552
--- /dev/null
+++ b/gui/src/styles-claudecode-workspace.css
@@ -0,0 +1,144 @@
+/* ============================================================================
+ claudecode-workspace — isolated stylesheet (mirrors providers-workspace layout DNA)
+ Namespace: claudecode-workspace- | widgets: ccw-
+ Uses only design tokens from styles.css. No gradients.
+ ============================================================================ */
+
+.main-inner:has(.claudecode-workspace-shell) {
+ max-width: 1200px;
+}
+
+.claudecode-workspace-shell {
+ width: 100%;
+ min-width: 0;
+}
+
+.claudecode-workspace-root {
+ display: grid;
+ grid-template-columns: minmax(240px, 280px) minmax(0, 1fr);
+ gap: var(--space-4);
+ width: 100%;
+ max-width: 100%;
+ min-height: 480px;
+}
+
+/* ── Rail ─────────────────────────────────────────────── */
+
+.claudecode-workspace-rail {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-3);
+ border-right: 1px solid var(--border);
+ padding-right: var(--space-3);
+ min-width: 0;
+}
+
+.claudecode-workspace-rail-header {
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+ gap: 8px;
+}
+
+.claudecode-workspace-rail-title {
+ font-size: var(--text-body);
+ font-weight: var(--weight-semibold);
+ color: var(--text);
+}
+
+.claudecode-workspace-rail-list {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ min-height: 0;
+}
+
+.claudecode-workspace-rail-row {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-0-5);
+ width: 100%;
+ min-height: 46px;
+ appearance: none;
+ background: none;
+ border: none;
+ border-radius: var(--radius-sm);
+ padding: var(--space-1-5) var(--space-2);
+ cursor: pointer;
+ text-align: left;
+ color: inherit;
+ font: inherit;
+ overflow: hidden;
+}
+
+.claudecode-workspace-rail-row:hover {
+ background: var(--surface-2);
+}
+
+.claudecode-workspace-rail-row--selected {
+ background: var(--surface-2);
+ outline: 1px solid var(--border);
+}
+
+.claudecode-workspace-rail-name {
+ font-size: var(--text-body);
+ font-weight: var(--weight-medium);
+ color: var(--text);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.claudecode-workspace-rail-meta {
+ font-size: var(--text-caption);
+ color: var(--faint);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+/* ── Main pane ────────────────────────────────────────── */
+
+.claudecode-workspace-main {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4);
+ min-width: 0;
+}
+
+.ccw-detail-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: var(--space-3);
+ flex-wrap: wrap;
+}
+
+.ccw-detail-title {
+ font-size: var(--text-h2);
+ font-weight: var(--weight-semibold);
+ color: var(--text);
+ margin: 0;
+}
+
+.ccw-body {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-3);
+ min-width: 0;
+}
+
+/* ── Responsive ───────────────────────────────────────── */
+
+@media (max-width: 768px) {
+ .claudecode-workspace-root {
+ grid-template-columns: 1fr;
+ }
+
+ .claudecode-workspace-rail {
+ border-right: none;
+ border-bottom: 1px solid var(--border);
+ padding-right: 0;
+ padding-bottom: var(--space-3);
+ }
+}
diff --git a/gui/src/styles.css b/gui/src/styles.css
index ec6f21ac4..d38167320 100644
--- a/gui/src/styles.css
+++ b/gui/src/styles.css
@@ -17,6 +17,7 @@
@import "./styles-dashboard-workspace.css";
@import "./styles-usage-workspace.css";
@import "./styles-apikeys-workspace.css";
+@import "./styles-claudecode-workspace.css";
:root {
/* default: follow the OS; [data-theme] below pins color-scheme so light-dark() obeys it */
From f7a05797e1e70053531e3661d241d4db1f3cf31c Mon Sep 17 00:00:00 2001
From: Wibias <37517432+Wibias@users.noreply.github.com>
Date: Thu, 23 Jul 2026 00:32:30 +0200
Subject: [PATCH 2/4] fix(gui): fix rail row border clipping (outline -> inset
shadow)
---
gui/src/styles-claudecode-workspace.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gui/src/styles-claudecode-workspace.css b/gui/src/styles-claudecode-workspace.css
index 091a09552..bd412be95 100644
--- a/gui/src/styles-claudecode-workspace.css
+++ b/gui/src/styles-claudecode-workspace.css
@@ -77,7 +77,7 @@
.claudecode-workspace-rail-row--selected {
background: var(--surface-2);
- outline: 1px solid var(--border);
+ box-shadow: inset 0 0 0 1px var(--border);
}
.claudecode-workspace-rail-name {
From 81c6f6fadb7613a6fc02b0939bcce410a7949909 Mon Sep 17 00:00:00 2001
From: Wibias <37517432+Wibias@users.noreply.github.com>
Date: Sat, 25 Jul 2026 11:18:12 +0200
Subject: [PATCH 3/4] fix(gui): polish Claude workspace rail and shared select
focus
Drop the duplicate rail title, align section content with the Settings card top, center toggle knobs, and remove the left inset accent bar from Select menus.
---
gui/src/pages/ClaudeCode.tsx | 3 ---
gui/src/styles-claudecode-workspace.css | 18 +++++-------------
gui/src/styles-combos-workspace.css | 2 +-
gui/src/styles.css | 8 +++-----
4 files changed, 9 insertions(+), 22 deletions(-)
diff --git a/gui/src/pages/ClaudeCode.tsx b/gui/src/pages/ClaudeCode.tsx
index 09663916b..4c82f58af 100644
--- a/gui/src/pages/ClaudeCode.tsx
+++ b/gui/src/pages/ClaudeCode.tsx
@@ -489,9 +489,6 @@ export default function ClaudeCode({ apiBase, viewMode }: { apiBase: string; vie
{status &&
{status}}