diff --git a/modules/rflows/components/flows.css b/modules/rflows/components/flows.css
index 23436fa..42a1b11 100644
--- a/modules/rflows/components/flows.css
+++ b/modules/rflows/components/flows.css
@@ -241,8 +241,8 @@
width: 100%; height: 100%; display: block;
cursor: grab;
background-color: var(--rs-canvas-bg);
- background-image: radial-gradient(circle, var(--rs-canvas-grid) 1px, transparent 1px);
- background-size: 20px 20px;
+ background-image: var(--rs-canvas-bg-image);
+ background-size: var(--rs-canvas-bg-size);
}
.flows-canvas-svg.panning { cursor: grabbing; }
.flows-canvas-svg.dragging { cursor: move; }
diff --git a/server/shell.ts b/server/shell.ts
index df55b0f..2e369b1 100644
--- a/server/shell.ts
+++ b/server/shell.ts
@@ -111,7 +111,7 @@ export function renderShell(opts: ShellOptions): string {
${escapeHtml(title)}
-
+
diff --git a/shared/components/rstack-identity.ts b/shared/components/rstack-identity.ts
index f42449a..1da3f8e 100644
--- a/shared/components/rstack-identity.ts
+++ b/shared/components/rstack-identity.ts
@@ -362,6 +362,14 @@ export class RStackIdentity extends HTMLElement {
🌙
+
+
Canvas
+
+
+
+
+
+
@@ -406,6 +414,22 @@ export class RStackIdentity extends HTMLElement {
this.dispatchEvent(new CustomEvent("theme-change", { bubbles: true, composed: true, detail: { theme: newTheme } }));
});
}
+
+ // Canvas background style selector
+ const canvasBgOptions = this.#shadow.getElementById("canvas-bg-options");
+ if (canvasBgOptions) {
+ canvasBgOptions.addEventListener("click", (e) => {
+ e.stopPropagation();
+ const btn = (e.target as HTMLElement).closest("[data-bg]") as HTMLElement | null;
+ if (!btn) return;
+ const bg = btn.dataset.bg!;
+ localStorage.setItem("canvas-bg", bg);
+ document.documentElement.setAttribute("data-canvas-bg", bg);
+ canvasBgOptions.querySelectorAll(".canvas-opt").forEach(b => b.classList.remove("active"));
+ btn.classList.add("active");
+ window.dispatchEvent(new Event("canvas-bg-change"));
+ });
+ }
} else {
this.#shadow.innerHTML = `
@@ -1402,6 +1426,28 @@ const STYLES = `
.theme-toggle input:checked + .theme-slider { background: #6366f1; }
.theme-toggle input:checked + .theme-slider::before { transform: translateX(18px); }
+/* Canvas background selector in dropdown */
+.dropdown-canvas-row {
+ display: flex; align-items: center; justify-content: center;
+ gap: 8px; padding: 6px 16px;
+}
+.canvas-label {
+ font-size: 0.7rem; font-weight: 600; opacity: 0.5;
+ text-transform: uppercase; letter-spacing: 0.04em;
+}
+.canvas-options { display: flex; gap: 4px; }
+.canvas-opt {
+ font-size: 0.65rem; font-weight: 600; padding: 3px 8px;
+ border: 1px solid var(--rs-border); border-radius: 6px;
+ background: transparent; color: var(--rs-text-secondary);
+ cursor: pointer; transition: all 0.15s;
+}
+.canvas-opt:hover { background: var(--rs-bg-hover); }
+.canvas-opt.active {
+ background: var(--rs-accent); color: white;
+ border-color: var(--rs-accent);
+}
+
/* Avatar wrapper + notification badge */
.avatar-wrap { position: relative; }
.notif-badge {
diff --git a/website/canvas.html b/website/canvas.html
index e6364ed..b3d221d 100644
--- a/website/canvas.html
+++ b/website/canvas.html
@@ -11,7 +11,7 @@
rSpace Canvas
-
+