[object Object]

← back to Ventura Claw

/admin/services-leads: dark/light theme toggle (sun/moon button) with anti-flash inline script + localStorage persistence; per CLAUDE.md sun/moon rule

8d0f1e1f9809b49ae4233e15b401204450e59dd9 · 2026-05-06 19:52:22 -0700 · Steve

Files touched

Diff

commit 8d0f1e1f9809b49ae4233e15b401204450e59dd9
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed May 6 19:52:22 2026 -0700

    /admin/services-leads: dark/light theme toggle (sun/moon button) with anti-flash inline script + localStorage persistence; per CLAUDE.md sun/moon rule
---
 server/public/admin-services-leads.html | 40 +++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/server/public/admin-services-leads.html b/server/public/admin-services-leads.html
index 2408ad5..5fbc11c 100644
--- a/server/public/admin-services-leads.html
+++ b/server/public/admin-services-leads.html
@@ -4,6 +4,15 @@
 <meta charset="utf-8" />
 <meta name="viewport" content="width=device-width,initial-scale=1" />
 <title>Services Leads — VenturaClaw Admin</title>
+<script>
+  // Anti-flash: apply theme before paint so light-mode users don't see a black flash
+  (function () {
+    try {
+      var t = localStorage.getItem('vc-theme') || 'dark';
+      if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
+    } catch (e) {}
+  })();
+</script>
 <style>
   :root {
     --bg: #0e0e10; --bg-2: #15151a; --bg-3: #1c1c22;
@@ -15,6 +24,27 @@
     --mono: "JetBrains Mono", "SFMono-Regular", Menlo, monospace;
     --sans: -apple-system, "SF Pro Text", system-ui, sans-serif;
   }
+  html[data-theme="light"] {
+    --bg: #faf8f3; --bg-2: #f1ece1; --bg-3: #e8e0cf;
+    --rule: #d6cfbd; --rule-2: #c3b9a2;
+    --ink: #1a1a1a; --ink-soft: #383530; --ink-mute: #6a655a; --ink-faint: #908a7d;
+    --gold: #8a6520; --gold-glow: #ad8333;
+    --good: #3d7a4a; --bad: #a04a32;
+  }
+  html, body { transition: background-color 200ms ease, color 200ms ease; }
+  /* sun/moon toggle */
+  .theme-toggle {
+    background: var(--bg-3); color: var(--ink-mute); border: 1px solid var(--rule);
+    width: 32px; height: 32px; border-radius: 50%; cursor: pointer;
+    display: inline-flex; align-items: center; justify-content: center;
+    font-size: 14px; line-height: 1; padding: 0; margin-left: 14px;
+    transition: all 200ms;
+  }
+  .theme-toggle:hover { color: var(--gold); border-color: var(--gold); transform: rotate(20deg); }
+  .theme-toggle .moon { display: inline; }
+  .theme-toggle .sun  { display: none; }
+  html[data-theme="light"] .theme-toggle .moon { display: none; }
+  html[data-theme="light"] .theme-toggle .sun  { display: inline; }
   *, *::before, *::after { box-sizing: border-box; }
   html, body { margin: 0; background: var(--bg); color: var(--ink); font-family: var(--sans); font-weight: 300; min-height: 100vh; }
   a { color: var(--gold); text-decoration: none; }
@@ -120,6 +150,7 @@
     <a href="/admin/connectors">Connectors</a>
     <a href="/admin/approvals">Approvals</a>
     <a href="/admin/audit">Audit</a>
+    <button class="theme-toggle" id="themeToggle" type="button" title="Toggle light/dark" aria-label="Toggle theme"><span class="moon">☾</span><span class="sun">☀︎</span></button>
   </nav>
 </header>
 
@@ -228,6 +259,15 @@
   $('period').addEventListener('change', render);
   $('refresh').addEventListener('click', load);
 
+  // Theme toggle wiring (anti-flash already applied in <head>).
+  document.getElementById('themeToggle').addEventListener('click', () => {
+    const cur = document.documentElement.getAttribute('data-theme') === 'light' ? 'light' : 'dark';
+    const next = cur === 'light' ? 'dark' : 'light';
+    if (next === 'light') document.documentElement.setAttribute('data-theme', 'light');
+    else document.documentElement.removeAttribute('data-theme');
+    try { localStorage.setItem('vc-theme', next); } catch {}
+  });
+
   load();
   setInterval(load, 30000); // auto-refresh every 30s
 </script>

← f80fef5 /pricing v2: dual-product split (chat orchestrator free + se  ·  back to Ventura Claw  ·  /legal-notice: post-pivot sweep — replace all 'document prep f640869 →