feat: canvas dark mode toggle — persistent theme with dark toolbar, grid, and panels

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-02-27 18:06:35 -08:00
parent eb05639608
commit 39ca0ff9b7
1 changed files with 134 additions and 1 deletions

View File

@ -440,6 +440,117 @@
touch-action: none; /* Prevent browser gestures, handle manually */
}
/* ── Dark mode overrides ── */
body[data-theme="dark"] #canvas {
background-color: #0f172a;
background-image:
linear-gradient(rgba(255,255,255,0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.04) 1px, transparent 1px);
}
body[data-theme="dark"] #toolbar {
background: #1e293b;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
}
body[data-theme="dark"] #toolbar > button,
body[data-theme="dark"] .toolbar-group-toggle {
background: #334155;
color: #e2e8f0;
}
body[data-theme="dark"] #toolbar > button:hover,
body[data-theme="dark"] .toolbar-group-toggle:hover {
background: #475569;
}
body[data-theme="dark"] .toolbar-sep {
background: #334155;
}
body[data-theme="dark"] .toolbar-dropdown,
body[data-theme="dark"] #toolbar-panel {
background: #1e293b;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4);
}
body[data-theme="dark"] .toolbar-dropdown button,
body[data-theme="dark"] #toolbar-panel-body button {
color: #e2e8f0;
}
body[data-theme="dark"] .toolbar-dropdown button:hover,
body[data-theme="dark"] #toolbar-panel-body button:hover {
background: #334155;
}
body[data-theme="dark"] #toolbar-panel-header {
border-bottom-color: #334155;
color: #94a3b8;
}
body[data-theme="dark"] #toolbar-collapse {
color: #64748b;
}
body[data-theme="dark"] #toolbar-collapse:hover {
background: #334155 !important;
color: #e2e8f0;
}
body[data-theme="dark"] #status {
background: #1e293b;
color: #94a3b8;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
body[data-theme="dark"] #community-info {
background: #1e293b;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
body[data-theme="dark"] #community-info h2 {
color: #e2e8f0;
}
body[data-theme="dark"] #community-info p {
color: #94a3b8;
}
body[data-theme="dark"] #memory-panel {
background: #1e293b;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
}
body[data-theme="dark"] #memory-panel-header {
border-bottom-color: #334155;
}
body[data-theme="dark"] #memory-panel-header h3 {
color: #e2e8f0;
}
body[data-theme="dark"] #memory-panel-header .count {
background: #334155;
color: #94a3b8;
}
body[data-theme="dark"] .memory-item:hover {
background: #334155;
}
body[data-theme="dark"] .memory-item .info .name {
color: #e2e8f0;
}
body[data-theme="dark"] .memory-item .info .meta {
color: #64748b;
}
body[data-theme="dark"] #memory-list:empty::after {
color: #64748b;
}
#canvas-content {
position: absolute;
top: 0;
@ -915,6 +1026,7 @@
<button id="new-arrow" title="Connect rSpaces">↗️ Connect</button>
<button id="new-feed" title="New Feed from another layer">🔄 Feed</button>
<button id="toggle-memory" title="Forgotten rSpaces">💭 Memory</button>
<button id="toggle-theme" title="Toggle dark mode">🌙 Dark</button>
<span class="toolbar-sep"></span>
@ -1025,6 +1137,27 @@
document.querySelector("rstack-app-switcher")?.setModules(data.modules || []);
}).catch(() => {});
// ── Dark mode toggle ──
{
const savedTheme = localStorage.getItem("canvas-theme") || "light";
const themeBtn = document.getElementById("toggle-theme");
function applyTheme(theme) {
document.body.setAttribute("data-theme", theme);
document.querySelector(".rstack-header")?.setAttribute("data-theme", theme);
document.querySelector(".rstack-tab-row")?.setAttribute("data-theme", theme);
if (themeBtn) themeBtn.textContent = theme === "dark" ? "☀️ Light" : "🌙 Dark";
}
applyTheme(savedTheme);
themeBtn?.addEventListener("click", () => {
const next = document.body.getAttribute("data-theme") === "dark" ? "light" : "dark";
applyTheme(next);
localStorage.setItem("canvas-theme", next);
});
}
// ── Tab bar / Layer system initialization ──
const tabBar = document.querySelector("rstack-tab-bar");
if (tabBar) {
@ -2567,7 +2700,7 @@
const btn = e.target.closest("button");
if (!btn) return;
// Keep open for connect, memory, group toggles, collapse, whiteboard tools
const keepOpen = ["new-arrow", "toggle-memory", "zoom-in", "zoom-out", "reset-view", "toolbar-collapse",
const keepOpen = ["new-arrow", "toggle-memory", "toggle-theme", "zoom-in", "zoom-out", "reset-view", "toolbar-collapse",
"wb-pencil", "wb-sticky", "wb-rect", "wb-circle", "wb-line", "wb-eraser"];
if (btn.classList.contains("toolbar-group-toggle")) return;
if (!keepOpen.includes(btn.id)) {