Command Center

Cosmic Command Center :root { –bg-void: #08070a; –bg-nebula-a: #2a1f0d; –bg-nebula-b: #1a1006; –gold: #c9a05c; –gold-bright: #e6c98f; –ink: #e8e6f0; –ink-dim: #9b98ab; –ink-faint: #5c5a6e; –sapphire: #2f9fa4; –sapphire-dim: #12474b; –opal-a: #f5c6d8; –opal-b: #c6e8d8; –opal-c: #c6d8f0; –amber: #f5a623; –amber-dim: #c97a2b; –jade: #1f6b4b; –jade-dim: #0d3b29; –onyx: #8a8a9e; –onyx-dim: #2a2a2e; –lapis: #3d4a6b; –lapis-gold: #d4af37; –krystal: #f3a98a; –krystal-dim: #b06a4e; –font-display: ‘Playfair Display’, serif; –font-body: ‘EB Garamond’, serif; –font-mono: ‘Cormorant Garamond’, serif; } * { box-sizing: border-box; } html, body { margin: 0; padding: 0; width: 100%; height: 100%; background: var(–bg-void); color: var(–ink); font-family: var(–font-body); overflow: hidden; } /* ———- Starfield ———- */ #starfield { position: fixed; inset: 0; z-index: 0; background: radial-gradient(ellipse at 20% 30%, rgba(180,140,45,0.16), transparent 55%), radial-gradient(ellipse at 80% 70%, rgba(120,85,20,0.22), transparent 55%), var(–bg-void); } .star-layer { position: absolute; inset: -10%; background-repeat: repeat; } .star-layer.a { animation: drift-a 240s linear infinite; opacity: 0.8; } .star-layer.b { animation: drift-b 340s linear infinite; opacity: 0.5; } .star-layer.c { animation: drift-a 180s linear infinite reverse; opacity: 0.35; } @keyframes drift-a { from { transform: translate(0,0); } to { transform: translate(-6%, -4%); } } @keyframes drift-b { from { transform: translate(0,0); } to { transform: translate(5%, -6%); } } @media (prefers-reduced-motion: reduce) { .star-layer { animation: none !important; } } /* ———- Layout shell ———- */ #stage { position: relative; z-index: 1; width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; } .header-block { position: absolute; top: 24px; left: 50%; transform: translateX(-50%); text-align: center; } .eyebrow-title { font-family: var(–font-display); font-size: 32px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(–gold); white-space: nowrap; } .eyebrow-subtitle { margin-top: 4px; font-family: var(–font-mono); font-size: 15px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(–gold); opacity: 0.7; white-space: nowrap; } /* ———- Table ———- */ #table-wrap { position: relative; width: min(70vw, 760px); height: min(44vw, 440px); margin-top: 220px; } #table-surface { position: absolute; inset: 0; border-radius: 50% / 50%; background: radial-gradient(ellipse at 50% 40%, rgba(180,140,45,0.14), transparent 62%), linear-gradient(160deg, rgba(40,30,15,0.55), rgba(10,8,6,0.75)); border: 1px solid rgba(212,175,55,0.22); box-shadow: inset 0 0 80px rgba(150,110,30,0.12), 0 40px 90px rgba(0,0,0,0.55); } .seat { position: absolute; display: flex; flex-direction: column; align-items: center; gap: 6px; width: 170px; text-align: center; } .seat .gem { width: 72px; height: 72px; clip-path: polygon(50% 2%, 90% 25%, 90% 75%, 50% 98%, 10% 75%, 10% 25%); position: relative; animation: ambient-float 6s ease-in-out infinite; } .seat .gem::before { content: ”; position: absolute; inset: 0; clip-path: polygon(50% 2%, 90% 25%, 50% 50%, 10% 25%); background: rgba(255,255,255,0.22); mix-blend-mode: overlay; } .seat .gem::after { content: ”; position: absolute; inset: -18px; border-radius: 50%; filter: blur(13px); opacity: 0.55; background: inherit; z-index: -1; } @keyframes ambient-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } } .seat .name { font-family: var(–font-display); font-size: 21px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; } .seat .role { font-family: var(–font-mono); font-size: 13px; font-weight: 600; color: var(–ink-dim); text-transform: uppercase; letter-spacing: 0.06em; line-height: 1.4; } .planet-title { display: block; font-size: 12px; font-weight: 500; letter-spacing: 0.02em; text-transform: none; color: var(–ink-dim); opacity: 1; white-space: nowrap; margin: 3px auto 0; } .seat.active .gem { box-shadow: 0 0 0 2px rgba(255,255,255,0.55), 0 0 34px 6px currentColor; animation: ambient-float 6s ease-in-out infinite, active-pulse 2.4s ease-in-out infinite; } @keyframes active-pulse { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.35); } } /* per-agent gem colors */ .gem.sapphire { background: repeating-conic-gradient(from 210deg, rgba(0,0,0,0.32) 0deg 1.5deg, transparent 1.5deg 44deg), linear-gradient(125deg, rgba(255,255,255,0.5) 0%, transparent 38%), conic-gradient(from 205deg, #d4f5f0 0deg 26deg, #6fd0c0 26deg 70deg, var(–sapphire) 70deg 118deg, var(–sapphire-dim) 118deg 165deg, #051f22 165deg 210deg, var(–sapphire-dim) 210deg 255deg, var(–sapphire) 255deg 300deg, #7fd8ca 300deg 340deg, #d4f5f0 340deg 360deg); box-shadow: inset -5px -7px 9px rgba(0,0,0,0.4), inset 3px 3px 6px rgba(255,255,255,0.25); color: var(–sapphire); } .gem.opal { background: repeating-conic-gradient(from 200deg, rgba(0,0,0,0.18) 0deg 1.5deg, transparent 1.5deg 44deg), linear-gradient(125deg, rgba(255,255,255,0.45) 0%, transparent 38%), conic-gradient(from 195deg, var(–opal-a) 0deg 45deg, var(–opal-c) 45deg 90deg, var(–opal-b) 90deg 135deg, #efe4f7 135deg 180deg, var(–opal-a) 180deg 225deg, var(–opal-c) 225deg 270deg, var(–opal-b) 270deg 315deg, #efe4f7 315deg 360deg); box-shadow: inset -5px -7px 9px rgba(120,90,110,0.3), inset 3px 3px 6px rgba(255,255,255,0.35); color: var(–opal-c); } .gem.amber { background: repeating-conic-gradient(from 210deg, rgba(0,0,0,0.32) 0deg 1.5deg, transparent 1.5deg 44deg), linear-gradient(125deg, rgba(255,255,255,0.5) 0%, transparent 38%), conic-gradient(from 205deg, #fff3d6 0deg 26deg, #ffcf7a 26deg 70deg, var(–amber) 70deg 118deg, var(–amber-dim) 118deg 165deg, #5c3608 165deg 210deg, var(–amber-dim) 210deg 255deg, var(–amber) 255deg 300deg, #ffdb96 300deg 340deg, #fff3d6 340deg 360deg); box-shadow: inset -5px -7px 9px rgba(0,0,0,0.4), inset 3px 3px 6px rgba(255,255,255,0.3); color: var(–amber); } .gem.jade { background: repeating-conic-gradient(from 210deg, rgba(0,0,0,0.32) 0deg 1.5deg, transparent 1.5deg 44deg), linear-gradient(125deg, rgba(255,255,255,0.45) 0%, transparent 38%), conic-gradient(from 205deg, #d4ffe9 0deg 26deg, #6fdfae 26deg 70deg, var(–jade) 70deg 118deg, var(–jade-dim) 118deg 165deg, #041b11 165deg 210deg, var(–jade-dim) 210deg 255deg, var(–jade) 255deg 300deg, #85e8bb 300deg 340deg, #d4ffe9 340deg 360deg); box-shadow: inset -5px -7px 9px rgba(0,0,0,0.45), inset 3px 3px 6px rgba(255,255,255,0.2); color: var(–jade); } .gem.onyx { background: repeating-conic-gradient(from 210deg, rgba(255,255,255,0.08) 0deg 1.5deg, transparent 1.5deg 44deg), linear-gradient(125deg, rgba(255,255,255,0.35) 0%, transparent 38%), conic-gradient(from 205deg, #c4c4d4 0deg 26deg, #6a6a7a 26deg 70deg, #3a3a42 70deg 118deg, #101014 118deg 165deg, #000000 165deg 210deg, #101014 210deg 255deg, #3a3a42 255deg 300deg, #77778a 300deg 340deg, #c4c4d4 340deg 360deg); box-shadow: inset -5px -7px 9px rgba(0,0,0,0.55), inset 3px 3px 6px rgba(255,255,255,0.2); color: var(–onyx); } .gem.lapis { background: radial-gradient(circle at 28% 22%, var(–lapis-gold) 3%, transparent 4%), radial-gradient(circle at 68% 58%, var(–lapis-gold) 2.5%, transparent 3.5%), radial-gradient(circle at 45% 75%, var(–lapis-gold) 2%, transparent 3%), repeating-conic-gradient(from 210deg, rgba(0,0,0,0.32) 0deg 1.5deg, transparent 1.5deg 44deg), linear-gradient(125deg, rgba(255,255,255,0.45) 0%, transparent 38%), conic-gradient(from 205deg, #cdd2e2 0deg 26deg, #8891ac 26deg 70deg, var(–lapis) 70deg 118deg, #1c2233 118deg 165deg, #06070c 165deg 210deg, #1c2233 210deg 255deg, var(–lapis) 255deg 300deg, #a3aac2 300deg 340deg, #cdd2e2 340deg 360deg); box-shadow: inset -5px -7px 9px rgba(0,0,0,0.45), inset 3px 3px 6px rgba(255,255,255,0.2); color: var(–lapis); } .gem.krystal { background: repeating-conic-gradient(from 210deg, rgba(0,0,0,0.2) 0deg 1.5deg, transparent 1.5deg 44deg), linear-gradient(125deg, rgba(255,255,255,0.55) 0%, transparent 38%), conic-gradient(from 205deg, #fff2ea 0deg 26deg, #f8c4a8 26deg 70deg, var(–krystal) 70deg 118deg, var(–krystal-dim) 118deg 165deg, #5c3320 165deg 210deg, var(–krystal-dim) 210deg 255deg, var(–krystal) 255deg 300deg, #fad3bd 300deg 340deg, #fff2ea 340deg 360deg); box-shadow: inset -5px -7px 9px rgba(140,80,50,0.35), inset 3px 3px 6px rgba(255,255,255,0.4); color: var(–krystal); } /* Seat positions around the arc — head (Sapphire) at top-center */ .seat.sapphire-seat { top: -6%; left: 50%; transform: translateX(-50%); } .seat.opal-seat { top: 14%; left: 4%; } .seat.jade-seat { top: 52%; left: -2%; } .seat.krystal-seat { top: 88%; left: 14%; } .seat.amber-seat { top: 14%; right: 4%; } .seat.lapis-seat { top: 52%; right: -2%; } .seat.onyx-seat { top: 88%; right: 14%; } /* ———- Planets (downstream specialists) ———- */ .planet { position: absolute; top: -58px; left: 50%; transform: translateX(-50%); width: 30px; height: 30px; border-radius: 50%; opacity: 0.85; } .planet:not(.label) { animation: planet-orbit 10s ease-in-out infinite; } /* Organic scattered positions and true-to-scale sizes (Luna as the baseline smallest body) */ .opal-seat .planet.sun { width: 102px; height: 102px; top: -118px; left: 16%; animation-duration: 15s; } .opal-seat .planet.gaia { width: 60px; height: 60px; top: -96px; left: 98%; animation-duration: 11s; animation-delay: -3s; } .amber-seat .planet.mars { width: 44px; height: 44px; top: -92px; left: 2%; animation-duration: 9s; animation-delay: -1s; } .amber-seat .planet.vena { width: 62px; height: 62px; top: -50px; left: 90%; animation-duration: 12s; animation-delay: -5s; } .jade-seat .planet.luna { width: 34px; height: 34px; top: 26px; left: -34%; animation-duration: 8s; animation-delay: -2s; } @keyframes planet-orbit { 0%, 100% { transform: translateX(-50%) translateY(0) rotate(0deg); } 50% { transform: translateX(-50%) translateY(-6px) rotate(6deg); } } .planet.sun { background: radial-gradient(circle at 35% 30%, #fff3c4, #ffb347 60%, #b5651d); box-shadow: 0 0 18px 3px rgba(255,179,71,0.5); } .planet.luna { background: radial-gradient(circle at 32% 28%, #ffffff, #d4d4dc 45%, #8d8d98 80%); box-shadow: 0 0 14px 2px rgba(216,216,224,0.45); } .planet.gaia { background: radial-gradient(circle at 28% 68%, rgba(58,138,88,0.65) 12%, transparent 32%), radial-gradient(circle at 62% 32%, rgba(58,138,88,0.55) 10%, transparent 28%), radial-gradient(circle at 35% 30%, #bfe8ff, #2e6fb8 55%, #12305e 85%); box-shadow: 0 0 16px 3px rgba(60,140,200,0.4); } .planet.vena { background: radial-gradient(circle at 35% 30%, #fff3ea, #f3a98a 55%, #b06a4e 85%); box-shadow: 0 0 14px 2px rgba(243,169,138,0.45); } .planet.mars { background: radial-gradient(circle at 35% 30%, #ffb199, #c1440e 60%, #6e260a); box-shadow: 0 0 14px 2px rgba(193,68,14,0.45); } .planet.luna { background: radial-gradient(circle at 35% 30%, #f4f4f8, #b8b8c4 60%, #7c7c88); box-shadow: 0 0 12px 2px rgba(200,200,210,0.4); } .planet.label { position: absolute; top: -74px; left: 50%; transform: translateX(-50%); font-family: var(–font-mono); font-size: 15px; font-weight: 600; color: var(–ink); white-space: nowrap; letter-spacing: 0.06em; text-transform: uppercase; z-index: 3; } .opal-seat .planet.label.sun-label { top: -192px; left: 16%; } .opal-seat .planet.label.gaia-label { top: -154px; left: 98%; } .amber-seat .planet.label.mars-label { top: -168px; left: 2%; } .amber-seat .planet.label.vena-label { top: -102px; left: 90%; } .jade-seat .planet.label.luna-label { top: -30px; left: -34%; } /* ———- Center console ———- */ #console { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 320px; text-align: center; } #active-name { font-family: var(–font-display); font-size: 34px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(–gold); } #active-status { font-family: var(–font-mono); font-size: 15px; font-weight: 600; color: var(–gold); opacity: 0.7; text-transform: uppercase; letter-spacing: 0.1em; margin-top: 4px; min-height: 14px; } /* ———- Bottom control bar ———- */ #control-bar { position: absolute; bottom: 36px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 14px; z-index: 2; } #mic-btn { width: 64px; height: 64px; border-radius: 50%; border: 1px solid rgba(212,175,55,0.4); background: radial-gradient(circle at 35% 30%, rgba(150,110,30,0.5), rgba(18,14,10,0.9)); color: var(–ink); cursor: pointer; display: flex; align-items: center; justify-content: center; transition: box-shadow 0.25s ease, transform 0.15s ease; } #mic-btn:hover { transform: translateY(-2px); } #mic-btn.listening { box-shadow: 0 0 0 2px rgba(255,255,255,0.4), 0 0 36px 10px rgba(120,110,200,0.55); animation: mic-pulse 1.6s ease-in-out infinite; } @keyframes mic-pulse { 0%, 100% { box-shadow: 0 0 0 2px rgba(255,255,255,0.4), 0 0 24px 6px rgba(120,110,200,0.4); } 50% { box-shadow: 0 0 0 2px rgba(255,255,255,0.6), 0 0 44px 14px rgba(120,110,200,0.65); } } #mic-btn svg { width: 24px; height: 24px; } #transcript { font-family: var(–font-mono); font-size: 18px; font-weight: 500; font-style: italic; color: var(–ink-dim); max-width: 480px; text-align: center; min-height: 16px; } audio#voice-out { display: none; } #brand-strip { position: fixed; top: 108px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 34px; z-index: 2; opacity: 0.95; } #brand-strip img { height: 140px; width: 140px; filter: drop-shadow(0 0 10px rgba(212,175,55,0.35)); } #brand-strip .divider { width: 1px; height: 40px; background: rgba(212,175,55,0.3); }
Cosmic Command Center
StarSeedSpa Estate · Live Feed
Sapphire
Chief Intelligence Officer
SolaraCapital Systems Analyst
GaiaResource Systems Analyst
Opal
Chief Financial Officer
LunaInstitutional Systems Analyst
Jade
Chief Administrative Officer
Krystal
Chief Experience Officer
MarsCustomer & Community Relationship Analyst
VenaCreative Experience Analyst
Amber
Chief Marketing Officer
Lapis
Chief Information Officer
Onyx
Chief Technology Officer
Sapphire
standing by
 
/* ============================================================ CONFIG — fill in each agent’s real webhook URL from n8n (Webhook node → Production URL, set to return the ElevenLabs audio binary as the response) ============================================================ */ const AGENT_WEBHOOKS = { Sapphire: “https://n8n.sapphirestardust.com/webhook/sapphire-voice&#8221;, Opal: “https://n8n.sapphirestardust.com/webhook/opal-voice&#8221;, Amber: “https://n8n.sapphirestardust.com/webhook/amber-voice&#8221;, Jade: “https://n8n.sapphirestardust.com/webhook/jade-voice&#8221;, Onyx: “https://n8n.sapphirestardust.com/webhook/onyx-voice&#8221;, Lapis: “https://n8n.sapphirestardust.com/webhook/lapis-voice&#8221;, Krystal: “https://n8n.sapphirestardust.com/webhook/krystal-voice&#8221;, }; const AGENT_NAMES = Object.keys(AGENT_WEBHOOKS); /* ============================================================ Starfield generation (simple twinkling dot layers) ============================================================ */ function makeStarLayer(el, count, size, color) { let dots = “”; for (let i = 0; i < count; i++) { const x = Math.random() * 100; const y = Math.random() * 100; const r = Math.random() * size + 0.4; dots += “; } el.style.backgroundImage = `url(“data:image/svg+xml,${encodeURIComponent( `${dots}` )}”)`; el.style.backgroundSize = “700px 700px”; } makeStarLayer(document.getElementById(‘stars-a’), 60, 0.5, ‘#f3e6c8’); makeStarLayer(document.getElementById(‘stars-b’), 40, 0.35, ‘#d4af37’); makeStarLayer(document.getElementById(‘stars-c’), 30, 0.3, ‘#fff6df’); /* ============================================================ State ============================================================ */ let currentAgent = “Sapphire”; const activeNameEl = document.getElementById(‘active-name’); const activeStatusEl = document.getElementById(‘active-status’); const transcriptEl = document.getElementById(‘transcript’); const micBtn = document.getElementById(‘mic-btn’); const audioOut = document.getElementById(‘voice-out’); function setActiveAgent(name) { currentAgent = name; activeNameEl.textContent = name; document.querySelectorAll(‘.seat’).forEach(seat => { seat.classList.toggle(‘active’, seat.dataset.agent === name); }); } function setStatus(text) { activeStatusEl.textContent = text; } /* ============================================================ Hand-off phrase detection Recognized patterns (case-insensitive): – “bring forward ” / “call forward” / “speak to ” / “let me talk to ” -> switches active agent to – “sapphire, let’s continue” / “thank you , sapphire” / “back to sapphire” -> switches active agent back to Sapphire ============================================================ */ function detectHandoff(text) { const lower = text.toLowerCase(); // returning to Sapphire if (/back to sapphire|sapphire.*(let’?s continue|continue the conversation)|thank you.*sapphire/.test(lower)) { return “Sapphire”; } // bringing someone forward const bringForward = /(bring forward|call forward|speak to|talk to|let me speak with)\s+([a-z]+)/.exec(lower); if (bringForward) { const requested = bringForward[2]; const match = AGENT_NAMES.find(n => n.toLowerCase() === requested); if (match) return match; } return null; // no hand-off detected — message goes to current agent as-is } /* ============================================================ Send transcribed text to the current agent’s webhook, play back the returned audio ============================================================ */ async function sendToAgent(agentName, text) { const url = AGENT_WEBHOOKS[agentName]; if (!url || url.startsWith(“PASTE_”)) { setStatus(`no webhook configured for ${agentName} yet`); return; } setStatus(`${agentName} is responding…`); try { const res = await fetch(url, { method: “POST”, headers: { “Content-Type”: “application/json” }, body: JSON.stringify({ chatInput: text }) }); if (!res.ok) { setStatus(`${agentName} could not be reached (${res.status})`); return; } const blob = await res.blob(); const audioUrl = URL.createObjectURL(blob); audioOut.src = audioUrl; await audioOut.play(); setStatus(`${agentName} responding`); audioOut.onended = () => setStatus(“standing by”); } catch (err) { setStatus(`connection error — ${err.message}`); } } /* ============================================================ Speech recognition (browser built-in, no cost) ============================================================ */ const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; let recognizer = null; let listening = false; if (SpeechRecognition) { recognizer = new SpeechRecognition(); recognizer.continuous = false; recognizer.interimResults = false; recognizer.lang = “en-US”; recognizer.onstart = () => { listening = true; micBtn.classList.add(‘listening’); setStatus(“listening…”); }; recognizer.onend = () => { listening = false; micBtn.classList.remove(‘listening’); }; recognizer.onerror = (e) => { listening = false; micBtn.classList.remove(‘listening’); setStatus(`mic error — ${e.error}`); }; recognizer.onresult = (event) => { const text = event.results[0][0].transcript; transcriptEl.textContent = `”${text}”`; const handoff = detectHandoff(text); if (handoff && handoff !== currentAgent) { setActiveAgent(handoff); setStatus(handoff === “Sapphire” ? “returning to Sapphire” : `bringing ${handoff} forward`); // Announce the hand-off itself as a message to the newly active agent // so they greet the user naturally. sendToAgent(handoff, `[hand-off] Dr. Drysdale would like to speak with you now.`); return; } sendToAgent(currentAgent, text); }; } else { setStatus(“speech recognition not supported in this browser”); } micBtn.addEventListener(‘click’, () => { if (!recognizer) return; if (listening) { recognizer.stop(); } else { recognizer.start(); } }); setActiveAgent(“Sapphire”);