From 1a422f06ac43aae9949fb231b0ef15e45cdf0c60 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 25 Mar 2026 16:09:05 -0700 Subject: [PATCH] feat(canvas): add first-time forgotten shapes explainer tooltip Shows a one-time onboarding tooltip when users first encounter a faded (forgotten) shape. Explains right-click to remember/forget permanently, the Hide Forgotten toggle in profile menu, and highlights the Collective Memory graph as a prototype feature. Persisted via localStorage. Co-Authored-By: Claude Opus 4.6 --- website/canvas.html | 123 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/website/canvas.html b/website/canvas.html index dc40c4e..7200f24 100644 --- a/website/canvas.html +++ b/website/canvas.html @@ -1406,6 +1406,84 @@ display: none !important; } + /* First-time forgotten explainer tooltip */ + #forgotten-explainer { + display: none; + position: fixed; + bottom: 24px; + left: 50%; + transform: translateX(-50%); + background: var(--rs-bg-surface, #1e293b); + border: 1px solid var(--rs-border, rgba(255,255,255,0.1)); + border-radius: 14px; + padding: 20px 24px; + max-width: 420px; + width: calc(100vw - 32px); + box-shadow: 0 12px 40px rgba(0,0,0,0.5); + z-index: 300000; + color: var(--rs-text-primary, #e2e8f0); + font-size: 0.85rem; + line-height: 1.55; + animation: explainer-slide-up 0.35s ease-out; + } + @keyframes explainer-slide-up { + from { opacity: 0; transform: translateX(-50%) translateY(20px); } + to { opacity: 1; transform: translateX(-50%) translateY(0); } + } + #forgotten-explainer.visible { display: block; } + #forgotten-explainer h4 { + margin: 0 0 10px; + font-size: 0.95rem; + color: var(--rs-text-primary, #e2e8f0); + } + #forgotten-explainer p { + margin: 0 0 8px; + color: var(--rs-text-secondary, #94a3b8); + } + #forgotten-explainer .tip-row { + display: flex; + align-items: flex-start; + gap: 8px; + margin-bottom: 6px; + } + #forgotten-explainer .tip-icon { + flex-shrink: 0; + font-size: 1rem; + line-height: 1.4; + } + #forgotten-explainer .tip-label { + font-size: 0.82rem; + color: var(--rs-text-secondary, #94a3b8); + } + #forgotten-explainer .tip-label strong { + color: var(--rs-text-primary, #e2e8f0); + } + #forgotten-explainer .proto-badge { + display: inline-block; + font-size: 0.68rem; + padding: 1px 6px; + border-radius: 4px; + background: rgba(124,58,237,0.15); + color: #a78bfa; + margin-left: 4px; + vertical-align: middle; + } + #forgotten-explainer .dismiss-btn { + display: block; + margin: 14px auto 0; + padding: 7px 20px; + background: rgba(20,184,166,0.12); + border: 1px solid rgba(20,184,166,0.25); + color: #14b8a6; + border-radius: 8px; + font-size: 0.82rem; + font-weight: 600; + cursor: pointer; + } + #forgotten-explainer .dismiss-btn:hover { + background: rgba(20,184,166,0.2); + } + /* Cross-space shape styling — colored border + source badge */ .rspace-cross-space-shape { outline: 2px dashed rgba(99, 102, 241, 0.5) !important; @@ -2128,6 +2206,24 @@ +
+

👻 Faded shapes are "forgotten"

+

When you or others close a shape, it doesn't disappear — it fades. This is collective memory.

+
+ 🖱 + Right-click a faded shape to Remember it (restore) or Forget permanently (delete) +
+
+ 👁 + Toggle Hide Forgotten in your profile menu to show/hide faded shapes +
+
+ 🔮 + The Collective Memory graph prototype visualizes what the group remembers vs. forgets +
+ +
+

💭 Recent Changes

@@ -6068,6 +6164,33 @@ Use real coordinates, YYYY-MM-DD dates, ISO currency codes. Ask clarifying quest if (memoryPanel.classList.contains("open")) renderMemoryPanel(); }); + // First-time forgotten explainer tooltip + { + const SEEN_KEY = 'rspace_forgotten_explainer_seen'; + let explainerShown = false; + + function showForgottenExplainer() { + if (explainerShown || localStorage.getItem(SEEN_KEY)) return; + explainerShown = true; + // Delay slightly so the faded shape is visible first + setTimeout(() => { + const el = document.getElementById('forgotten-explainer'); + if (el) el.classList.add('visible'); + }, 800); + } + + document.getElementById('forgotten-explainer-dismiss')?.addEventListener('click', () => { + localStorage.setItem(SEEN_KEY, '1'); + const el = document.getElementById('forgotten-explainer'); + if (el) el.classList.remove('visible'); + }); + + sync.addEventListener("shape-state-changed", (e) => { + if (e.detail?.state === 'forgotten') showForgottenExplainer(); + }); + sync.addEventListener("shape-forgotten", () => showForgottenExplainer()); + } + // Re-dispatch comment-pins-changed on window so header bell can update sync.addEventListener("comment-pins-changed", () => { window.dispatchEvent(new CustomEvent("comment-pins-changed"));