- {rows.map(a => (
+ {aliasRows.map(a => (
{a.id}
{a.display_name}
@@ -461,4 +472,58 @@ 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..2e6e256c6
--- /dev/null
+++ b/gui/src/styles-claudecode-workspace.css
@@ -0,0 +1,136 @@
+/* ============================================================================
+ 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-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);
+ box-shadow: inset 0 0 0 1px 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;
+}
+
+/* Match Settings: section titles must not push content below the Settings card top. */
+.ccw-body > .h-section {
+ margin-top: 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-combos-workspace.css b/gui/src/styles-combos-workspace.css
index 649898ecd..452a0c1bd 100644
--- a/gui/src/styles-combos-workspace.css
+++ b/gui/src/styles-combos-workspace.css
@@ -117,7 +117,7 @@
.combos-workspace-rail-row.combos-workspace-rail-row--selected {
background: var(--accent-soft);
- box-shadow: inset 3px 0 0 var(--accent);
+ box-shadow: inset 0 0 0 1px var(--border);
}
.combos-workspace-rail-row:focus-visible {
diff --git a/gui/src/styles.css b/gui/src/styles.css
index ec6f21ac4..9d8982e25 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 */
@@ -670,11 +671,11 @@ select.input { appearance: none; }
/* Keyboard / aria-activedescendant focus — visible without relying on :hover. */
.select-option-active {
background: var(--hover);
- box-shadow: inset 2px 0 0 var(--accent);
}
+/* Selected + keyboard-highlighted: full inset ring (not a left stripe). */
.select-option.active.select-option-active {
background: var(--accent-soft);
- box-shadow: inset 2px 0 0 var(--accent);
+ box-shadow: inset 0 0 0 1px var(--accent);
}
/* ---- switch ---- */
@@ -815,7 +816,7 @@ dialog.modal-overlay::backdrop {
.bar-amber { background: linear-gradient(90deg, var(--green), var(--amber)); }
.toggle { width: var(--toggle-w); height: var(--toggle-h); border-radius: var(--radius-pill); background: var(--toggle-off-bg); border: 1px solid var(--border); cursor: pointer; position: relative; transition: background var(--motion-normal), border-color var(--motion-normal); flex-shrink: 0; }
.toggle.on { background: var(--toggle-on-bg); border-color: var(--toggle-on-bg); }
-.toggle-knob { width: 16px; height: 16px; background: light-dark(#ffffff, #ececec); border-radius: var(--radius-round); position: absolute; top: 1px; left: 1px; transition: left var(--motion-normal), background var(--motion-normal); }
+.toggle-knob { width: 16px; height: 16px; background: light-dark(#ffffff, #ececec); border-radius: var(--radius-round); position: absolute; top: 50%; left: 1px; transform: translateY(-50%); transition: left var(--motion-normal), background var(--motion-normal); }
.toggle.on .toggle-knob { left: 17px; background: var(--toggle-dot-color); }
.toggle:disabled { cursor: not-allowed; opacity: 0.55; }
.codex-auto-switch-card { gap: 16px; flex-wrap: wrap; }
@@ -1167,9 +1168,9 @@ button.prov-account-row.active { cursor: default; }
.toggle { position: relative; display: inline-block; width: var(--toggle-w); height: var(--toggle-h); flex-shrink: 0; }
.toggle input { opacity: 0; width: 0; height: 0; position: absolute; }
.toggle .slider { position: absolute; inset: 0; background: var(--toggle-off-bg); border-radius: var(--radius-pill); cursor: pointer; transition: background var(--motion-normal) ease; }
-.toggle .slider::after { content: ""; position: absolute; top: 3px; left: 3px; width: var(--toggle-dot); height: var(--toggle-dot); background: var(--toggle-dot-color); border-radius: var(--radius-round); transition: transform var(--motion-normal) ease; }
+.toggle .slider::after { content: ""; position: absolute; top: 50%; left: 3px; width: var(--toggle-dot); height: var(--toggle-dot); background: var(--toggle-dot-color); border-radius: var(--radius-round); transform: translateY(-50%); transition: transform var(--motion-normal) ease; }
.toggle input:checked + .slider { background: var(--toggle-on-bg); }
-.toggle input:checked + .slider::after { transform: translateX(calc(var(--toggle-w) - var(--toggle-dot) - 6px)); }
+.toggle input:checked + .slider::after { transform: translate(calc(var(--toggle-w) - var(--toggle-dot) - 6px), -50%); }
.toggle input:focus-visible + .slider { outline: 2px solid var(--accent-ring); outline-offset: 2px; }
.toggle input:disabled + .slider { opacity: 0.5; cursor: not-allowed; }