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:
parent
eb05639608
commit
39ca0ff9b7
|
|
@ -440,6 +440,117 @@
|
||||||
touch-action: none; /* Prevent browser gestures, handle manually */
|
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 {
|
#canvas-content {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
@ -915,6 +1026,7 @@
|
||||||
<button id="new-arrow" title="Connect rSpaces">↗️ Connect</button>
|
<button id="new-arrow" title="Connect rSpaces">↗️ Connect</button>
|
||||||
<button id="new-feed" title="New Feed from another layer">🔄 Feed</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-memory" title="Forgotten rSpaces">💭 Memory</button>
|
||||||
|
<button id="toggle-theme" title="Toggle dark mode">🌙 Dark</button>
|
||||||
|
|
||||||
<span class="toolbar-sep"></span>
|
<span class="toolbar-sep"></span>
|
||||||
|
|
||||||
|
|
@ -1025,6 +1137,27 @@
|
||||||
document.querySelector("rstack-app-switcher")?.setModules(data.modules || []);
|
document.querySelector("rstack-app-switcher")?.setModules(data.modules || []);
|
||||||
}).catch(() => {});
|
}).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 ──
|
// ── Tab bar / Layer system initialization ──
|
||||||
const tabBar = document.querySelector("rstack-tab-bar");
|
const tabBar = document.querySelector("rstack-tab-bar");
|
||||||
if (tabBar) {
|
if (tabBar) {
|
||||||
|
|
@ -2567,7 +2700,7 @@
|
||||||
const btn = e.target.closest("button");
|
const btn = e.target.closest("button");
|
||||||
if (!btn) return;
|
if (!btn) return;
|
||||||
// Keep open for connect, memory, group toggles, collapse, whiteboard tools
|
// 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"];
|
"wb-pencil", "wb-sticky", "wb-rect", "wb-circle", "wb-line", "wb-eraser"];
|
||||||
if (btn.classList.contains("toolbar-group-toggle")) return;
|
if (btn.classList.contains("toolbar-group-toggle")) return;
|
||||||
if (!keepOpen.includes(btn.id)) {
|
if (!keepOpen.includes(btn.id)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue