fix(desktop): external gateway mode and start script alignment

- Add desktop env for non-embedded gateway (OCLAW_DESKTOP_EMBED_BACKEND, base URL, skip channel).
- Wire start_all/start_desktop to pass gateway URL when keeping existing gateway; fix root start_all flags.
- Prefer electron.cmd for background desktop launch; admin static theme presets and chat boot timeouts.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-05-06 11:06:16 +08:00
parent 19e51e2c12
commit 16169b3de2
12 changed files with 566 additions and 45 deletions

View file

@ -0,0 +1,51 @@
/* Admin + standalone /chat: restore palette from localStorage before first paint. */
(function () {
const STORAGE_KEY = "oclaw_admin_theme";
const THEMES = ["deepseek", "github", "nord", "dracula", "forest", "catppuccin", "light"];
const LEGIT = new Set(THEMES);
function applyAdminTheme(theme) {
const t = theme && LEGIT.has(theme) ? theme : "deepseek";
if (t === "deepseek") document.body.removeAttribute("data-admin-theme");
else document.body.setAttribute("data-admin-theme", t);
}
function initAdminThemeFromStorage() {
let raw = "deepseek";
try {
raw = localStorage.getItem(STORAGE_KEY) || "deepseek";
} catch (_) {
raw = "deepseek";
}
if (!LEGIT.has(raw)) raw = "deepseek";
applyAdminTheme(raw);
return raw;
}
function persistAdminTheme(theme) {
const t = theme && LEGIT.has(theme) ? theme : "deepseek";
try {
localStorage.setItem(STORAGE_KEY, t);
} catch (_) {}
applyAdminTheme(t);
}
function currentAdminTheme() {
try {
const v = localStorage.getItem(STORAGE_KEY);
return v && LEGIT.has(v) ? v : "deepseek";
} catch (_) {
return "deepseek";
}
}
window.OclawAdminTheme = {
STORAGE_KEY,
THEMES,
applyAdminTheme,
initAdminThemeFromStorage,
persistAdminTheme,
currentAdminTheme,
};
initAdminThemeFromStorage();
})();

View file

@ -232,6 +232,14 @@ const I18N = {
"common.notFound": "未找到页面",
"common.forbidden": "无权访问该页面。",
"common.error": "错误",
"theme.label": "界面配色",
"theme.deepseek": "DeepSeek 默认",
"theme.github": "GitHub 暗色",
"theme.nord": "Nord",
"theme.dracula": "Dracula",
"theme.forest": "森绿",
"theme.catppuccin": "Catppuccin Mocha",
"theme.light": "浅色",
"lang.switch": "English",
"memory.title": "记忆治理",
"memory.hits": "最近命中",
@ -665,6 +673,14 @@ const I18N = {
"common.notFound": "Not found",
"common.forbidden": "You do not have access to this page.",
"common.error": "Error",
"theme.label": "Color theme",
"theme.deepseek": "DeepSeek (default)",
"theme.github": "GitHub Dark",
"theme.nord": "Nord",
"theme.dracula": "Dracula",
"theme.forest": "Forest",
"theme.catppuccin": "Catppuccin Mocha",
"theme.light": "Light",
"lang.switch": "中文",
"memory.title": "Memory Governance",
"memory.hits": "Recent Hits",
@ -997,6 +1013,12 @@ function applyI18nStatic() {
});
const langBtn = document.getElementById("btnLang");
if (langBtn) langBtn.textContent = t("lang.switch");
const themeSel = document.getElementById("adminThemeSelect");
if (themeSel && window.OclawAdminTheme) {
try {
themeSel.value = OclawAdminTheme.currentAdminTheme();
} catch (_) {}
}
}
function toggleLang() {
@ -9164,6 +9186,14 @@ if (btnLangEl) btnLangEl.addEventListener("click", () => {
toggleLang();
router();
});
const adminThemeSelectEl = document.getElementById("adminThemeSelect");
if (adminThemeSelectEl && window.OclawAdminTheme) {
adminThemeSelectEl.addEventListener("change", () => {
try {
window.OclawAdminTheme.persistAdminTheme(adminThemeSelectEl.value);
} catch (_) {}
});
}
const btnBackChatEl = document.getElementById("btnBackChat");
if (btnBackChatEl) {
try {

View file

@ -7,6 +7,7 @@
<!-- Avoid render-blocking external fonts (can stall first paint ~30s on blocked networks). -->
<link rel="stylesheet" href="/admin/assets/styles.css" />
<link rel="stylesheet" href="/admin/assets/theme-deepseek.css" />
<link rel="stylesheet" href="/admin/assets/theme-presets.css" />
<style>
body.theme-ds-body.chat-standalone-page {
margin: 0;
@ -561,9 +562,10 @@
onload="(function(){try{ if (window.__oclawHydrateMermaidAll) window.__oclawHydrateMermaidAll(); }catch(e){}})()"
></script>
<!-- Cache-bust for desktop webview: avoid stale chat.js -->
<script defer src="/admin/assets/admin-theme.js"></script>
<script
defer
src="/admin/assets/chat.js?v=20260501-1"
src="/admin/assets/chat.js?v=20260507-2"
onerror="(function(){var s=document.getElementById('chat-boot-splash');if(s){s.querySelector('.chat-boot-splash__title span:last-child').textContent='无法加载 chat.js';s.querySelector('.chat-boot-splash__muted').textContent='请确认网关已启动且 /admin/assets/chat.js 可访问。';}})()"
></script>
</head>

View file

@ -66,6 +66,14 @@ const I18N = {
"auth.chatLoginDenied": "当前账号无法使用对话(请联系管理员)。",
"auth.disabled": "账号已被禁用,请联系管理员",
"common.error": "错误",
"theme.label": "界面配色",
"theme.deepseek": "DeepSeek 默认",
"theme.github": "GitHub 暗色",
"theme.nord": "Nord",
"theme.dracula": "Dracula",
"theme.forest": "森绿",
"theme.catppuccin": "Catppuccin Mocha",
"theme.light": "浅色",
"lang.switch": "English",
"chat.imageViewerClose": "关闭",
"chat.imageViewerHint": "点击查看大图,空白处或 Esc 关闭",
@ -234,6 +242,14 @@ const I18N = {
"auth.chatLoginDenied": "This account cannot use chat (contact an admin).",
"auth.disabled": "Account is disabled",
"common.error": "Error",
"theme.label": "Color theme",
"theme.deepseek": "DeepSeek (default)",
"theme.github": "GitHub Dark",
"theme.nord": "Nord",
"theme.dracula": "Dracula",
"theme.forest": "Forest",
"theme.catppuccin": "Catppuccin Mocha",
"theme.light": "Light",
"lang.switch": "中文",
"chat.imageViewerClose": "Close",
"chat.imageViewerHint": "Click image to enlarge; click outside or Esc to close",
@ -2372,6 +2388,26 @@ function syncAuthUserLabel() {
text: t("chat.myProfile"),
}),
];
items.push(el("div", { class: "chat-sess-menu-sep" }));
items.push(
el("div", { class: "muted", style: "padding:6px 10px 2px;font-size:12px;", text: t("theme.label") }),
);
const themeSelMenu = el("select", {
class: "input",
style: "width:100%;margin:4px 8px 8px;max-width:calc(100% - 16px);",
});
try {
(window.OclawAdminTheme && window.OclawAdminTheme.THEMES ? window.OclawAdminTheme.THEMES : ["deepseek"]).forEach((tid) => {
themeSelMenu.appendChild(el("option", { value: tid, text: t(`theme.${tid}`) }));
});
themeSelMenu.value = window.OclawAdminTheme ? window.OclawAdminTheme.currentAdminTheme() : "deepseek";
} catch (_) {}
themeSelMenu.addEventListener("change", () => {
try {
if (window.OclawAdminTheme) window.OclawAdminTheme.persistAdminTheme(themeSelMenu.value);
} catch (_) {}
});
items.push(themeSelMenu);
const bridge = window.__chatUserMenuPrefs;
if (bridge && typeof bridge === "object") {
items.push(el("div", { class: "chat-sess-menu-sep" }));

View file

@ -7,6 +7,7 @@
<!-- Avoid render-blocking external fonts (can stall first paint ~30s on blocked networks). -->
<link rel="stylesheet" href="/admin/assets/styles.css" />
<link rel="stylesheet" href="/admin/assets/theme-deepseek.css" />
<link rel="stylesheet" href="/admin/assets/theme-presets.css" />
<style>
/* First paint before app.js runs: keep admin from showing a blank dark screen. */
.admin-boot-splash {
@ -47,6 +48,7 @@
</style>
</head>
<body class="theme-ds-body">
<script src="/admin/assets/admin-theme.js"></script>
<div class="layout">
<aside class="sidebar">
<div class="brand">
@ -101,6 +103,18 @@
<div id="topTitle" class="topbar__title">Runtime</div>
<div class="topbar__actions">
<span id="authUser" class="muted"></span>
<label class="admin-theme-wrap" style="display: inline-flex; align-items: center; gap: 6px; margin-right: 4px">
<span class="muted" style="font-size: 12px" data-i18n="theme.label">配色</span>
<select id="adminThemeSelect" class="input input--compact" style="min-width: 132px; max-width: 200px; padding: 6px 8px" aria-label="theme">
<option value="deepseek" data-i18n="theme.deepseek">DeepSeek</option>
<option value="github" data-i18n="theme.github">GitHub</option>
<option value="nord" data-i18n="theme.nord">Nord</option>
<option value="dracula" data-i18n="theme.dracula">Dracula</option>
<option value="forest" data-i18n="theme.forest">Forest</option>
<option value="catppuccin" data-i18n="theme.catppuccin">Catppuccin</option>
<option value="light" data-i18n="theme.light">Light</option>
</select>
</label>
<a id="btnBackChat" class="btn" data-i18n="nav.chat" href="chat">对话</a>
<button id="btnLogout" class="btn" data-i18n="auth.logout">退出登录</button>
<button id="btnLang" class="btn">中文</button>
@ -120,7 +134,7 @@
</div>
<script
defer
src="/admin/assets/app.js?v=20260425-1"
src="/admin/assets/app.js?v=20260507-2"
onerror="(function(){var s=document.getElementById('admin-boot-splash');if(s){s.querySelector('.admin-boot-splash__title span:last-child').textContent='无法加载 app.js';s.querySelector('.admin-boot-splash__muted').textContent='请确认 /admin/assets/app.js 可访问。';}})()"
></script>
</body>

View file

@ -11,6 +11,17 @@ body.theme-ds-body {
--ds-text-muted: rgba(232, 232, 232, 0.55);
--ds-accent: #5eb3ff;
--ds-accent-soft: rgba(94, 179, 255, 0.18);
--ds-sidebar: #161618;
--ds-topbar-bg: rgba(22, 22, 24, 0.92);
--ds-accent-border: rgba(94, 179, 255, 0.25);
--ds-accent-border-strong: rgba(94, 179, 255, 0.45);
--ds-accent-link: rgba(94, 179, 255, 0.95);
--ds-accent-scrollbar: rgba(94, 179, 255, 0.45);
--ds-accent-scrollbar-hover: rgba(94, 179, 255, 0.65);
--ds-panel: #222224;
--ds-chat-scroll-track: #2e2e2e;
--ds-chat-scroll-thumb: #7a7a7a;
--ds-chat-scroll-thumb-hover: #909090;
/* 左侧会话列表:贴近侧栏 #0d0d0d,选中仅略提亮 */
--chat-sess-hover-bg: rgba(255, 255, 255, 0.05);
--chat-sess-active-bg: rgba(255, 255, 255, 0.062);
@ -21,7 +32,7 @@ body.theme-ds-body {
}
body.theme-ds-body .layout .sidebar {
background: #161618;
background: var(--ds-sidebar);
border-right-color: var(--ds-border);
}
@ -36,7 +47,7 @@ body.theme-ds-body .nav__item:hover {
body.theme-ds-body .nav__item--active {
background: var(--ds-accent-soft);
border: 1px solid rgba(94, 179, 255, 0.25);
border: 1px solid var(--ds-accent-border);
color: var(--ds-text);
}
@ -49,7 +60,7 @@ body.theme-ds-body .main {
}
body.theme-ds-body .topbar {
background: rgba(22, 22, 24, 0.92);
background: var(--ds-topbar-bg);
border-bottom-color: var(--ds-border);
}
@ -78,7 +89,7 @@ body.theme-ds-body .btn:hover {
body.theme-ds-body .btn--primary {
background: var(--ds-accent-soft);
border-color: rgba(94, 179, 255, 0.45);
border-color: var(--ds-accent-border-strong);
color: var(--ds-text);
}
@ -276,7 +287,7 @@ body.theme-ds-body .card {
.chat-nav__link {
display: inline-block;
font-size: 13px;
color: rgba(94, 179, 255, 0.95);
color: var(--ds-accent-link);
text-decoration: none;
}
@ -379,7 +390,7 @@ body.theme-ds-body .card {
.chat-pending-files:hover,
.table-wrap:hover,
.session-monitor-modal__card:hover {
scrollbar-color: rgba(94, 179, 255, 0.45) rgba(255, 255, 255, 0.06);
scrollbar-color: var(--ds-accent-scrollbar) rgba(255, 255, 255, 0.06);
}
.chat-msg__reasoning-pre::-webkit-scrollbar,
@ -425,14 +436,14 @@ body.theme-ds-body .card {
.chat-pending-files:hover::-webkit-scrollbar-thumb,
.table-wrap:hover::-webkit-scrollbar-thumb,
.session-monitor-modal__card:hover::-webkit-scrollbar-thumb {
background: rgba(94, 179, 255, 0.45);
background: var(--ds-accent-scrollbar);
}
.chat-msg__reasoning-pre::-webkit-scrollbar-thumb:hover,
.chat-pending-files::-webkit-scrollbar-thumb:hover,
.table-wrap::-webkit-scrollbar-thumb:hover,
.session-monitor-modal__card::-webkit-scrollbar-thumb:hover {
background: rgba(94, 179, 255, 0.65);
background: var(--ds-accent-scrollbar-hover);
}
.chat-msg {
@ -973,7 +984,7 @@ body.chat-standalone-page .chat-nav__scroll::-webkit-scrollbar {
body.chat-standalone-page .chat-messages {
scrollbar-width: thin;
scrollbar-color: #7a7a7a #2e2e2e;
scrollbar-color: var(--ds-chat-scroll-thumb) var(--ds-chat-scroll-track);
}
body.chat-standalone-page .chat-messages::-webkit-scrollbar {
@ -982,14 +993,14 @@ body.chat-standalone-page .chat-messages::-webkit-scrollbar {
}
body.chat-standalone-page .chat-messages::-webkit-scrollbar-track {
background: #2e2e2e;
background: var(--ds-chat-scroll-track);
}
body.chat-standalone-page .chat-messages::-webkit-scrollbar-thumb {
background: #7a7a7a;
background: var(--ds-chat-scroll-thumb);
border-radius: 0;
}
body.chat-standalone-page .chat-messages::-webkit-scrollbar-thumb:hover {
background: #909090;
background: var(--ds-chat-scroll-thumb-hover);
}

View file

@ -0,0 +1,233 @@
/* Classic admin/chat palettes: override CSS variables on body.theme-ds-body[data-admin-theme="…"].
Default (no attribute or deepseek) stays in theme-deepseek.css. */
body.theme-ds-body[data-admin-theme="github"] {
--ds-bg: #0d1117;
--ds-chat-main: #010409;
--ds-surface: #161b22;
--ds-surface-2: #21262d;
--ds-border: rgba(240, 246, 252, 0.1);
--ds-text: #f0f6fc;
--ds-text-muted: rgba(240, 246, 252, 0.55);
--ds-accent: #58a6ff;
--ds-accent-soft: rgba(88, 166, 255, 0.16);
--ds-sidebar: #161b22;
--ds-topbar-bg: rgba(22, 27, 34, 0.94);
--ds-accent-border: rgba(88, 166, 255, 0.32);
--ds-accent-border-strong: rgba(88, 166, 255, 0.55);
--ds-accent-link: rgba(88, 166, 255, 0.95);
--ds-accent-scrollbar: rgba(88, 166, 255, 0.45);
--ds-accent-scrollbar-hover: rgba(88, 166, 255, 0.68);
--ds-panel: #21262d;
--ds-chat-scroll-track: #21262d;
--ds-chat-scroll-thumb: #484f58;
--ds-chat-scroll-thumb-hover: #6e7681;
--chat-sess-hover-bg: rgba(240, 246, 252, 0.06);
--chat-sess-active-bg: rgba(240, 246, 252, 0.08);
--chat-sess-border: rgba(240, 246, 252, 0.12);
}
body.theme-ds-body[data-admin-theme="nord"] {
--ds-bg: #2e3440;
--ds-chat-main: #242933;
--ds-surface: #3b4252;
--ds-surface-2: #434c5e;
--ds-border: rgba(236, 239, 244, 0.12);
--ds-text: #eceff4;
--ds-text-muted: rgba(236, 239, 244, 0.55);
--ds-accent: #88c0d0;
--ds-accent-soft: rgba(136, 192, 208, 0.2);
--ds-sidebar: #3b4252;
--ds-topbar-bg: rgba(59, 66, 82, 0.95);
--ds-accent-border: rgba(136, 192, 208, 0.35);
--ds-accent-border-strong: rgba(136, 192, 208, 0.55);
--ds-accent-link: rgba(143, 188, 187, 0.98);
--ds-accent-scrollbar: rgba(136, 192, 208, 0.5);
--ds-accent-scrollbar-hover: rgba(143, 188, 187, 0.75);
--ds-panel: #434c5e;
--ds-chat-scroll-track: #3b4252;
--ds-chat-scroll-thumb: #5e81ac;
--ds-chat-scroll-thumb-hover: #81a1c1;
--chat-user-bubble-bg: #a3be8c;
--chat-user-bubble-fg: #2e3440;
}
body.theme-ds-body[data-admin-theme="dracula"] {
--ds-bg: #282a36;
--ds-chat-main: #1e1f29;
--ds-surface: #44475a;
--ds-surface-2: #6272a4;
--ds-border: rgba(248, 248, 242, 0.1);
--ds-text: #f8f8f2;
--ds-text-muted: rgba(248, 248, 242, 0.55);
--ds-accent: #bd93f9;
--ds-accent-soft: rgba(189, 147, 249, 0.22);
--ds-sidebar: #44475a;
--ds-topbar-bg: rgba(68, 71, 90, 0.95);
--ds-accent-border: rgba(189, 147, 249, 0.4);
--ds-accent-border-strong: rgba(189, 147, 249, 0.6);
--ds-accent-link: rgba(255, 121, 198, 0.95);
--ds-accent-scrollbar: rgba(189, 147, 249, 0.5);
--ds-accent-scrollbar-hover: rgba(255, 121, 198, 0.65);
--ds-panel: #44475a;
--ds-chat-scroll-track: #21222c;
--ds-chat-scroll-thumb: #6272a4;
--ds-chat-scroll-thumb-hover: #bd93f9;
}
body.theme-ds-body[data-admin-theme="forest"] {
--ds-bg: #0c1412;
--ds-chat-main: #070d0b;
--ds-surface: #13251f;
--ds-surface-2: #1a332b;
--ds-border: rgba(167, 243, 208, 0.1);
--ds-text: #ecfdf5;
--ds-text-muted: rgba(209, 250, 229, 0.55);
--ds-accent: #34d399;
--ds-accent-soft: rgba(52, 211, 153, 0.18);
--ds-sidebar: #13251f;
--ds-topbar-bg: rgba(19, 37, 31, 0.94);
--ds-accent-border: rgba(52, 211, 153, 0.35);
--ds-accent-border-strong: rgba(52, 211, 153, 0.55);
--ds-accent-link: rgba(110, 231, 183, 0.95);
--ds-accent-scrollbar: rgba(52, 211, 153, 0.45);
--ds-accent-scrollbar-hover: rgba(110, 231, 183, 0.7);
--ds-panel: #1a332b;
--ds-chat-scroll-track: #13251f;
--ds-chat-scroll-thumb: #047857;
--ds-chat-scroll-thumb-hover: #059669;
}
body.theme-ds-body[data-admin-theme="catppuccin"] {
--ds-bg: #1e1e2e;
--ds-chat-main: #181825;
--ds-surface: #313244;
--ds-surface-2: #45475a;
--ds-border: rgba(205, 214, 244, 0.1);
--ds-text: #cdd6f4;
--ds-text-muted: rgba(205, 214, 244, 0.52);
--ds-accent: #89b4fa;
--ds-accent-soft: rgba(137, 180, 250, 0.2);
--ds-sidebar: #313244;
--ds-topbar-bg: rgba(49, 50, 68, 0.95);
--ds-accent-border: rgba(137, 180, 250, 0.38);
--ds-accent-border-strong: rgba(137, 180, 250, 0.58);
--ds-accent-link: rgba(166, 218, 249, 0.96);
--ds-accent-scrollbar: rgba(137, 180, 250, 0.48);
--ds-accent-scrollbar-hover: rgba(166, 218, 249, 0.72);
--ds-panel: #45475a;
--ds-chat-scroll-track: #313244;
--ds-chat-scroll-thumb: #6c7086;
--ds-chat-scroll-thumb-hover: #89b4fa;
}
/* Light: same pipeline as dark presets (CSS variables on body) + a small set of chat/sidebar
tweaks where theme-deepseek.css still used “white mist” tints meant for dark canvases. */
body.theme-ds-body[data-admin-theme="light"] {
--ds-bg: #f1f5f9;
--ds-chat-main: #ffffff;
--ds-surface: #ffffff;
--ds-surface-2: #e2e8f0;
--ds-border: rgba(15, 23, 42, 0.12);
--ds-text: #0f172a;
--ds-text-muted: rgba(15, 23, 42, 0.55);
--ds-accent: #2563eb;
--ds-accent-soft: rgba(37, 99, 235, 0.14);
--ds-sidebar: #f8fafc;
--ds-topbar-bg: rgba(248, 250, 252, 0.92);
--ds-accent-border: rgba(37, 99, 235, 0.35);
--ds-accent-border-strong: rgba(37, 99, 235, 0.55);
--ds-accent-link: #1d4ed8;
--ds-accent-scrollbar: rgba(37, 99, 235, 0.42);
--ds-accent-scrollbar-hover: rgba(29, 78, 216, 0.62);
--ds-panel: #ffffff;
--ds-chat-scroll-track: #e2e8f0;
--ds-chat-scroll-thumb: #94a3b8;
--ds-chat-scroll-thumb-hover: #64748b;
--chat-sess-hover-bg: rgba(15, 23, 42, 0.06);
--chat-sess-active-bg: rgba(15, 23, 42, 0.09);
--chat-sess-border: rgba(15, 23, 42, 0.1);
--chat-user-bubble-bg: #10b981;
--chat-user-bubble-fg: #ffffff;
}
body.theme-ds-body[data-admin-theme="light"] .nav__groupTitle {
color: rgba(15, 23, 42, 0.48);
}
body.theme-ds-body[data-admin-theme="light"] .brand__sub {
color: rgba(15, 23, 42, 0.55);
}
body.theme-ds-body[data-admin-theme="light"] .chat-nav__newGlyph {
background-color: rgba(15, 23, 42, 0.08);
}
body.theme-ds-body[data-admin-theme="light"] .chat-nav__new:hover .chat-nav__newGlyph {
background-color: rgba(15, 23, 42, 0.14);
}
body.theme-ds-body[data-admin-theme="light"] .chat-nav__newGlyph::before,
body.theme-ds-body[data-admin-theme="light"] .chat-nav__newGlyph::after {
background-color: #0f172a;
}
body.theme-ds-body[data-admin-theme="light"] .chat-avatar--bot,
body.theme-ds-body[data-admin-theme="light"] .chat-avatar--userBuiltin {
background: rgba(15, 23, 42, 0.06);
}
body.theme-ds-body[data-admin-theme="light"] .chat-msg--assistant {
background: rgba(15, 23, 42, 0.045);
border-color: var(--ds-border);
}
body.theme-ds-body[data-admin-theme="light"] .chat-msg__action-btn {
border-color: rgba(15, 23, 42, 0.2);
color: rgba(15, 23, 42, 0.78);
}
body.theme-ds-body[data-admin-theme="light"] .chat-msg__action-btn:hover {
background: rgba(15, 23, 42, 0.06);
}
body.theme-ds-body[data-admin-theme="light"] .chat-msg--tool {
background: rgba(15, 23, 42, 0.06);
border-color: rgba(15, 23, 42, 0.18);
color: rgba(15, 23, 42, 0.88);
}
body.theme-ds-body[data-admin-theme="light"] .chat-msg--thinking {
background: rgba(15, 23, 42, 0.04);
border-color: rgba(15, 23, 42, 0.12);
}
body.theme-ds-body[data-admin-theme="light"] .chat-task-stage {
border-color: rgba(15, 23, 42, 0.12);
background: rgba(15, 23, 42, 0.03);
}
body.theme-ds-body[data-admin-theme="light"] .chat-task-stage__toggle {
border-color: rgba(15, 23, 42, 0.14);
background: rgba(15, 23, 42, 0.04);
}
body.theme-ds-body[data-admin-theme="light"] .chat-composer {
border-top-color: rgba(15, 23, 42, 0.08);
}
body.theme-ds-body[data-admin-theme="light"] .chat-msg__reasoning {
border-color: rgba(15, 23, 42, 0.1);
background: rgba(15, 23, 42, 0.03);
}
body.theme-ds-body[data-admin-theme="light"] .chat-msg__reasoning-pre {
background: rgba(15, 23, 42, 0.05);
border-color: rgba(15, 23, 42, 0.08);
color: var(--ds-text);
}
body.theme-ds-body[data-admin-theme="light"] .chat-msg__md .mermaid {
border-color: rgba(15, 23, 42, 0.14);
background: rgba(248, 250, 252, 0.95);
}