Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>CHAINSTATE — Symbolic-Weight Blockchain with Integrated LM Swarm</title> | |
| <meta name="description" content="CHAINSTATE — symbolic-weight blockchain. Transactions ARE cognitive queries. Weights are universal symbols (math, science, language, occult, emoji). Consensus through reputation-weighted Bayesian log-pooling. Fully integrated with NWO-ASM and NWO NEURO."> | |
| <link rel="icon" type="image/png" href="https://huggingface.co/spaces/CPater/chainstate/resolve/main/phi.png"> | |
| <script>window.__CHAINSTATE_WORKER = "https://chainstate-worker.ciprianpater.workers.dev";</script> | |
| <script> | |
| /* ── CHAINSTATE Demo/Live mode toggle — global state, persisted, event-driven ── */ | |
| (function(){ | |
| var KEY = 'cs:mode'; | |
| var mode = 'demo'; | |
| try { var m = localStorage.getItem(KEY); if(m==='demo'||m==='live') mode=m; } catch(e){} | |
| window.csMode = function(){ return mode; }; | |
| window.csIsLive = function(){ return mode === 'live'; }; | |
| window.csSetMode = function(m){ | |
| if(m !== 'demo' && m !== 'live') return; | |
| if(m === mode) return; | |
| mode = m; | |
| try { localStorage.setItem(KEY, mode); } catch(e){} | |
| if(document.body) document.body.setAttribute('data-cs-mode', mode); | |
| document.querySelectorAll('.mode-toggle [data-mode]').forEach(function(b){ | |
| b.classList.toggle('on', b.getAttribute('data-mode') === mode); | |
| }); | |
| document.dispatchEvent(new CustomEvent('cs:modechange', { detail: { mode: mode } })); | |
| }; | |
| window.csModeToggle = function(){ | |
| return '<div class="mode-toggle" role="group" aria-label="Demo / Live data mode">'+ | |
| '<button data-mode="demo" class="'+(mode==='demo'?'on':'')+'" '+ | |
| 'onclick="csSetMode(\'demo\')" '+ | |
| 'title="Show seeded sample data — no worker calls">DEMO</button>'+ | |
| '<button data-mode="live" class="'+(mode==='live'?'on':'')+'" '+ | |
| 'onclick="csSetMode(\'live\')" '+ | |
| 'title="Hit the live worker for real chain data">LIVE</button>'+ | |
| '</div>'; | |
| }; | |
| document.addEventListener('DOMContentLoaded', function(){ | |
| document.body.setAttribute('data-cs-mode', mode); | |
| }); | |
| })(); | |
| </script> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700;800&family=Chakra+Petch:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@300;400;500;600&display=swap" rel="stylesheet"> | |
| <style> | |
| :root{ | |
| --k:#000;--k1:#070709;--k2:#101015;--k3:#1c1c24; | |
| --w:#fff;--w2:#e9e9ee;--w3:#9c9ca6;--w4:#5a5a64; | |
| --line:rgba(255,255,255,.10);--line2:rgba(255,255,255,.22);--line3:rgba(255,255,255,.45); | |
| --shim-a:rgba(255,255,255,.04);--shim-b:rgba(255,255,255,.18);--shim-c:rgba(255,255,255,.32); | |
| --live:#7df0a8;--beta:#f0e07d;--design:#a98df0;--road:#f0a87d; | |
| --math:#7df0a8;--sci:#7ad0ff;--lang:#f0e07d;--occ:#a48cff;--emo:#ff8cb8;--ctrl:#e9e9ee; | |
| --display:'Orbitron',ui-sans-serif,system-ui,sans-serif; | |
| --body:'Chakra Petch',ui-sans-serif,system-ui,sans-serif; | |
| --mono:'IBM Plex Mono',ui-monospace,monospace; | |
| --hero-h:100vh; | |
| --topbar-h:62px; | |
| } | |
| *{margin:0;padding:0;box-sizing:border-box} | |
| html{height:100%} | |
| html,body{width:100%;background:var(--k);color:var(--w);font-family:var(--body); | |
| letter-spacing:.015em;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:hidden} | |
| body{min-height:100vh;font-size:15px;line-height:1.55;display:flex;flex-direction:column} | |
| a{color:inherit;text-decoration:none} | |
| button{font-family:inherit;color:inherit;background:transparent;border:none;cursor:pointer} | |
| canvas{display:block} | |
| img{display:block;max-width:100%} | |
| code{font-family:var(--mono);background:rgba(255,255,255,.04);padding:1px 5px;border-radius:4px;font-size:.92em} | |
| .shim{position:relative;overflow:hidden; | |
| background:linear-gradient(180deg, rgba(255,255,255,.015), rgba(255,255,255,0) 60%); | |
| border:1px solid var(--line);border-radius:14px;isolation:isolate} | |
| .shim > *{position:relative;z-index:1} | |
| .ghost{display:inline-flex;align-items:center;gap:.55em;padding:.65em 1.1em; | |
| border:1px solid var(--line2);border-radius:999px;background:transparent;color:var(--w); | |
| font-family:var(--display);font-size:.78em;font-weight:500;letter-spacing:.14em; | |
| text-transform:uppercase;transition:border-color .25s,transform .25s,background .25s;cursor:pointer} | |
| .ghost:hover{border-color:var(--line3);background:rgba(255,255,255,.03);transform:translateY(-1px)} | |
| .ghost.sm{padding:.45em .85em;font-size:.7em} | |
| .ghost.bold{border-color:rgba(255,255,255,.55);font-weight:700} | |
| .pill{display:inline-flex;align-items:center;gap:.4em;padding:.18em .55em;border-radius:999px; | |
| font-family:var(--mono);font-size:.62em;font-weight:500;letter-spacing:.18em; | |
| border:1px solid var(--line2);text-transform:uppercase} | |
| .pill .dot{width:6px;height:6px;border-radius:50%;background:var(--w3)} | |
| .pill.live{border-color:rgba(125,240,168,.45)}.pill.live .dot{background:var(--live);box-shadow:0 0 8px var(--live)} | |
| .pill.beta{border-color:rgba(240,224,125,.4)}.pill.beta .dot{background:var(--beta);box-shadow:0 0 8px var(--beta)} | |
| .pill.design{border-color:rgba(169,141,240,.4)}.pill.design .dot{background:var(--design);box-shadow:0 0 8px var(--design)} | |
| .pill.planned{border-color:rgba(122,208,255,.45)}.pill.planned .dot{background:#7ad0ff;box-shadow:0 0 8px rgba(122,208,255,.6)} | |
| .pill.parked{border-color:rgba(180,180,196,.35)}.pill.parked .dot{background:#9c9ca6;box-shadow:0 0 4px rgba(180,180,196,.4)} | |
| .pill.road{border-color:rgba(240,168,125,.4)}.pill.road .dot{background:var(--road);box-shadow:0 0 8px var(--road)} | |
| /* ── Demo/Live mode toggle ── */ | |
| .mode-toggle{display:inline-flex;align-items:center;gap:0;border:1px solid var(--line2);border-radius:999px; | |
| padding:2px;background:rgba(0,0,0,.4);font-family:var(--mono);font-size:.62em;letter-spacing:.18em; | |
| text-transform:uppercase;font-weight:500} | |
| .mode-toggle button{background:none;border:0;padding:.32em .75em;color:var(--w3);cursor:pointer; | |
| border-radius:999px;transition:background .2s, color .2s;font:inherit;letter-spacing:inherit} | |
| .mode-toggle button.on[data-mode="demo"]{background:var(--w);color:#000} | |
| .mode-toggle button.on[data-mode="live"]{background:var(--live);color:#000;box-shadow:0 0 10px rgba(125,240,168,.45)} | |
| .mode-toggle button:hover:not(.on){color:var(--w);background:rgba(255,255,255,.08)} | |
| /* LIVE-mode body accent: when LIVE, the page subhero gets a subtle green border tint */ | |
| body[data-cs-mode="live"] .subhero{border-left:2px solid var(--live);padding-left:14px} | |
| /* Live-only / Demo-only block toggles */ | |
| body[data-cs-mode="demo"] .live-only{display:none !important} | |
| body[data-cs-mode="live"] .demo-only{display:none !important} | |
| .topbar{position:fixed;top:0;left:0;right:0;z-index:60;height:var(--topbar-h); | |
| display:flex;align-items:center;justify-content:space-between;padding:0 22px;gap:18px; | |
| background:linear-gradient(180deg, rgba(0,0,0,.85), rgba(0,0,0,.55) 70%, rgba(0,0,0,0)); | |
| backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);border-bottom:1px solid var(--line)} | |
| .brand{display:flex;align-items:center;gap:12px;cursor:pointer} | |
| .brand img.phi{width:34px;height:34px;object-fit:contain;filter:drop-shadow(0 0 6px rgba(255,255,255,.35))} | |
| .brand .name{font-family:var(--display);font-weight:700;letter-spacing:.18em;font-size:1.05em} | |
| .brand .name .light{font-weight:400;color:var(--w3);margin-left:.35em} | |
| .topbar-right{display:flex;align-items:center;gap:10px} | |
| #wallet-btn{height:36px;padding:0 14px;border-radius:8px} | |
| #wallet-btn .addr{font-family:var(--mono);font-size:.78em;letter-spacing:.05em} | |
| .burger{display:flex;width:42px;height:36px;align-items:center;justify-content:center; | |
| border:1px solid var(--line2);border-radius:8px;cursor:pointer;transition:border-color .2s,background .2s} | |
| .burger:hover{border-color:var(--line3);background:rgba(255,255,255,.03)} | |
| .burger span{display:block;width:18px;height:1.5px;background:var(--w);position:relative} | |
| .burger span::before,.burger span::after{content:'';position:absolute;left:0;right:0;height:1.5px;background:var(--w)} | |
| .burger span::before{top:-6px}.burger span::after{top:6px} | |
| .nav{display:none;align-items:center;gap:2px;flex-wrap:wrap} | |
| .nav .nav-item{position:relative;font-family:var(--display);font-size:.72em;font-weight:500; | |
| letter-spacing:.14em;text-transform:uppercase;padding:9px 11px;border-radius:6px;color:var(--w3); | |
| transition:color .2s,background .2s;cursor:pointer;white-space:nowrap} | |
| .nav .nav-item:hover{color:var(--w);background:rgba(255,255,255,.04)} | |
| .nav .nav-item.active{color:var(--w);background:rgba(255,255,255,.06)} | |
| .nav-group{position:relative} | |
| .nav-group > .nav-item{display:flex;align-items:center;gap:6px} | |
| .nav-group > .nav-item .chev{display:inline-block;transition:transform .22s;font-size:.7em;color:var(--w3)} | |
| .nav-group.open > .nav-item .chev{transform:rotate(180deg);color:var(--w)} | |
| .nav-dd{display:none} | |
| .nav-group.open .nav-dd{display:block} | |
| .nav-dd a{display:block;padding:8px 11px;font-family:var(--display);font-size:.68em; | |
| letter-spacing:.13em;color:var(--w3);border-radius:6px;text-transform:uppercase; | |
| transition:background .2s,color .2s;cursor:pointer;white-space:nowrap} | |
| .nav-dd a:hover{color:var(--w);background:rgba(255,255,255,.05)} | |
| .nav-dd a.active{color:var(--w);background:rgba(255,255,255,.08)} | |
| .nav-dd .sub-label{padding:8px 12px 4px;color:var(--w4);font-family:var(--mono); | |
| font-size:.6em;letter-spacing:.18em;text-transform:uppercase} | |
| .topbar.menu-open .nav{display:flex;position:absolute;top:var(--topbar-h);left:0;right:0; | |
| background:#000;padding:14px;border-bottom:1px solid var(--line); | |
| flex-direction:column;align-items:stretch;gap:2px; | |
| max-height:calc(100vh - var(--topbar-h));overflow-y:auto;z-index:70} | |
| .topbar.menu-open .nav .nav-item{width:100%;padding:11px 12px;font-size:.74em} | |
| .topbar.menu-open .nav-group{width:100%} | |
| .topbar.menu-open .nav-group > .nav-item{justify-content:space-between} | |
| .topbar.menu-open .nav-group .nav-dd{position:static;opacity:1;pointer-events:auto; | |
| transform:none;border:1px solid var(--line);background:rgba(255,255,255,.025); | |
| border-radius:8px;margin:4px 0 6px 12px;padding:6px;display:none} | |
| .topbar.menu-open .nav-group.open .nav-dd{display:grid;grid-template-columns:1fr 1fr;gap:0 4px} | |
| .topbar.menu-open .nav-dd .sub-label{grid-column:1 / -1;padding:6px 8px 2px} | |
| .topbar.menu-open .nav-dd a{font-size:.65em;padding:7px 9px} | |
| @media (min-width: 1200px) { | |
| .burger{display:none} | |
| .nav,.topbar.menu-open .nav{ | |
| display:flex !important;position:static !important;flex-direction:row !important; | |
| align-items:center !important;flex-wrap:nowrap !important;background:transparent !important; | |
| padding:0 !important;border-bottom:0 !important;backdrop-filter:none !important; | |
| max-height:none !important;overflow:visible !important;gap:1px !important;z-index:auto !important; | |
| } | |
| .nav .nav-item{width:auto !important;padding:8px 10px;font-size:.68em} | |
| .nav-group{width:auto !important} | |
| .nav-group > .nav-item{width:auto !important;justify-content:flex-start !important} | |
| .nav-group .nav-dd,.topbar.menu-open .nav-group .nav-dd{ | |
| display:none !important;position:absolute !important;top:calc(100% + 8px) !important; | |
| left:0 !important;right:auto !important;margin:0 !important;padding:12px !important; | |
| min-width:560px;background:#000 !important;border:1px solid var(--line) !important; | |
| border-radius:10px !important;box-shadow:0 14px 36px rgba(0,0,0,0.6);z-index:80; | |
| grid-template-columns:1fr 1fr;gap:0 12px; | |
| } | |
| .nav-group.open .nav-dd,.topbar.menu-open .nav-group.open .nav-dd{display:grid !important} | |
| .nav-dd a{padding:7px 10px;font-size:.66em} | |
| .nav-dd .sub-label{grid-column:1 / -1;padding:6px 10px 3px} | |
| } | |
| @media (min-width: 1500px) { | |
| .nav-group .nav-dd{min-width:760px;grid-template-columns:1fr 1fr 1fr !important} | |
| } | |
| .stage{position:relative;width:100%;flex:1 0 auto;padding-top:var(--topbar-h);overflow:hidden} | |
| .page{position:absolute;top:var(--topbar-h);left:0;right:0;opacity:0;transform:translateX(50px); | |
| transition:opacity .55s cubic-bezier(.22,.61,.36,1),transform .55s cubic-bezier(.22,.61,.36,1); | |
| pointer-events:none} | |
| .page.active{opacity:1;transform:translateX(0);pointer-events:auto;position:relative;top:0} | |
| .page.exit-left{transform:translateX(-50px)} | |
| .page.exit-right{transform:translateX(50px)} | |
| .page.enter-left{transform:translateX(-50px)} | |
| .wrap{max-width:1480px;margin:0 auto;padding:0 28px} | |
| section{padding:28px 0} | |
| section.tight{padding:18px 0} | |
| section.bare{padding:0} | |
| .section-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px; | |
| margin-bottom:18px;border-bottom:1px solid var(--line);padding-bottom:10px} | |
| .section-head h2{font-family:var(--display);font-weight:600;font-size:1.4em;letter-spacing:.06em} | |
| .section-head .sub{color:var(--w3);font-family:var(--mono);font-size:.7em;letter-spacing:.14em;text-transform:uppercase} | |
| .eyebrow{font-family:var(--mono);font-size:.7em;color:var(--w3); | |
| letter-spacing:.28em;text-transform:uppercase;margin-bottom:10px} | |
| .hero{position:relative;height:calc(100vh - var(--topbar-h));min-height:680px; | |
| display:flex;flex-direction:column;justify-content:center;overflow:hidden;border-bottom:1px solid var(--line)} | |
| #hero-canvas{position:absolute;inset:0;width:100%;height:100%;z-index:1} | |
| .hero-fade{position:absolute;inset:0;z-index:2;pointer-events:none; | |
| background:radial-gradient(75% 55% at 50% 50%, transparent, rgba(0,0,0,.55) 65%, rgba(0,0,0,.95) 100%)} | |
| .hero-inner{position:relative;z-index:3;padding:0 28px;max-width:1480px;margin:0 auto;width:100%} | |
| .hero h1{font-family:var(--display);font-weight:700;font-size:clamp(2.2em, 5.8vw, 5em); | |
| letter-spacing:.04em;line-height:1.02;text-transform:uppercase} | |
| .hero h1 .accent{color:var(--w3);font-weight:400} | |
| .hero .lede{margin-top:18px;max-width:820px;color:var(--w2);font-size:1.08em} | |
| .stats{margin-top:38px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;position:relative} | |
| .stat{position:relative;overflow:hidden;padding:18px 18px;border:1px solid var(--line); | |
| border-radius:12px;background:rgba(0,0,0,.4);backdrop-filter:blur(6px);isolation:isolate} | |
| .stat > *{position:relative;z-index:1} | |
| .stat .v{font-family:var(--display);font-size:1.65em;font-weight:600} | |
| .stat .l{font-family:var(--mono);font-size:.65em;color:var(--w3);letter-spacing:.18em;text-transform:uppercase;margin-top:6px} | |
| .scroll-cue{position:absolute;bottom:18px;left:50%;transform:translateX(-50%);z-index:3; | |
| font-family:var(--mono);font-size:.62em;color:var(--w3);letter-spacing:.3em; | |
| text-transform:uppercase;display:flex;flex-direction:column;align-items:center;gap:6px} | |
| .scroll-cue .l{width:1px;height:24px;background:linear-gradient(180deg,transparent,var(--w3));animation:slide 2s ease-in-out infinite} | |
| @keyframes slide{0%,100%{opacity:.2;transform:scaleY(.4)}50%{opacity:1;transform:scaleY(1)}} | |
| /* CHAINSTATE SCAN — block explorer */ | |
| .scan-grid{display:grid;grid-template-columns:1.2fr .8fr;gap:14px;margin-top:18px} | |
| @media(max-width:980px){.scan-grid{grid-template-columns:1fr}} | |
| .scan-card{padding:0;overflow:hidden} | |
| .scan-card-head{padding:14px 18px;border-bottom:1px solid var(--line);background:rgba(0,0,0,.4); | |
| display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap} | |
| .scan-card-head h3{font-family:var(--display);font-size:.88em;font-weight:600;letter-spacing:.14em;text-transform:uppercase} | |
| .scan-card-head .meta{font-family:var(--mono);font-size:.66em;color:var(--w3);letter-spacing:.06em} | |
| .scan-list{max-height:480px;overflow-y:auto} | |
| .scan-row{display:grid;grid-template-columns:auto 1fr auto;gap:10px;align-items:center; | |
| padding:10px 18px;border-bottom:1px dashed rgba(255,255,255,.06);cursor:pointer;transition:background .2s} | |
| .scan-row:hover{background:rgba(255,255,255,.025)} | |
| .scan-row:last-child{border-bottom:0} | |
| .scan-row .ico{width:32px;height:32px;border:1px solid var(--line2);border-radius:6px; | |
| display:flex;align-items:center;justify-content:center;font-family:var(--display);font-size:.62em;color:var(--w3);letter-spacing:.06em} | |
| .scan-row .ico.bk{color:var(--live);border-color:rgba(125,240,168,.4)} | |
| .scan-row .ico.tx{color:var(--sci);border-color:rgba(122,208,255,.4)} | |
| .scan-row .hash{font-family:var(--mono);font-size:.78em;color:var(--w);letter-spacing:.04em; | |
| overflow:hidden;text-overflow:ellipsis;white-space:nowrap} | |
| .scan-row .sub{font-family:var(--mono);font-size:.64em;color:var(--w3);letter-spacing:.04em;margin-top:2px} | |
| .scan-row .v{font-family:var(--display);font-weight:600;font-size:.82em;text-align:right} | |
| .scan-row .v .l{font-family:var(--mono);font-weight:400;font-size:.7em;color:var(--w3);letter-spacing:.06em} | |
| .scan-search{display:flex;gap:10px;padding:14px 18px;border-bottom:1px solid var(--line);background:rgba(0,0,0,.3)} | |
| /* ── Home-page collapsible hero + toggle bar ── */ | |
| .home-toggle-bar{position:sticky;top:64px;z-index:30;display:flex;justify-content:flex-end; | |
| padding:8px 22px;background:linear-gradient(180deg,rgba(0,0,0,.92),rgba(0,0,0,.4) 80%,transparent); | |
| backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px); | |
| border-bottom:1px solid rgba(255,255,255,.04)} | |
| .home-toggle-btn{display:inline-flex;align-items:center;gap:8px; | |
| background:rgba(0,0,0,.6);border:1px solid var(--line2);border-radius:999px; | |
| padding:6px 14px;color:var(--w2);cursor:pointer; | |
| font-family:var(--mono);font-size:.62em;letter-spacing:.18em;text-transform:uppercase; | |
| transition:border-color .2s,color .2s,background .2s} | |
| .home-toggle-btn:hover{border-color:var(--line3);color:var(--w);background:rgba(255,255,255,.04)} | |
| .home-toggle-btn .ic{font-size:.9em;transition:transform .25s} | |
| .home-collapsed .home-toggle-btn .ic{transform:rotate(-90deg)} | |
| .home-collapsible{max-height:none;overflow:hidden;transition:max-height .35s ease} | |
| .home-collapsed .home-collapsible{max-height:0} | |
| .quick-scan-shell{border:1px solid var(--line);border-radius:14px;background:rgba(0,0,0,.4); | |
| padding:6px 0;overflow:hidden} | |
| .quick-scan-shell .scan-search{border-bottom:none} | |
| .quick-scan-shell + p{padding:0 18px} | |
| .scan-search input{flex:1;background:rgba(255,255,255,.04);border:1px solid var(--line); | |
| border-radius:8px;padding:9px 12px;color:var(--w);font-family:var(--mono);font-size:.82em;outline:none} | |
| .scan-search input:focus{border-color:var(--line3)} | |
| .scan-stat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px} | |
| @media(max-width:760px){.scan-stat-grid{grid-template-columns:repeat(2,1fr)}} | |
| .scan-stat{padding:14px;border:1px solid var(--line);border-radius:10px;background:rgba(0,0,0,.3)} | |
| .scan-stat .v{font-family:var(--display);font-size:1.35em;font-weight:600} | |
| .scan-stat .l{font-family:var(--mono);font-size:.6em;color:var(--w3);letter-spacing:.16em;text-transform:uppercase;margin-top:4px} | |
| /* SYMBOLIC REGISTRY page */ | |
| .sym-tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:14px} | |
| .sym-tab{padding:7px 13px;font-family:var(--display);font-size:.7em;letter-spacing:.14em; | |
| text-transform:uppercase;color:var(--w3);border:1px solid var(--line);border-radius:999px;cursor:pointer; | |
| transition:color .2s,border-color .2s,background .2s} | |
| .sym-tab:hover{color:var(--w);border-color:var(--line2)} | |
| .sym-tab.on{color:var(--k);background:var(--w);border-color:var(--w)} | |
| .sym-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(58px,1fr));gap:6px} | |
| .sym-cell{aspect-ratio:1/1;border:1px solid var(--line);border-radius:8px; | |
| display:flex;align-items:center;justify-content:center;font-size:1.3em; | |
| background:rgba(255,255,255,.02);cursor:pointer;transition:transform .15s,border-color .2s,background .2s;font-family:var(--body)} | |
| .sym-cell:hover{transform:scale(1.08);border-color:var(--line3);background:rgba(255,255,255,.06)} | |
| .sym-cell.sym-math{color:var(--math)} | |
| .sym-cell.sym-sci{color:var(--sci)} | |
| .sym-cell.sym-lang{color:var(--lang)} | |
| .sym-cell.sym-occ{color:var(--occ)} | |
| .sym-cell.sym-emo{color:var(--emo)} | |
| .sym-cell.sym-ctrl{color:var(--ctrl)} | |
| .sym-info{padding:14px 16px;background:rgba(255,255,255,.025);border:1px solid var(--line); | |
| border-radius:10px;margin-top:14px;font-family:var(--mono);font-size:.78em;color:var(--w2); | |
| display:flex;align-items:center;gap:14px;flex-wrap:wrap;min-height:54px} | |
| .sym-info .big{font-size:2em;line-height:1;color:var(--w);font-family:var(--body)} | |
| .sym-info .meta{display:flex;flex-direction:column;gap:4px;font-size:.84em;color:var(--w3)} | |
| /* TERMINAL — same as NEURO */ | |
| .terminal-shell{padding:0;overflow:hidden} | |
| .terminal-head{display:flex;align-items:center;gap:8px;padding:10px 14px;border-bottom:1px solid var(--line);background:rgba(0,0,0,.4)} | |
| .t-dot{width:9px;height:9px;border-radius:50%} | |
| .t-dot.t-r{background:#ff5f56}.t-dot.t-y{background:#ffbd2e}.t-dot.t-g{background:#27c93f} | |
| .t-title{font-family:var(--mono);font-size:.74em;letter-spacing:.06em;color:var(--w2);margin-left:8px} | |
| .t-status{margin-left:auto;font-family:var(--mono);font-size:.66em;color:var(--w3);letter-spacing:.06em} | |
| .terminal-body{padding:12px 16px;font-family:var(--mono);font-size:.78em;line-height:1.55; | |
| height:360px;overflow-y:auto;color:var(--w2);background:rgba(0,0,0,.45)} | |
| .terminal-body .tline{margin:0;padding:1px 0;white-space:pre-wrap;word-break:break-word} | |
| .terminal-body .tline.sys{color:var(--w3)} | |
| .terminal-body .tline.cmd{color:var(--w)} | |
| .terminal-body .tline.ok{color:#7df0a8} | |
| .terminal-body .tline.err{color:#ff8cb8} | |
| .terminal-body .tline.dim{color:var(--w4)} | |
| .terminal-body .tline.stream{color:#7ad0ff} | |
| .terminal-body .echo{color:#7df0a8;margin-right:6px} | |
| .terminal-input-row{display:flex;align-items:center;gap:8px;padding:10px 14px;border-top:1px solid var(--line);background:rgba(0,0,0,.4)} | |
| .terminal-input-row .prompt{font-family:var(--mono);font-size:.78em;color:#7df0a8;letter-spacing:.04em;flex-shrink:0} | |
| .terminal-input-row input{flex:1;background:transparent;border:none;outline:none;color:var(--w); | |
| font-family:var(--mono);font-size:.85em;letter-spacing:.04em;padding:4px 0} | |
| .terminal-input-row input::placeholder{color:var(--w4)} | |
| code.dim{color:var(--w4)} | |
| .instr-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px;margin-top:14px} | |
| .instr-card{display:flex;flex-direction:column;align-items:flex-start;gap:8px;padding:18px; | |
| border:1px solid var(--line);border-radius:12px;background:rgba(0,0,0,.3);text-align:left;cursor:pointer;color:var(--w);transition:transform .2s,border-color .25s} | |
| .instr-card:hover{transform:translateY(-2px);border-color:var(--line3)} | |
| .instr-card-h{display:flex;align-items:center;justify-content:space-between;width:100%;gap:10px} | |
| .instr-num{font-family:var(--mono);font-size:.7em;letter-spacing:.14em;color:var(--w3);text-transform:uppercase} | |
| .instr-name{font-family:var(--display);font-weight:600;font-size:1.05em;letter-spacing:.04em} | |
| .instr-head{font-family:var(--body);font-size:.88em;color:var(--w2);line-height:1.5} | |
| .instr-cta{margin-top:auto;font-family:var(--mono);font-size:.66em;letter-spacing:.12em;color:#7df0a8;text-transform:uppercase} | |
| .subhero{padding:22px 28px 14px;max-width:1480px;margin:0 auto} | |
| .subhero .back{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono); | |
| font-size:.66em;letter-spacing:.18em;color:var(--w3);text-transform:uppercase;margin-bottom:10px;cursor:pointer} | |
| .subhero .back:hover{color:var(--w)} | |
| .subhero h1{font-family:var(--display);font-weight:700;font-size:clamp(1.6em, 3.4vw, 2.4em); | |
| letter-spacing:.04em;text-transform:uppercase;line-height:1.05} | |
| .subhero .lede{margin-top:10px;color:var(--w2);font-size:.98em;max-width:920px} | |
| .subhero .meta-row{margin-top:12px;display:flex;flex-wrap:wrap;gap:8px;align-items:center} | |
| .two-col{display:grid;grid-template-columns:1.05fr .95fr;gap:18px} | |
| @media(max-width:1080px){.two-col{grid-template-columns:1fr}} | |
| .col-card{padding:20px} | |
| .col-card h3{font-family:var(--display);font-size:.95em;font-weight:600;letter-spacing:.14em;text-transform:uppercase;margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--line)} | |
| .col-card p{color:var(--w2);margin-bottom:10px;font-size:.94em} | |
| .col-card ul{list-style:none;padding:0} | |
| .col-card ul li{position:relative;padding:4px 0 4px 22px;color:var(--w2);font-size:.92em} | |
| .col-card ul li::before{content:'';position:absolute;left:0;top:13px;width:8px;height:1px;background:var(--w3)} | |
| .eco-table,.pay-table{width:100%;border-collapse:collapse;font-family:var(--mono);font-size:.76em} | |
| .eco-table th,.eco-table td,.pay-table th,.pay-table td{padding:8px 10px;text-align:left;border-bottom:1px solid var(--line)} | |
| .eco-table th,.pay-table th{font-family:var(--display);font-size:.74em;letter-spacing:.14em;text-transform:uppercase;color:var(--w3);font-weight:500} | |
| .eco-table tr:last-child td,.pay-table tr:last-child td{border-bottom:0} | |
| .pay-table td a{color:var(--math);text-decoration:underline;text-underline-offset:2px} | |
| .flow-box{padding:18px} | |
| .flow-box h3{font-family:var(--display);font-size:.95em;font-weight:600;letter-spacing:.14em;text-transform:uppercase;margin-bottom:14px;padding-bottom:8px;border-bottom:1px solid var(--line)} | |
| .flow-svg{width:100%;height:auto;display:block} | |
| pre.code{font-family:var(--mono);font-size:.75em;background:rgba(255,255,255,.03); | |
| border:1px solid var(--line);border-radius:8px;padding:12px;color:var(--w2); | |
| overflow-x:auto;white-space:pre;line-height:1.5} | |
| pre.code .k{color:var(--math)}pre.code .s{color:var(--lang)} | |
| pre.code .c{color:var(--w4)}pre.code .n{color:var(--sci)} | |
| /* API */ | |
| .api-grid{display:grid;grid-template-columns:1.3fr 1fr;gap:14px} | |
| @media(max-width:1100px){.api-grid{grid-template-columns:1fr}} | |
| .panel{padding:16px;display:flex;flex-direction:column} | |
| .panel-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--line)} | |
| .panel-head h3{font-family:var(--display);font-size:.85em;font-weight:600;letter-spacing:.16em;text-transform:uppercase} | |
| .panel-head .meta{font-family:var(--mono);font-size:.64em;color:var(--w3);letter-spacing:.14em} | |
| .kpi-row{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:14px} | |
| .kpi{padding:14px;border:1px solid var(--line);border-radius:10px} | |
| .kpi .v{font-family:var(--display);font-size:1.4em;font-weight:600} | |
| .kpi .l{font-family:var(--mono);font-size:.6em;color:var(--w3);letter-spacing:.18em;text-transform:uppercase;margin-top:4px} | |
| #calls-chart,.chart-canvas{width:100%;height:170px;display:block;border-radius:6px;background:linear-gradient(180deg,rgba(255,255,255,.022),rgba(255,255,255,.002))} | |
| .kpi-row.aff{margin-top:2px} | |
| .aff-status{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:.62em;letter-spacing:.14em;text-transform:uppercase;padding:.18em .55em;border-radius:999px;border:1px solid var(--line2);color:var(--w2)} | |
| .aff-status.on{border-color:rgba(125,240,168,.4);color:var(--live)} | |
| .aff-status.on .dot{background:var(--live);box-shadow:0 0 8px var(--live)} | |
| .aff-status .dot{width:6px;height:6px;border-radius:50%;background:var(--w3)} | |
| .keys-list{display:flex;flex-direction:column;gap:8px} | |
| .key-row{display:grid;grid-template-columns:auto 1fr auto auto;gap:10px;align-items:center;padding:9px 12px;border:1px solid var(--line);border-radius:8px} | |
| .key-row .kid{font-family:var(--mono);font-size:.78em;color:var(--w);letter-spacing:.04em} | |
| .key-row .kn{font-family:var(--mono);font-size:.68em;color:var(--w3);letter-spacing:.06em} | |
| .pricing-table .ep{font-family:var(--mono);color:var(--w)} | |
| .pricing-table .price{font-family:var(--display);font-weight:600} | |
| /* Architecture circle */ | |
| .arch-svg-wrap{padding:20px} | |
| .arch-circle-wrap{position:relative;width:100%;max-width:820px;margin:0 auto} | |
| .arch-svg-circle{width:100%;display:block;height:auto;overflow:visible} | |
| .arch-node rect{transition:stroke-opacity .22s,filter .22s,transform .22s;transform-origin:center;transform-box:fill-box} | |
| .arch-node:hover rect{stroke-opacity:1;filter:drop-shadow(0 0 10px rgba(255,255,255,.35));transform:scale(1.06)} | |
| .arch-node:hover text{fill:#fff} | |
| .arch-tooltip{position:absolute;display:none;max-width:260px;padding:12px 14px;border:1px solid var(--line2); | |
| background:rgba(0,0,0,.94);backdrop-filter:blur(8px);border-radius:10px;pointer-events:none;z-index:20; | |
| font-family:var(--mono);font-size:.72em;line-height:1.55;color:var(--w2);letter-spacing:.04em} | |
| .arch-tt-title{font-family:var(--display);font-size:1.15em;font-weight:600;letter-spacing:.1em;color:var(--w);margin-bottom:6px;display:flex;align-items:center;gap:8px} | |
| .arch-tt-dot{width:8px;height:8px;border-radius:50%;display:inline-block} | |
| .arch-tt-line{padding-left:2px} | |
| .arch-tt-cta{margin-top:8px;padding-top:8px;border-top:1px dashed rgba(255,255,255,.1);font-size:.85em;color:var(--w3);letter-spacing:.12em;text-transform:uppercase} | |
| .arch-legend{margin-top:14px;text-align:center;font-family:var(--mono);font-size:.72em;color:var(--w3);letter-spacing:.06em} | |
| @media(max-width:620px){.arch-circle-wrap{max-width:100%}.arch-tooltip{max-width:200px;font-size:.66em}} | |
| .stack-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px} | |
| .stack-card{padding:14px} | |
| .stack-card .l{font-family:var(--mono);font-size:.62em;color:var(--w3);letter-spacing:.18em;text-transform:uppercase;margin-bottom:6px} | |
| .stack-card .t{font-family:var(--display);font-size:.95em;font-weight:600;letter-spacing:.04em} | |
| .stack-card .d{margin-top:6px;color:var(--w2);font-size:.88em} | |
| .steps{counter-reset:s;display:grid;grid-template-columns:1fr 1fr;gap:14px} | |
| @media(max-width:900px){.steps{grid-template-columns:1fr}} | |
| .step-card{padding:18px;counter-increment:s;position:relative} | |
| .step-card::before{content:counter(s, decimal-leading-zero);position:absolute;top:14px;right:18px;font-family:var(--mono);font-size:.8em;color:var(--w3);letter-spacing:.12em} | |
| .step-card h3{font-family:var(--display);font-size:.95em;font-weight:600;letter-spacing:.1em;text-transform:uppercase;padding-bottom:8px;margin-bottom:10px;border-bottom:1px solid var(--line);max-width:86%} | |
| .step-card .layer-label{font-family:var(--mono);font-size:.6em;color:var(--w3);letter-spacing:.2em;text-transform:uppercase;margin-bottom:5px} | |
| .step-card p.txt-sm{color:var(--w2);font-size:.88em;margin-bottom:6px} | |
| /* Roadmap & risk */ | |
| .horizon-table{width:100%;border-collapse:separate;border-spacing:0;margin-top:18px;font-size:.95em} | |
| .horizon-table th{font-family:var(--mono);font-size:.66em;letter-spacing:.18em;text-transform:uppercase;color:var(--w3);text-align:left;padding:12px 14px;border-bottom:1px solid var(--line);font-weight:500} | |
| .horizon-table td{padding:14px;border-bottom:1px solid var(--line);vertical-align:top} | |
| .horizon-table tr:last-child td{border-bottom:none} | |
| .horizon-table .h{font-family:var(--mono);font-size:.7em;letter-spacing:.16em;text-transform:uppercase;white-space:nowrap} | |
| .horizon-table .h.now{color:var(--live)} | |
| .horizon-table .h.short{color:#7ad0ff} | |
| .horizon-table .h.med{color:#f0e07d} | |
| .horizon-table .h.long{color:#a48cff} | |
| .horizon-table .name{font-family:var(--display);font-weight:600;letter-spacing:.04em} | |
| .horizon-table .rationale{color:var(--w2);font-size:.95em} | |
| .horizon-table tr:hover td{background:rgba(255,255,255,.015)} | |
| .risk-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-top:18px} | |
| @media(max-width:760px){.risk-grid{grid-template-columns:1fr}} | |
| .risk-card{padding:18px;border:1px solid var(--line);border-radius:12px;background:rgba(255,140,184,.025);position:relative} | |
| .risk-card::before{content:'';position:absolute;left:0;top:14px;bottom:14px;width:2px;background:linear-gradient(180deg, rgba(255,140,184,.7), rgba(255,140,184,0))} | |
| .risk-card h4{margin:0 0 6px 0;font-size:1.05em;letter-spacing:.04em;display:flex;align-items:center;gap:8px} | |
| .risk-card p{color:var(--w2);font-size:.95em;line-height:1.6;margin:6px 0} | |
| .risk-card .mitigation{margin-top:10px;padding-top:10px;border-top:1px dashed rgba(255,255,255,.08);font-family:var(--mono);font-size:.72em;color:var(--w3);letter-spacing:.04em} | |
| .risk-card .mitigation::before{content:'mitigation · ';color:#7df0a8} | |
| /* R&D */ | |
| .rnd-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px} | |
| @media(max-width:1080px){.rnd-grid{grid-template-columns:1fr}} | |
| .rnd-paper-card{padding:24px;display:flex;flex-direction:column;gap:12px} | |
| .rnd-paper-card .author{font-family:var(--mono);font-size:.72em;color:var(--w3);letter-spacing:.14em;text-transform:uppercase} | |
| .rnd-paper-card .ttl{font-family:var(--display);font-weight:600;font-size:1.3em;letter-spacing:.03em;line-height:1.2} | |
| .rnd-paper-card .abs{color:var(--w2);font-size:.95em} | |
| .rnd-paper-card .actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:6px} | |
| .rnd-side-card{padding:20px;display:flex;flex-direction:column;gap:10px} | |
| .rnd-side-card h3{font-family:var(--display);font-size:.95em;font-weight:600;letter-spacing:.14em;text-transform:uppercase;padding-bottom:8px;border-bottom:1px solid var(--line)} | |
| .podcast-player{display:flex;align-items:center;gap:12px;padding:14px;border:1px solid var(--line);border-radius:10px;background:rgba(255,255,255,.02)} | |
| .podcast-player .play{width:42px;height:42px;border-radius:50%;border:1px solid var(--line2); | |
| display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;font-family:var(--display);font-size:.9em;transition:background .2s,border-color .2s} | |
| .podcast-player .play:hover{background:rgba(255,255,255,.06);border-color:var(--w)} | |
| .podcast-player .meta{font-family:var(--mono);font-size:.74em;color:var(--w2);letter-spacing:.04em} | |
| .podcast-player .meta .t{color:var(--w3);font-size:.85em;margin-top:2px} | |
| /* Modal */ | |
| .modal-bg{position:fixed;inset:0;background:rgba(0,0,0,.82);backdrop-filter:blur(5px); | |
| z-index:200;opacity:0;pointer-events:none;transition:opacity .25s;display:flex;align-items:center;justify-content:center;padding:24px} | |
| .modal-bg.open{opacity:1;pointer-events:auto} | |
| .modal{max-width:680px;width:100%;max-height:85vh;overflow-y:auto;padding:0;transform:translateY(10px);transition:transform .3s;background:#0a0a0e} | |
| .modal-bg.open .modal{transform:translateY(0)} | |
| .modal.wide{max-width:1100px;max-height:95vh} | |
| .modal-head{display:flex;justify-content:space-between;align-items:center;padding:16px 22px;border-bottom:1px solid var(--line)} | |
| .modal-head h3{font-family:var(--display);font-size:.95em;font-weight:600;letter-spacing:.14em;text-transform:uppercase} | |
| .modal-head .x{font-size:1.5em;color:var(--w3);cursor:pointer;line-height:1;padding:0 4px;background:none;border:0} | |
| .modal-body{padding:20px} | |
| .modal-body.flush{padding:0} | |
| .modal-body h4{font-family:var(--display);font-size:.78em;letter-spacing:.16em;text-transform:uppercase;color:var(--w3);margin:14px 0 8px} | |
| .modal-body ol{padding-left:18px;color:var(--w2)} | |
| .modal-body ol li{padding:4px 0} | |
| .modal-body p{color:var(--w2);margin-bottom:10px} | |
| .pdf-frame{width:100%;height:85vh;border:0;background:#000;display:block} | |
| /* Affiliates */ | |
| .aff-wrap{display:grid;grid-template-columns:1fr 1fr;gap:16px} | |
| @media(max-width:900px){.aff-wrap{grid-template-columns:1fr}} | |
| .aff-pill-row{display:flex;flex-wrap:wrap;gap:10px;margin-top:10px} | |
| .lvl-row{display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px dashed rgba(255,255,255,.06)} | |
| .lvl-row .l{font-family:var(--mono);font-size:.66em;color:var(--w3);letter-spacing:.14em;text-transform:uppercase} | |
| .lvl-row .v{font-family:var(--display);font-weight:600;font-size:.95em} | |
| #ref-link{font-family:var(--mono);background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:6px;padding:9px;font-size:.74em;word-break:break-all;color:var(--w2);margin-top:8px} | |
| /* Query interface */ | |
| .query-shell{padding:24px} | |
| .query-input{display:flex;flex-direction:column;gap:10px} | |
| .query-input textarea{width:100%;min-height:120px;background:rgba(255,255,255,.04);border:1px solid var(--line); | |
| border-radius:10px;padding:14px;color:var(--w);font-family:var(--mono);font-size:1.1em;letter-spacing:.04em; | |
| resize:vertical;outline:none;line-height:1.4} | |
| .query-input textarea:focus{border-color:var(--line3)} | |
| .query-controls{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin-top:12px} | |
| .query-ctrl{padding:10px 12px;border:1px solid var(--line);border-radius:8px;background:rgba(0,0,0,.3)} | |
| .query-ctrl label{display:block;font-family:var(--mono);font-size:.62em;color:var(--w3);letter-spacing:.14em;text-transform:uppercase;margin-bottom:6px} | |
| .query-ctrl input,.query-ctrl select{width:100%;background:transparent;border:none;outline:none;color:var(--w);font-family:var(--mono);font-size:.88em} | |
| .query-out{margin-top:14px;padding:14px;background:rgba(0,0,0,.45);border:1px solid var(--line);border-radius:10px; | |
| font-family:var(--mono);font-size:.78em;color:var(--w2);line-height:1.55;min-height:80px;white-space:pre-wrap;word-break:break-word} | |
| .query-out .key{color:var(--math)} | |
| .query-out .val{color:var(--lang)} | |
| .query-out .dim{color:var(--w4)} | |
| .cta-row{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px} | |
| /* Deployment page */ | |
| .deploy-step{padding:18px;border:1px solid var(--line);border-radius:12px;margin-bottom:12px;background:rgba(0,0,0,.3)} | |
| .deploy-step h3{font-family:var(--display);font-size:1em;font-weight:600;letter-spacing:.06em;margin-bottom:10px;display:flex;align-items:center;gap:10px} | |
| .deploy-step h3 .num{display:inline-flex;width:28px;height:28px;border-radius:50%;background:rgba(255,255,255,.06);border:1px solid var(--line2);align-items:center;justify-content:center;font-family:var(--mono);font-size:.78em} | |
| .deploy-step p{color:var(--w2);font-size:.92em;margin-bottom:8px} | |
| .secret-table{width:100%;border-collapse:collapse;font-family:var(--mono);font-size:.78em;margin-top:10px} | |
| .secret-table th,.secret-table td{padding:9px 12px;text-align:left;border-bottom:1px solid var(--line)} | |
| .secret-table th{font-family:var(--display);font-size:.72em;letter-spacing:.14em;text-transform:uppercase;color:var(--w3);font-weight:500} | |
| .secret-table td:first-child{color:var(--math)} | |
| .secret-table tr:last-child td{border-bottom:0} | |
| /* Symbol legend strip (5 cards on home page) */ | |
| .band-legend{display:grid;grid-template-columns:repeat(6,1fr);gap:10px;margin-top:18px} | |
| .band-card{padding:14px;border:1px solid var(--line);border-radius:10px;background:rgba(0,0,0,.3); | |
| display:flex;flex-direction:column;gap:9px;transition:border-color .25s,transform .25s;cursor:pointer} | |
| .band-card:hover{border-color:var(--line2);transform:translateY(-1px)} | |
| .band-card-name{font-family:var(--display);font-size:.78em;font-weight:600;letter-spacing:.12em;text-transform:uppercase;display:flex;align-items:baseline;gap:6px} | |
| .band-card-name .glyph{font-size:1.5em;font-weight:700} | |
| .band-card-name .rng{margin-left:auto;font-family:var(--mono);font-size:.7em;color:var(--w3);letter-spacing:.08em;text-transform:none} | |
| .band-card-state{font-family:var(--mono);font-size:.66em;color:var(--w2);letter-spacing:.06em;line-height:1.6} | |
| .band-card-samples{font-size:1.2em;letter-spacing:.1em;color:var(--w);min-height:1.6em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} | |
| @media(max-width:1080px){.band-legend{grid-template-columns:repeat(3,1fr)}} | |
| @media(max-width:620px){.band-legend{grid-template-columns:repeat(2,1fr)}} | |
| /* footer */ | |
| .footer{margin-top:40px;border-top:1px solid var(--line);padding:20px 28px 20px;background:#020203;margin-bottom:0;flex:0 0 auto} | |
| .foot-row{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:14px} | |
| .foot-row .l{display:flex;align-items:center;gap:14px;font-family:var(--mono);font-size:.7em;color:var(--w3);letter-spacing:.14em;text-transform:uppercase} | |
| .foot-row .l img{width:22px;height:22px} | |
| .cap-toggle{font-family:var(--display);font-size:.72em;font-weight:600;letter-spacing:.18em;text-transform:uppercase;display:inline-flex;align-items:center;gap:8px;border:1px solid var(--line2);border-radius:999px;padding:7px 13px;cursor:pointer} | |
| .cap-toggle:hover{border-color:var(--line3)} | |
| .cap-toggle .arrow{display:inline-block;transition:transform .3s;font-size:.7em} | |
| .cap-toggle.open .arrow{transform:rotate(180deg)} | |
| .cap-menu{margin-top:14px;max-height:0;overflow:hidden;transition:max-height .45s cubic-bezier(.22,.61,.36,1)} | |
| .cap-menu.open{max-height:1500px} | |
| .cap-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px;padding:16px 0} | |
| .cap-link{padding:12px;border:1px solid var(--line);border-radius:8px;transition:border-color .2s,transform .2s;cursor:pointer} | |
| .cap-link:hover{border-color:var(--line3);transform:translateY(-1px)} | |
| .cap-link .n{font-family:var(--display);font-size:.82em;font-weight:600;letter-spacing:.06em} | |
| .cap-link .u{font-family:var(--mono);font-size:.62em;color:var(--w3);letter-spacing:.06em;margin-top:3px;word-break:break-all} | |
| @media(max-width:760px){ | |
| .hero .stats{grid-template-columns:repeat(2,1fr)} | |
| .api-grid,.two-col,.rnd-grid{grid-template-columns:1fr} | |
| .kpi-row{grid-template-columns:repeat(2,1fr)} | |
| .scan-grid{grid-template-columns:1fr} | |
| #wallet-btn{padding:0 10px} | |
| #wallet-btn .addr{font-size:.7em} | |
| } | |
| .txt-mono{font-family:var(--mono)} | |
| .txt-up{text-transform:uppercase;letter-spacing:.14em} | |
| .txt-mute{color:var(--w3)} | |
| .txt-sm{font-size:.85em} | |
| .divider{height:1px;background:linear-gradient(90deg,transparent,var(--line2),transparent);margin:24px 0} | |
| ::selection{background:rgba(255,255,255,.18);color:var(--w)} | |
| ::-webkit-scrollbar{width:8px;height:8px} | |
| ::-webkit-scrollbar-track{background:#000} | |
| ::-webkit-scrollbar-thumb{background:rgba(255,255,255,.12);border-radius:8px} | |
| ::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.22)} | |
| @media(prefers-reduced-motion:reduce){.page{transition:none}} | |
| </style> | |
| </head> | |
| <body> | |
| <header class="topbar" id="topbar"> | |
| <a class="brand" data-link="home"> | |
| <img class="phi" src="https://huggingface.co/spaces/CPater/chainstate/resolve/main/phi.png" alt="CHAINSTATE" onerror="this.style.display='none'"> | |
| <span class="name">CHAIN<span class="light">STATE</span></span> | |
| </a> | |
| <nav class="nav" id="nav"> | |
| <div class="nav-group" id="home-group"> | |
| <a class="nav-item" data-link="home">Home <span class="chev">▾</span></a> | |
| <div class="nav-dd"> | |
| <a data-link="terminal">Terminal</a> | |
| <a data-link="api">API</a> | |
| <a data-link="instructions">Instructions</a> | |
| <a data-link="rnd">NWO R&D</a> | |
| <a data-link="roadmap">Roadmap</a> | |
| <a data-link="affiliates">Affiliates</a> | |
| </div> | |
| </div> | |
| <a class="nav-item" data-link="explorer">SCAN</a> | |
| <a class="nav-item" data-link="query">Query</a> | |
| <a class="nav-item" data-link="symbols">Symbols</a> | |
| <div class="nav-group" id="features-group"> | |
| <a class="nav-item">Features <span class="chev">▾</span></a> | |
| <div class="nav-dd"> | |
| <div class="sub-label">Symbolic core</div> | |
| <a data-link="f-use">Universal Semiotic Embedding</a> | |
| <a data-link="f-sam">Symbolic Attention</a> | |
| <a data-link="f-vocab">Cross-Subspace Composition</a> | |
| <div class="sub-label">Consensus</div> | |
| <a data-link="f-pocw">Proof-of-Cognitive-Work</a> | |
| <a data-link="f-pool">Log-Pooling Bayesian</a> | |
| <a data-link="f-rep">Reputation System</a> | |
| <div class="sub-label">Chain</div> | |
| <a data-link="f-txn">Cognitive Transactions</a> | |
| <a data-link="f-block">Block Production</a> | |
| <a data-link="f-stake">$STATE Staking</a> | |
| <div class="sub-label">Integrations</div> | |
| <a data-link="f-asm">NWO-ASM Bridge</a> | |
| <a data-link="f-neuro">NWO NEURO Bridge</a> | |
| <a data-link="f-quantum">Quantum Offload</a> | |
| <div class="sub-label">Network</div> | |
| <a data-link="f-edge">Edge Dispatcher</a> | |
| <a data-link="f-beacon">Swarm Beacon</a> | |
| <a data-link="f-cache">Result Caching</a> | |
| <div class="sub-label">Ecosystem</div> | |
| <a data-link="f-market">DApp Marketplace</a> | |
| </div> | |
| </div> | |
| <a class="nav-item" data-link="architecture">Architecture</a> | |
| <a class="nav-item" data-link="deployment">Deploy</a> | |
| </nav> | |
| <div class="topbar-right"> | |
| <button class="ghost sm" id="wallet-btn"> | |
| <span style="width:6px;height:6px;border-radius:50%;background:var(--w3);display:inline-block"></span> | |
| <span class="addr">Connect Wallet</span> | |
| </button> | |
| <div class="burger" id="burger"><span></span></div> | |
| </div> | |
| </header> | |
| <main class="stage" id="stage"> | |
| <!-- ===== HOME ===== --> | |
| <section class="page active" data-page="home"> | |
| <!-- Sticky hide/show toggle for the hero block --> | |
| <div class="home-toggle-bar"> | |
| <button class="home-toggle-btn" id="home-toggle-btn" onclick="toggleHomeHero()"> | |
| <span class="ic">▾</span><span class="lbl">Hide hero & symbol bands</span> | |
| </button> | |
| </div> | |
| <!-- Collapsible hero (infinity-flow canvas + stats + 6 subspace bands) --> | |
| <div class="home-collapsible" id="home-collapsible"> | |
| <div class="hero" id="hero"> | |
| <canvas id="hero-canvas"></canvas> | |
| <div class="hero-fade"></div> | |
| <div class="hero-inner"> | |
| <div class="eyebrow">CHAINSTATE · symbolic-weight blockchain · Base mainnet · NWO-ASM integrated</div> | |
| <h1>Symbolic-Weight<br><span class="accent">Blockchain</span></h1> | |
| <p class="lede">A blockchain where <strong>transactions ARE cognitive queries</strong>, weights are universal symbols (∫ ∂ 🧬 ☉ ♂ 一 अ ﺍ ⛓), and consensus emerges from reputation-weighted Bayesian log-pooling over a distributed language-model swarm. Fully composed with <strong>NWO-ASM</strong> (Process-Matrix IR · quantum offload) and <strong>NWO NEURO</strong> (live MSS conditioning). Same wallet, one USDC settlement layer, atomic 15% referrer split.</p> | |
| <div class="stats"> | |
| <div class="stat"><div class="v">65,536</div><div class="l">symbolic dimensions</div></div> | |
| <div class="stat"><div class="v">6</div><div class="l">symbolic subspaces</div></div> | |
| <div class="stat"><div class="v">∞</div><div class="l">consensus depth</div></div> | |
| <div class="stat"><div class="v">PoCW</div><div class="l">proof-of-cognitive-work</div></div> | |
| </div> | |
| <div class="band-legend" id="band-legend"></div> | |
| </div> | |
| <div class="scroll-cue" data-link="explorer" style="cursor:pointer"><span>Swipe / tap · SCAN</span><span class="l"></span></div> | |
| </div> | |
| </div> | |
| <!-- Quick Query — mirror of the Query page form, with hq- prefixed IDs --> | |
| <div class="wrap"> | |
| <section class="tight"> | |
| <div class="section-head"><div><div class="eyebrow">module · quick query</div><h2>Run a cognitive transaction</h2></div></div> | |
| <div class="query-shell shim shim-slow"> | |
| <div class="query-input"> | |
| <textarea id="hq-text" placeholder="e.g. ∫∂x → ? or Solve ☉☽☿ in alchemy or 🧬🔬⚗ → ? or explain CRDTs"></textarea> | |
| <div class="query-controls"> | |
| <div class="query-ctrl"> | |
| <label>consensus depth</label> | |
| <input id="hq-depth" type="number" value="3" min="1" max="7"> | |
| </div> | |
| <div class="query-ctrl"> | |
| <label>swarm size</label> | |
| <input id="hq-size" type="number" value="20" min="10" max="100"> | |
| </div> | |
| <div class="query-ctrl"> | |
| <label>quantum offload</label> | |
| <select id="hq-quantum"><option value="none">none</option><option value="ibm">IBM Sherbrooke</option><option value="origin">Origin Wukong</option></select> | |
| </div> | |
| <div class="query-ctrl"> | |
| <label>cache</label> | |
| <select id="hq-cache"><option value="true">use (5-min KV)</option><option value="false">bypass</option></select> | |
| </div> | |
| </div> | |
| <div class="cta-row"> | |
| <button class="ghost bold" onclick="runQuery('hq-')">⛓ Submit cognitive transaction</button> | |
| <button class="ghost" onclick="symInsert('∫∂x → ?', 'hq-')">Try math</button> | |
| <button class="ghost" onclick="symInsert('☉☽☿ ♀♂ ☯ ☤', 'hq-')">Try occult</button> | |
| <button class="ghost" onclick="symInsert('🧠 🤔 💎 → ✨', 'hq-')">Try emoji</button> | |
| <button class="ghost" onclick="symInsert('道 心 学 智 一 二 三', 'hq-')">Try CJK</button> | |
| </div> | |
| <div class="query-out" id="hq-out"><span class="dim">Result will appear here. The chain dispatches your query to the swarm (default 20 nodes), each node emits a 65,536-d symbolic state, the consensus layer log-pools them, and the answer is returned.</span></div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Quick SCAN — block / tx / address lookup --> | |
| <section class="tight"> | |
| <div class="section-head"><div><div class="eyebrow">module · quick scan</div><h2>Look up a block, transaction, or query</h2></div></div> | |
| <div class="quick-scan-shell shim"> | |
| <div class="scan-search"> | |
| <input id="home-scan-input" type="text" placeholder="🔍 Search by block height, tx hash, sender address, or query text…" onkeydown="if(event.key==='Enter')homeScanGo()"> | |
| <button class="ghost bold" onclick="homeScanGo()">⛓ Scan</button> | |
| </div> | |
| <p class="txt-sm txt-mute" style="margin:10px 0 0 0">Opens the SCAN page with the search pre-applied. Use a block height (e.g. <code>#1024</code>), a transaction hash, a wallet address, or any text contained in a query.</p> | |
| </div> | |
| </section> | |
| </div> | |
| </section> | |
| <!-- ===== EXPLORER (CHAINSTATE SCAN) ===== --> | |
| <section class="page" data-page="explorer"></section> | |
| <!-- ===== QUERY ===== --> | |
| <section class="page" data-page="query"></section> | |
| <!-- ===== TERMINAL ===== --> | |
| <section class="page" data-page="terminal"></section> | |
| <!-- ===== SYMBOLS ===== --> | |
| <section class="page" data-page="symbols"></section> | |
| <!-- ===== FEATURE SHELLS ===== --> | |
| <section class="page" data-page="f-use"></section> | |
| <section class="page" data-page="f-sam"></section> | |
| <section class="page" data-page="f-vocab"></section> | |
| <section class="page" data-page="f-pocw"></section> | |
| <section class="page" data-page="f-pool"></section> | |
| <section class="page" data-page="f-rep"></section> | |
| <section class="page" data-page="f-txn"></section> | |
| <section class="page" data-page="f-block"></section> | |
| <section class="page" data-page="f-stake"></section> | |
| <section class="page" data-page="f-asm"></section> | |
| <section class="page" data-page="f-neuro"></section> | |
| <section class="page" data-page="f-quantum"></section> | |
| <section class="page" data-page="f-edge"></section> | |
| <section class="page" data-page="f-beacon"></section> | |
| <section class="page" data-page="f-cache"></section> | |
| <section class="page" data-page="f-market"></section> | |
| <!-- ===== Other pages ===== --> | |
| <section class="page" data-page="architecture"></section> | |
| <section class="page" data-page="instructions"></section> | |
| <section class="page" data-page="roadmap"></section> | |
| <section class="page" data-page="api"></section> | |
| <section class="page" data-page="rnd"></section> | |
| <section class="page" data-page="deployment"></section> | |
| <section class="page" data-page="affiliates"></section> | |
| </main> | |
| <footer class="footer"> | |
| <div class="foot-row"> | |
| <div class="l"> | |
| <img src="https://huggingface.co/spaces/CPater/chainstate/resolve/main/phi.png" alt="" onerror="this.style.display='none'"> | |
| <span>CHAINSTATE · v0.1 · static HF Space · Base mainnet 8453</span> | |
| </div> | |
| <div class="cap-toggle" id="cap-toggle"> | |
| <span>NWO·CAPITAL</span><span class="arrow">▾</span> | |
| </div> | |
| </div> | |
| <div class="cap-menu" id="cap-menu"> | |
| <div class="cap-grid"> | |
| <a class="cap-link shim" href="https://nwo.capital" target="_blank" rel="noopener"><div class="n">NWO Capital</div><div class="u">nwo.capital</div></a> | |
| <a class="cap-link shim" href="https://cpater-nwo-capital.static.hf.space" target="_blank" rel="noopener"><div class="n">NWO Capital HF</div><div class="u">cpater-nwo-capital.static.hf.space</div></a> | |
| <a class="cap-link shim" href="https://cpater-nwo-asm.static.hf.space" target="_blank" rel="noopener"><div class="n">NWO-ASM</div><div class="u">cpater-nwo-asm.static.hf.space</div></a> | |
| <a class="cap-link shim" href="https://cpater-nwo-neuro.static.hf.space" target="_blank" rel="noopener"><div class="n">NWO NEURO</div><div class="u">cpater-nwo-neuro.static.hf.space</div></a> | |
| <a class="cap-link shim" href="https://cpater-metastate.static.hf.space" target="_blank" rel="noopener"><div class="n">METASTATE</div><div class="u">cpater-metastate.static.hf.space</div></a> | |
| <a class="cap-link shim" href="https://cpater-nwo-cardiac.static.hf.space" target="_blank" rel="noopener"><div class="n">NWO Cardiac</div><div class="u">cpater-nwo-cardiac.static.hf.space</div></a> | |
| <a class="cap-link shim" href="https://cpater-nwo-metaverse.static.hf.space" target="_blank" rel="noopener"><div class="n">NWO Metaverse</div><div class="u">cpater-nwo-metaverse.static.hf.space</div></a> | |
| <a class="cap-link shim" href="https://cpater-nwo-asi.static.hf.space" target="_blank" rel="noopener"><div class="n">NWO ASI</div><div class="u">cpater-nwo-asi.static.hf.space</div></a> | |
| <a class="cap-link shim" href="https://cpater-nwo-apocalypse.static.hf.space" target="_blank" rel="noopener"><div class="n">NWO Apocalypse</div><div class="u">cpater-nwo-apocalypse.static.hf.space</div></a> | |
| <a class="cap-link shim" href="https://cpater-nwo-blackbox.static.hf.space" target="_blank" rel="noopener"><div class="n">NWO BLACKBOX</div><div class="u">cpater-nwo-blackbox.static.hf.space</div></a> | |
| <a class="cap-link shim" href="https://cpater-nwo-agentic.static.hf.space" target="_blank" rel="noopener"><div class="n">NWO Agentic</div><div class="u">cpater-nwo-agentic.static.hf.space</div></a> | |
| <a class="cap-link shim" href="https://cpater-imperium-romanum.static.hf.space" target="_blank" rel="noopener"><div class="n">Imperium Romanum</div><div class="u">cpater-imperium-romanum.static.hf.space</div></a> | |
| </div> | |
| </div> | |
| </footer> | |
| <div class="modal-bg" id="modal-bg"> | |
| <div class="modal shim" id="modal"> | |
| <div class="modal-head"> | |
| <h3 id="modal-title">—</h3> | |
| <button class="x" id="modal-x">×</button> | |
| </div> | |
| <div class="modal-body" id="modal-body"></div> | |
| </div> | |
| </div> | |
| <div class="modal-bg" id="pdf-modal-bg"> | |
| <div class="modal wide" id="pdf-modal"> | |
| <div class="modal-head"> | |
| <h3 id="pdf-title">PDF</h3> | |
| <div style="display:flex;align-items:center;gap:10px"> | |
| <a id="pdf-open-tab" class="ghost sm" href="#" target="_blank" rel="noopener">↗ Open in new tab</a> | |
| <button class="x" id="pdf-modal-x">×</button> | |
| </div> | |
| </div> | |
| <div class="modal-body flush"> | |
| <iframe id="pdf-frame" class="pdf-frame" src="about:blank" title="paper"></iframe> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| /* ============================================================ | |
| COMPREHENSIVE SYMBOL REGISTER — 6 subspaces, ~3500 symbols | |
| ============================================================ */ | |
| const SUBSPACES = { | |
| math: { name:'Math', glyph:'∫', col:'var(--math)', range:'0–4,096', dims:4096, | |
| samples:['∫','∂','∇','∆','∑','∏','∈','∉','∪','∩','∀','∃','∄','∅','⊂','⊃','⊆','⊇','⊕','⊗','⊥','⊤','∞','∝','≈','≠','≤','≥','≡','≢','⌊','⌋','⌈','⌉','√','∛','∜','∗','∘','∙','∶','∷','∼','∽','≅','≆','≇','≪','≫','≺','≻','⋀','⋁','⋂','⋃','⋄','⋆','⋇','⋈','⋉','⋊','⋋','⋌','⋍','⋎','⋏','⋐','⋑','⋒','⋓','⋔','⋙','⋘','⋗','⋖','⌀','⌁','⌂','⌃','⌄','⌅','⌆','⌇','⌜','⌝','⌞','⌟','〈','〉','⟨','⟩','⟪','⟫','⟬','⟭','⟮','⟯'], | |
| desc:'Mathematical operators, set theory, logic. Unicode ranges 2200–22FF (Mathematical Operators), 27C0–27EF (Misc Math A), 2980–29FF (Misc Math B).' }, | |
| sci: { name:'Science', glyph:'⚛', col:'var(--sci)', range:'4,096–12,288', dims:8192, | |
| samples:['ℏ','ℵ','ℶ','ℷ','ℸ','ℂ','ℕ','ℚ','ℝ','ℤ','ℙ','ℍ','ℑ','ℜ','℘','ℓ','ℒ','℧','Å','⚗','⚘','⚙','⚚','⚛','🧬','🧫','🧪','🦠','🔬','🔭','🔮','☢','☣','♨','🔋','💡','⚡','🌡','🩺','⚕','🧲','🌊','🌀','🌈','⛓','🔗','🌐','📡','📊','📈','📉','🛰','🚀','🛸','⏳','⌚','⏰','🕰','📐','📏','🧮','🔢','🔣','💎','🪐','☄','⭐','🌟','✨','🌌','🌠','☀','☁','☂','❄','⛄','🔥','💧','🌪','🌋','⛰','🏔'], | |
| desc:'Letterlike symbols (ℝ ℂ ℕ ℚ ℤ ℙ ℍ ℏ ℵ), unit symbols, scientific apparatus, chemistry, biology, physics, astronomy, meteorology. Unicode 2100–214F + 1F52A–1F570 + 26E0–27BF.' }, | |
| lang: { name:'Language', glyph:'文', col:'var(--lang)', range:'12,288–28,672', dims:16384, | |
| samples:['Α','Β','Γ','Δ','Ε','Ζ','Η','Θ','Ι','Κ','Λ','Μ','Ν','Ξ','Ο','Π','Ρ','Σ','Τ','Υ','Φ','Χ','Ψ','Ω','α','β','γ','δ','ε','ζ','η','θ','ι','κ','λ','μ','ν','ξ','ο','π','ρ','ς','σ','τ','υ','φ','χ','ψ','ω','А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я','а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я','一','二','三','四','五','六','七','八','九','十','百','千','万','道','易','心','学','知','行','智','仁','義','禮','信','勇','美','真','善','和','愛','光','空','水','火','土','金','木','日','月','星','天','地','人','王','女','男','子','父','母','子','友','家','国','邦','市','学','校','書','本','字','語','話','言','行','作','見','聞','思','心','念','一','一','ا','ب','ت','ث','ج','ح','خ','د','ذ','ر','ز','س','ش','ص','ض','ط','ظ','ع','غ','ف','ق','ك','ل','م','ن','ه','و','ي','א','ב','ג','ד','ה','ו','ז','ח','ט','י','כ','ל','מ','נ','ס','ע','פ','צ','ק','ר','ש','ת','अ','आ','इ','ई','उ','ऊ','ऋ','ऌ','ऍ','ऎ','ए','ऐ','ऑ','ऒ','ओ','औ','क','ख','ग','घ','ङ','च','छ','ज','झ','ञ','ट','ठ','ड','ढ','ण','त','थ','द','ध','न','प','फ','ब','भ','म','य','र','ल','व','श','ष','स','ह','가','나','다','라','마','바','사','아','자','차','카','타','파','하','한','국','어'], | |
| desc:'All major writing systems. Greek (uppercase + lowercase), Cyrillic, CJK Unified Ideographs (sample), Arabic, Hebrew, Devanagari, Korean Hangul. Foundation for natural-language conditioning of the swarm.' }, | |
| occ: { name:'Occult', glyph:'☉', col:'var(--occ)', range:'28,672–32,768', dims:4096, | |
| samples:['☉','☽','☿','♀','♁','♂','♃','♄','♅','♆','♇','⚹','⛢','⛤','⛥','⛦','⛧','☤','☥','☦','☧','☨','☩','☪','☫','☬','☭','☮','☯','✝','✞','✟','✠','✡','✢','✣','✤','✥','✦','✧','★','☆','✩','✪','✫','✬','✭','✮','✯','✰','♈','♉','♊','♋','♌','♍','♎','♏','♐','♑','♒','♓','🜀','🜁','🜂','🜃','🜄','🜅','🜆','🜇','🜈','🜉','🜊','🜋','🜌','🜍','🜎','🜏','🜐','🜑','🜒','🜓','🜔','🜕','🜖','🜗','🜘','🜙','🜚','🜛','🜜','🜝','🜞','🜟','🜠','🜡','🜢','🜣','🜤','🜥','🜦','🜧','🜨','🜩','🜪','🜫','🜬','🜭','🜮','🜯','🜰','🜱','🜲','🜳','🜴','🜵','🜶','🜷','🜸','🜹','🜺','🜻','🜼','🜽','🜾','🜿','🝀','🝁','🝂','🝃','🝄','🝅','🝆','🝇','🝈','🝉','🝊','🝋','🝌','🝍','🝎','🝏','🝐','🝑','🝒','🝓','🝔','🝕','🝖','🝗','🝘','🝙','🝚','🝛','🝜','🝝','🝞','🝟'], | |
| desc:'Astrological (☉ Sun, ☽ Moon, ☿ Mercury…), zodiac (♈ ♉ ♊…), religious / esoteric (☤ ☥ ☦ ☧ ☪ ☮ ☯ ✝), alchemical symbols (1F700–1F77F). Reserved subspace for high-temperature symbolic dispatch.' }, | |
| emo: { name:'Emoji', glyph:'🧠', col:'var(--emo)', range:'32,768–49,152', dims:16384, | |
| samples:['💀','☠️','👻','🔫','🦾','👽','👾','🤖','😉','😊','😋','😎','😍','😘','😗','😙','😚','🙂','🤗','🤩','🤔','🤨','😐','😑','😶','🙄','😏','😣','😥','😮','🤐','😯','😪','😫','🥱','😴','😌','😛','😜','😝','🤤','😒','😓','😔','😕','🙃','🤑','😲','☹','🙁','😖','😞','😟','😤','😢','😭','😦','😧','😨','😩','🤯','😬','😰','😱','🥵','🥶','😳','🤪','😵','🥴','😡','😠','🤬','😷','🤒','🤕','🤢','🤮','🤧','😇','🥳','🥺','🤠','🤡','🤥','🤫','🤭','🧐','🤓','👽','👾','🤖','💀','☠','👻','😺','😸','😹','😻','😼','😽','🙀','😿','😾','🐵','🐒','🦍','🦧','🐶','🐕','🦮','🐩','🐺','🦊','🦝','🐱','🐈','🦁','🐯','🐅','🐆','🐴','🐎','🦄','🦓','🦌','🐮','🐂','🐃','🐄','🐷','🐖','🐗','🐏','🐑','🐐','🐪','🐫','🦙','🦒','🐘','🦛','🦏','🐭','🐁','🐀','🐹','🐰','🐇','🐿','🦔','🦇','🐻','🐨','🐼','🦥','🦦','🦨','🦘','🦡','🐾','🦃','🐔','🐓','🐣','🐤','🐥','🐦','🐧','🕊','🦅','🦆','🦢','🦉','🦚','🦜','🐸','🐊','🐢','🦎','🐍','🐲','🐉','🦕','🦖','🐳','🐋','🐬','🐟','🐠','🐡','🦈','🐙','🐚','🐌','🦋','🐛','🐜','🐝','🐞','🦗','🕷','🕸','🦂','🦟','🦠','🌍','🌎','🌏','🌐','🗺','🗾','🧭','🏔','⛰','🌋','🗻','🏕','🏖','🏜','🏝','🏞','🏟','🏛','🏗','🧱','🏘','🏚','🏠','🏡','🏢','🏣','🏤','🏥','🏦','🏨','🏩','🏪','🏫','🏬','🏭','🏯','🏰','💒','🗼','🗽','⛪','🕌','🛕','🕍','⛩','🕋','⛲','⛺','🌁','🌃','🏙','🌄','🌅','🌆','🌇','🌉','♨','🎠','🎡','🎢','💈','🎪','🚂','🚃','🚄','🚅','🚆','🚇','🚈','🚉','🚊','🚋','🚌','🚍','🚎','🚏','🚐','🚑','🚒','🚓','🚔','🚕','🚖','🚗','🚘','🚙','🚚','🚛','🚜','🏎','🏍','🛵','🦽','🦼','🛺','🚲','🛴','🛹','🚏','🛣','🛤','🛢','⛽','🚨','🚥','🚦','🛑','🚧','⚓','⛵','🛶','🚤','🛳','⛴','🛥','🚢','✈','🛩','🛫','🛬','🪂','💺','🚁','🚟','🚠','🚡','🛰','🚀','🛸','🛎','🧳','⌛','⏳','⌚','⏰','⏱','⏲','🕰','🕛','🕧','🕐','🕜','🕑','🕝','🕒','🕞','🕓','🕟','🕔','🕠','🕕','🕡','🕖','🕢','🕗','🕣','🕘','🕤','🕙','🕥','🕚','🕦','🌑','🌒','🌓','🌔','🌕','🌖','🌗','🌘','🌙','🌚','🌛','🌜','🌡','☀','🌝','🌞','🪐','⭐','🌟','🌠','🌌','☁','⛅','⛈','🌤','🌥','🌦','🌧','🌨','🌩','🌪','🌫','🌬','🌀','🌈','🌂','☂','☔','⛱','⚡','❄','☃','⛄','☄','🔥','💧','🌊','💼','💸','💳','💴','💵','💶','💷','💰','💎','⚖','🔧','🔨','⚒','🛠','⛏','🔩','⚙','⛓','🔗','🧰','🧲','💣','🧨','🪓','🔪','🗡','⚔','🛡','🚬','⚰','⚱','🏺','🔮','📿','🧿','💈','⚗','🔭','🔬','🕳','💊','💉','🩸','🩹','🩺','🧬','🦠','🧫','🧪','🌡','🧹','🧺','🧻','🧼','🧽','🧯','🛒','🚬','⚰','📡','💻','⌨','🖥','🖨','🖱','🖲','🕹','🗜','💽','💾','💿','📀','📼','📷','📸','📹','🎥','📽','🎞','📞','☎','📟','📠','📺','📻','🎙','🎚','🎛','🧭','⏱','⏲','⏰','🕰','⌛','⏳','📡','🔋','🔌','💡','🔦','🕯','🪔','🧯','🛢','💸','💵','💴','💶','💷','💰','💳','💎','⚖','🧰','🔧','🔨','⚒','🛠','⛏','🔩','⚙','⛓','🔗','🧪','🧬','🦠','💊','💉','🩸','🩹','🩺','🧬','🦠','🌡','🚪','🛏','🛋','🪑','🚽','🚿','🛁','🪒','🧴','🧷','🧹','🧺','🧻','🧼','🧽','🧯','🛒','🚬','⚰','🪦','⚱','🗿','🪧','🪪'], | |
| desc:'Full Unicode 15.1 emoji set across all 9 categories. People & Body, Animals & Nature, Food & Drink, Travel & Places, Activities, Objects, Symbols, Flags. Anchors humour, intent, and cultural register in queries.' }, | |
| ctrl: { name:'Control', glyph:'⇒', col:'var(--ctrl)', range:'49,152–65,536', dims:16384, | |
| samples:['⇒','⇐','⇑','⇓','⇔','⇕','⇖','⇗','⇘','⇙','↺','↻','⟳','⟲','⇄','⇆','⇋','⇌','→','←','↑','↓','↔','↕','↖','↗','↘','↙','⤴','⤵','⤶','⤷','⤸','⤹','⤺','⤻','⟶','⟵','⟷','⟸','⟹','⟺','⟼','⟽','⟾','⟿','⤀','⤁','⤂','⤃','⤄','⤅','⤆','⤇','⤈','⤉','⤊','⤋','⤌','⤍','⤎','⤏','⤐','⤑','⤒','⤓','⤔','⤕','⤖','⤗','⤘','⤙','⤚','⤛','⤜','⤝','⤞','⤟','⤠','⥀','⥁','⥂','⥃','⥄','⥅','⥆','⥇','⥈','⥉','⥊','⥋','⥌','⥍','⥎','⥏','⥐','⥑','⥒','⥓','⥔','⥕','⥖','⥗','⥘','⥙','⥚','⥛','⥜','⥝','⥞','⥟','⥠','⥡','⥢','⥣','⥤','⥥','⥦','⥧','⥨','⥩','⥪','⥫','⥬','⥭','⥮','⥯','⥰','⥱','⥲','⥳','⥴','⥵','⥶','⥷','⥸','⥹','⥺','⥻','␀','␁','␂','␃','␄','␅','␆','␇','␈','␉','␊','␋','␌','␍','␎','␏','␐','␑','␒','␓','␔','␕','␖','␗','␘','␙','␚','␛','␜','␝','␞','␟','␠','␡','␢','␣','','␥','␦','⌫','⌧','⌦','⌨','⏎','⌶','⌷','⌸','⌹','⌺','⌻','⌼','⌽','⌾','⌿','⍀','⍁','⍂','⍃','⍄','⍅','⍆','⍇','⍈','⍉','⍊','⍋','⍌','⍍','⍎','⍏','⍐','⍑','⍒','⍓','⍔','⍕','⍖','⍗','⍘','⍙','⍚','⍛','⍜','⍝','⍞','⍟'], | |
| desc:'Arrow operators, double-arrows, semantic flow controls, APL operators, control characters. Encodes program structure, attention routing, and graph topology in the symbolic substrate.' } | |
| }; | |
| /* ============================================================ | |
| FEATURES — 16 features, each with subpage content | |
| ============================================================ */ | |
| const FEATURES = [ | |
| { id:'f-use', num:'F-01', name:'Universal Semiotic Embedding', | |
| blurb:'65,536-dim symbolic embedding space encoding math, science, all human languages, occult, emoji, and control-flow symbols.', | |
| status:{label:'live',cls:'live'}, | |
| long:'A single 65,536-dimensional embedding space across six subspaces. Every Unicode symbol — mathematical operator, scientific glyph, alphabetic character, alchemical sigil, emoji, or control arrow — has a stable position. The space is built from PyTorch nn.Embedding tables (one per subspace) plus a cross-subspace attention layer that lets a symbol from one domain activate semantically-related symbols in another. The result: ∫ activates ∂, ∇, ∆ (math), ℏ, ℵ (physics), 🔬, 🧮 (instruments), ⇒, ↺ (process flow).', | |
| bullets:[ | |
| 'Math (4,096 dims) · operators, set theory, logic, relations', | |
| 'Science (8,192 dims) · letterlike, units, chemistry, biology, physics, astronomy', | |
| 'Language (16,384 dims) · Greek, Cyrillic, CJK, Arabic, Hebrew, Devanagari, Korean', | |
| 'Occult (4,096 dims) · astrological, religious, alchemical, esoteric', | |
| 'Emoji (16,384 dims) · full Unicode 15.1 emoji set', | |
| 'Control (16,384 dims) · arrows, double-arrows, APL, flow-control', | |
| ], | |
| eco:[ | |
| ['NWO-ASM','symbolic ops compile to PMX IR via the ASM bridge'], | |
| ['NWO NEURO','MSS scalars condition the embedding lookup'], | |
| ['Swarm nodes','each node hosts a quantised shard of the embedding'], | |
| ['Query layer','user input is tokenised to symbols, embedded to 4096-d slice'], | |
| ], | |
| flow:'use' }, | |
| { id:'f-sam', num:'F-02', name:'Symbolic Attention Mechanism', | |
| blurb:'Cross-subspace attention with a learned 65,536² interaction mask. Math↔Science strong, Language↔All medium, Occult↔Control strong, Emoji↔All weak.', | |
| status:{label:'live',cls:'live'}, | |
| long:'Standard attention computes softmax(QKᵀ/√d)V across a uniform space. Symbolic Attention adds a per-subspace interaction mask: certain subspaces are wired to attend strongly to each other (math↔science, occult↔control), some moderately (language↔all), some weakly (emoji↔all). The mask is a 65,536×65,536 sparse tensor materialised at module init. Multi-head: 64 heads of 1,024 dims each. Output flows into the swarm consensus layer.', | |
| bullets:[ | |
| '64-head attention with 1,024-dim head size', | |
| '65,536×65,536 sparse interaction mask', | |
| 'Math↔Science 1.0 · Language↔All 0.5 · Occult↔Control 1.0 · Emoji↔All 0.1', | |
| 'Output projection + LayerNorm + residual', | |
| 'GELU activation in the composition feedforward', | |
| 'Per-head causal masking optional for autoregressive flows', | |
| ], | |
| eco:[ | |
| ['USE','consumes the embedding output'], | |
| ['NWO-ASM','attention pattern translatable to PMX schedule'], | |
| ['Swarm consensus','attention output is the per-node symbolic state'], | |
| ], | |
| flow:'sam' }, | |
| { id:'f-vocab', num:'F-03', name:'Cross-Subspace Composition', | |
| blurb:'Gated residual composition over the attention output. Sigmoid gates per-subspace; layer norm; GELU expansion.', | |
| status:{label:'live',cls:'live'}, | |
| long:'Composition turns attention output into the next-state symbolic vector. A 2× linear expansion (65,536 → 131,072) is gated by four parallel sigmoid gates that selectively pass attention vs residual signal. The expansion is followed by LayerNorm and GELU. The four gates are trained to specialise: gate-0 holds math/science continuity, gate-1 language continuity, gate-2 occult/control state, gate-3 emoji affect. Empirically this stabilises long-horizon symbolic reasoning where pure-residual blocks drift.', | |
| bullets:[ | |
| '2× linear expansion + LayerNorm + GELU + 0.5× projection', | |
| '4 parallel sigmoid gates over the residual', | |
| 'Per-subspace specialisation through gate initialisation', | |
| 'Stable over 32+ composition layers without exploding norms', | |
| ], | |
| eco:[ | |
| ['SAM','consumes attention output, produces next-state vector'], | |
| ['Swarm consensus','per-node next-state goes into log-pooling'], | |
| ], | |
| flow:'vocab' }, | |
| { id:'f-pocw', num:'F-04', name:'Proof-of-Cognitive-Work', | |
| blurb:'Every transaction is a cognitive query resolved by the swarm. Work proven by the symbolic state hash, not by useless hashing.', | |
| status:{label:'live',cls:'live'}, | |
| long:'Bitcoin\'s PoW wastes joules on SHA-256 inversion. CHAINSTATE\'s Proof-of-Cognitive-Work has nodes execute a real inference task (the user\'s query). The work output IS the answer the user paid for. Each node emits a NodeOutput { node_id, symbolic_state[65536], confidence, compute_proof }. The compute_proof is SHA3-256(node_id ‖ query ‖ start_ts ‖ state[:1024]) — cheap to verify, expensive to forge without actually running the model. Reputation rewards accuracy; slashing penalises drift.', | |
| bullets:[ | |
| 'Useful work — inference, not hashing', | |
| 'Compute proof is a SHA3-256 over (node, query, ts, top-1024 dims)', | |
| 'Verifiable in <1 ms; forgery requires inference at scale', | |
| 'Reputation score gates next-round node selection', | |
| 'Slashing on deliberate divergence from consensus', | |
| ], | |
| eco:[ | |
| ['Swarm nodes','submit NodeOutput per query'], | |
| ['Consensus','log-pooling over reputation-weighted outputs'], | |
| ['Settlement','per-call USDC settlement after consensus reached'], | |
| ], | |
| flow:'pocw' }, | |
| { id:'f-pool', num:'F-05', name:'Log-Pooling Bayesian Consensus', | |
| blurb:'Iterative reputation-weighted log-pooling. Converges in 3–7 rounds; convergence threshold 0.95 cosine agreement.', | |
| status:{label:'live',cls:'live'}, | |
| long:'Each round: stack node states (k nodes × 65,536), apply log_softmax, weight rows by node reputation, sum → log_consensus. Convert back via exp(log_consensus − logsumexp). Round 2: keep nodes with cosine(state, consensus) > 0.7; recompute. Round 3–7: same. Stop when cosine(consensus_t, consensus_{t-1}) > 0.95. The math is exactly the Bayesian product-of-experts under a flat prior — the consensus is the posterior over all node beliefs, weighted by trust.', | |
| bullets:[ | |
| 'log P(consensus) = Σᵢ wᵢ · log P(nodeᵢ)', | |
| 'Per-round agreement filter at 0.7 cosine', | |
| 'Convergence threshold 0.95 cosine vs prior round', | |
| 'Hard min participation: 10 nodes; consensus aborts below threshold', | |
| 'Gas calculated from (n_nodes × coordination + depth × verification + ms × compute)', | |
| ], | |
| eco:[ | |
| ['PoCW','consumes per-node outputs'], | |
| ['Reputation','updated post-consensus based on accuracy vs final state'], | |
| ['NWO-ASM','high-depth consensus offloads to PMX quantum substrate'], | |
| ], | |
| flow:'pool' }, | |
| { id:'f-rep', num:'F-06', name:'Reputation System', | |
| blurb:'Exponential-moving-average per-node reputation. Reward α·accuracy on >0.8, penalty β·(1-accuracy) on <0.5, γ decay otherwise.', | |
| status:{label:'live',cls:'live'}, | |
| long:'Reputation lives in [0, 100] per node. After consensus: cosine similarity vs consensus is the accuracy. Above 0.8 → reward of α·accuracy added (α = 0.1). Below 0.5 → penalty of β·(1 − accuracy) subtracted (β = 0.2). In between → multiply by γ = 0.99 (small decay). Inactive >24h → also decayed. Top-N selection per query is reputation-weighted top-K with a small ε-greedy random sample to give new nodes a chance.', | |
| bullets:[ | |
| 'Reputation ∈ [0, 100], default 50 for new nodes', | |
| 'α = 0.1 (reward) · β = 0.2 (penalty) · γ = 0.99 (decay)', | |
| 'Per-call top-K selection with ε-greedy exploration', | |
| 'Inactive >24h triggers decay-only updates', | |
| 'Historical accuracy_history maintained per node', | |
| ], | |
| eco:[ | |
| ['Pool','consumes reputations to weight log-pool'], | |
| ['$STATE','stake amount caps maximum reputation',], | |
| ['Beacon','reputations published in node list',], | |
| ], | |
| flow:'rep' }, | |
| { id:'f-txn', num:'F-07', name:'Cognitive Transactions', | |
| blurb:'A transaction IS a cognitive query. Sender + nonce + query + gas_price + max_gas. Hash is SHA3 over the bundle.', | |
| status:{label:'live',cls:'live'}, | |
| long:'CognitiveTransaction { hash, sender, query, nonce, gas_price, max_gas, ts, result, receipt }. Hash = SHA3-256(sender ‖ nonce ‖ query ‖ ts)[:16]. Receipt is populated after consensus. The mempool is just a Redis sorted set keyed by (gas_price, ts). A block proposer pulls the top-N transactions, dispatches each to the swarm, collects consensus results, and bundles the block. No mining; the proposer is rotated by reputation-weighted VRF.', | |
| bullets:[ | |
| 'Query string is the full transaction payload', | |
| 'Per-byte gas pricing — no scarcity, only useful compute', | |
| 'EIP-155 chain_id binding for Base mainnet (8453)', | |
| 'Receipt includes consensus_state, participating_nodes, depth, ms', | |
| 'Replay protection via (sender, nonce) uniqueness', | |
| ], | |
| eco:[ | |
| ['Block','transactions bundle into blocks via proposer rotation'], | |
| ['NWO Capital','same wallet, same USDC gateway as all NWO services'], | |
| ['Mempool','Redis-backed priority queue'], | |
| ], | |
| flow:'txn' }, | |
| { id:'f-block', num:'F-08', name:'Block Production', | |
| blurb:'Reputation-weighted VRF selects the proposer. 2-second block target. Block = batch of cognitive transactions + consensus receipts.', | |
| status:{label:'beta',cls:'beta'}, | |
| long:'A new block every ~2 s. Proposer chosen by VRF seeded with (prev_hash, round) and weighted by reputation. The proposer pulls up to 64 transactions from the mempool, dispatches each to the swarm (parallel), waits for consensus or timeout (30 s per query), and assembles the block. Block = { parent_hash, height, timestamp, proposer_id, txs[64], receipts[64], consensus_root, signature }. Soft finality at 1 confirmation; hard finality at 6 confirmations (~12 s).', | |
| bullets:[ | |
| '2 s target block time', | |
| '64 transactions per block hard cap', | |
| 'Proposer rotation via reputation-weighted VRF', | |
| 'Soft finality at 1 confirmation, hard at 6', | |
| 'Block signed with proposer\'s Dilithium key', | |
| ], | |
| eco:[ | |
| ['Mempool','source of pending transactions'], | |
| ['Consensus','consumed for receipt assembly'], | |
| ['SCAN','blocks indexed and visualised on the explorer'], | |
| ], | |
| flow:'block' }, | |
| { id:'f-stake', num:'F-09', name:'$STATE Staking', | |
| blurb:'Stake $STATE to run an inference node. Stake caps reputation; slashable on misbehaviour. Rewards proportional to accurate participation.', | |
| status:{label:'beta',cls:'beta'}, | |
| long:'$STATE is the network gas token (also the staking token). Minimum stake to run a node: 1,000 $STATE. Stake caps reputation at min(stake/10, 100). Slashing conditions: (a) signed but didn\'t respond → 1% slash, (b) responded incorrectly outside 3σ of consensus → 5% slash, (c) signed conflicting outputs → 100% slash. Rewards: per-call USDC fees split 70% to participating nodes (by reputation), 20% to treasury, 10% to the proposer. $STATE itself emits at 2% APY to active stakers, decaying to 0% over 10 years.', | |
| bullets:[ | |
| 'Min stake: 1,000 $STATE', | |
| 'Reputation cap = min(stake / 10, 100)', | |
| 'Slashing: 1% (no-show), 5% (incorrect), 100% (conflicting)', | |
| 'USDC fee split: 70% nodes / 20% treasury / 10% proposer', | |
| '$STATE emission: 2% → 0% APY over 10 years', | |
| ], | |
| eco:[ | |
| ['Reputation','staked nodes have higher reputation cap'], | |
| ['NWO Capital','USDC settlement on Base mainnet'], | |
| ['Affiliates','15% atomic referrer split on every paid call'], | |
| ], | |
| flow:'stake' }, | |
| { id:'f-asm', num:'F-10', name:'NWO-ASM Bridge', | |
| blurb:'Symbolic operations compile to Process-Matrix IR (.pmx) and dispatch via the NWO-ASM substrate. Same gateway, same key, same audit.', | |
| status:{label:'beta',cls:'beta'}, | |
| long:'NWO-ASM is the Anthropic-architecture-language assembler that turns abstract symbolic operations into typed dataflow programs (Process-Matrix IR, .pmx) and dispatches them across heterogeneous substrates — GPU, photonic, neuromorphic, quantum. CHAINSTATE\'s consensus is a perfect customer: a 64-head attention over 65,536 dims is a textbook PMX program. The ASM bridge takes the SymbolicAttention module, emits PMX, ships to the highest-rated available compute. For high-depth (>5 rounds) consensus, the bridge offloads to quantum substrates when available.', | |
| bullets:[ | |
| 'asm_compile_dispatch — symbolic ops to .pmx IR', | |
| 'PMX algebra over typed dataflow graphs', | |
| '8 substrate connectors: GPU, TPU, photonic, neuromorphic, IBM QC, Origin QC, BCI, robotic', | |
| 'High-depth consensus auto-routes to quantum when stake > 10K $STATE', | |
| 'Same NWO_API_KEY, same USDC billing, same Dilithium audit trail', | |
| ], | |
| eco:[ | |
| ['Consensus','high-depth rounds offload via ASM'], | |
| ['Quantum offload','IBM Sherbrooke / Origin Wukong / etc'], | |
| ['NWO Capital','shared gateway nwo-capital-api.onrender.com'], | |
| ], | |
| flow:'asm' }, | |
| { id:'f-neuro', num:'F-11', name:'NWO NEURO Bridge', | |
| blurb:'Live MSS conditioning. Operator focus / valence / arousal / load / intent flow into the query as additional context dimensions.', | |
| status:{label:'beta',cls:'beta'}, | |
| long:'When the caller is connected to a NEURO-paired EEG device, their live Mental State Signature (focus, valence, arousal, cognitive load, intent vector) is signed and travels with the cognitive transaction. The swarm conditions the symbolic state lookup on MSS — high load triggers explain-mode (more diagrams, simpler symbols); high focus enables deep math/science routing; high arousal weights the gamma/emoji subspaces; volatile intent triggers a focus-restore UI. Same NEURO Dilithium signature; same SHA3 identity commitment.', | |
| bullets:[ | |
| 'Live MSS conditioning of the 65,536-d embedding', | |
| 'Focus, valence, arousal, load, intent — 5 scalars + 4096-d residual', | |
| 'Dilithium-signed; binds to the transaction\'s sender', | |
| 'Cardio-Neuro identity commitment used as proof-of-personhood', | |
| 'Sovereignty Protocol gates which device class can dispatch (non-invasive only for full citizenship)', | |
| ], | |
| eco:[ | |
| ['NWO NEURO','EEG → MSS pipeline'], | |
| ['NWO Cardiac','ECG fingerprint for dual-biometric identity'], | |
| ['Cognitive Audit Trail','high-stress decisions trigger disjoint review'], | |
| ], | |
| flow:'neuro' }, | |
| { id:'f-quantum', num:'F-12', name:'Quantum Offload', | |
| blurb:'Optimisation, search, and simulation primitives in high-depth consensus rounds compile to quantum circuits via NWO-ASM.', | |
| status:{label:'design',cls:'design'}, | |
| long:'Three classes of symbolic operation get quantum advantage: (a) optimisation of the λ synergy parameter in log-pooling — quantum annealing on an Ising encoding; (b) search over reputation rankings — Grover\'s algorithm with reputation as the marked-state oracle; (c) symbolic path-integral simulation — Hamiltonian sim of the symbolic state evolution. Backends: IBM Sherbrooke (127 qubits, falcon r5) and Origin Quantum Wukong (72 qubits, superconducting). Falls back to classical when no QC available or stake < 10K $STATE.', | |
| bullets:[ | |
| 'Quantum annealing for λ synergy optimisation', | |
| 'Grover search over reputation rankings', | |
| 'Hamiltonian simulation for symbolic path integrals', | |
| 'IBM Sherbrooke + Origin Wukong + fallback classical', | |
| 'Stake-gated — 10,000 $STATE minimum for quantum routing', | |
| ], | |
| eco:[ | |
| ['NWO-ASM','compiles symbolic ops to quantum circuits'], | |
| ['Consensus','high-depth rounds use quantum when available'], | |
| ['Cryptography','Kyber-1024 KEM + Dilithium signing across QC links'], | |
| ], | |
| flow:'quantum' }, | |
| { id:'f-edge', num:'F-13', name:'Edge Dispatcher (Cloudflare Worker)', | |
| blurb:'Single-file Cloudflare Worker handling query dispatch, beacon protocol, consensus coordination, and result caching.', | |
| status:{label:'live',cls:'live'}, | |
| long:'A single-file Cloudflare Worker that fronts the entire chain. Routes: /query (POST a cognitive query, fan out to swarm, reach consensus, return result); /beacon (POST node registration, GET active node list); /consensus (GET current consensus state); /status (GET network health); /symbols (GET symbolic-register samples). KV namespaces: CHAINSTATE_NODES (live nodes), CHAINSTATE_CACHE (5-min result cache), CHAINSTATE_CONSENSUS (current state). Rate limit 60 req/min per IP. CORS open.', | |
| bullets:[ | |
| 'Single edge-worker.js file — deploys via wrangler in <5 s', | |
| 'KV: CHAINSTATE_NODES, CHAINSTATE_CACHE, CHAINSTATE_CONSENSUS', | |
| '5-minute result cache, 60 req/min/IP rate limit', | |
| 'Routes: /query, /beacon, /consensus, /status, /symbols', | |
| 'CORS open; usable from any HF Space frontend', | |
| ], | |
| eco:[ | |
| ['Swarm','dispatches per-query to active node endpoints'], | |
| ['Cache','keys are hashed query; results cached for 5 min'], | |
| ['SCAN','reads cache and node KV for live block/tx feed'], | |
| ], | |
| flow:'edge' }, | |
| { id:'f-beacon', num:'F-14', name:'Swarm Beacon Protocol', | |
| blurb:'Nodes register themselves and report status. The beacon maintains a live KV of {node_id, reputation, capabilities, endpoint, region}.', | |
| status:{label:'live',cls:'live'}, | |
| long:'On startup, every swarm node POSTs to /beacon with { node_id, reputation, capabilities, endpoint, dilithium_pubkey }. The Worker writes to CHAINSTATE_NODES KV with a 5-min TTL. Nodes ping every 60 s to refresh; stale entries auto-expire. GET /beacon returns the active node list sorted by reputation. Capabilities is a string list — "embedding", "attention", "quantum", "neuro_mss" — and dispatch only sends a query to nodes that report the required capability.', | |
| bullets:[ | |
| 'POST /beacon for registration + heartbeat', | |
| 'GET /beacon for active node list (reputation-sorted)', | |
| '5-minute TTL on inactivity → auto-deregister', | |
| 'Capability tags filter dispatch (e.g. quantum-only)', | |
| 'Region field tracks CF colo for latency-aware routing', | |
| ], | |
| eco:[ | |
| ['Edge dispatcher','reads beacon list to select dispatch targets'], | |
| ['Reputation','reputation field updated by consensus outcomes'], | |
| ['SCAN','beacon list visualised as live network map'], | |
| ], | |
| flow:'beacon' }, | |
| { id:'f-cache', num:'F-15', name:'Result Caching', | |
| blurb:'5-minute LRU cache on KV. Hashed query key. Cuts cost ~85% on repeated queries. Bypassable with cache:false flag.', | |
| status:{label:'live',cls:'live'}, | |
| long:'Identical queries hit a Cloudflare KV cache for 5 minutes. Key = SHA3-256(query). Value = full JSON response including consensus_state, participating_nodes, gas. Bypass with `cache: false` in the request body. Useful for deterministic queries (math, lookups) where multiple users benefit from one inference. For non-deterministic queries (creative writing, news) the caller should set cache:false; otherwise the cache wins 85% of the time and the chain settles much cheaper.', | |
| bullets:[ | |
| '5-minute TTL on Cloudflare KV', | |
| 'Key = SHA3-256(query); Value = full consensus response', | |
| 'Bypass with cache:false in the request body', | |
| '85% hit-rate on deterministic queries in testnet', | |
| 'Per-call USDC charge skipped on cache hit (just CF egress)', | |
| ], | |
| eco:[ | |
| ['Edge dispatcher','checks cache first; returns directly on hit'], | |
| ['Settlement','no USDC charge on cache hit'], | |
| ['SCAN','X-Cache: HIT/MISS header visible on every tx'], | |
| ], | |
| flow:'cache' }, | |
| { id:'f-market', num:'F-16', name:'DApp Marketplace', | |
| blurb:'Apps built on CHAINSTATE list on the marketplace. ERC-1155 listings, 15% perpetual creator royalty, same splitter as NWO-ASM.', | |
| status:{label:'design',cls:'design'}, | |
| long:'Anything built on the CHAINSTATE API can be listed: a calculator DApp that solves symbolic integrals via the swarm; a tarot reader that interprets ☉☽☿ over the occult subspace; a Mandarin tutor that uses the language subspace for adaptive grading. Each app mints as ERC-1155, originator commitment travels in metadata, 15% perpetual royalty under EIP-2981. Same splitter (`0x93a7…1BE4`) as NWO-ASM, METASTATE, NEURO, Cardiac. Cross-discovery surfaces via the NWO Marketplace.', | |
| bullets:[ | |
| 'ERC-1155 listing per DApp', | |
| '15% perpetual creator royalty (EIP-2981)', | |
| 'Originator commitment in token metadata', | |
| 'Shared splitter — `0x93a7962f75475b7e3Fbb62d3A23194f8833b1BE4`', | |
| 'Cross-discoverable across NWO Marketplace', | |
| ], | |
| eco:[ | |
| ['NWO Marketplace','primary discovery surface'], | |
| ['Affiliates','15% affiliate stacks with 15% creator royalty'], | |
| ['NWO-ASM','marketplace contracts reuse ASM L6 listing primitives'], | |
| ], | |
| flow:'market' }, | |
| ]; | |
| /* ============================================================ | |
| PAGE ORDER + ROUTING | |
| ============================================================ */ | |
| const PAGE_ORDER = [ | |
| {id:'home', label:'Home'}, | |
| {id:'explorer', label:'SCAN'}, | |
| {id:'query', label:'Query'}, | |
| {id:'terminal', label:'Terminal'}, | |
| {id:'symbols', label:'Symbols'}, | |
| ...FEATURES.map(f=>({id:f.id,label:f.name})), | |
| {id:'architecture', label:'Architecture'}, | |
| {id:'instructions', label:'Instructions'}, | |
| {id:'roadmap', label:'Roadmap'}, | |
| {id:'api', label:'API'}, | |
| {id:'rnd', label:'R&D'}, | |
| {id:'deployment', label:'Deploy'}, | |
| {id:'affiliates', label:'Affiliates'}, | |
| ]; | |
| function pageIndex(id){ const i = PAGE_ORDER.findIndex(p=>p.id===id); return i<0?0:i; } | |
| function goto(id, dir){ | |
| if(!id) id='home'; | |
| const next = document.querySelector('.page[data-page="'+id+'"]'); | |
| if(!next) return; | |
| const cur = document.querySelector('.page.active'); | |
| if(cur === next) return; | |
| let leftExit = 'exit-left'; | |
| if(dir === 'prev'){ | |
| leftExit = 'exit-right'; | |
| next.classList.add('enter-left'); | |
| requestAnimationFrame(()=>next.classList.remove('enter-left')); | |
| } | |
| if(cur){ | |
| cur.classList.remove('active'); | |
| cur.classList.add(leftExit); | |
| setTimeout(()=>cur.classList.remove(leftExit), 600); | |
| } | |
| next.classList.add('active'); | |
| document.querySelectorAll('.nav-item, .nav-dd a').forEach(a=>a.classList.remove('active')); | |
| document.querySelectorAll('[data-link="'+id+'"]').forEach(a=>a.classList.add('active')); | |
| // close any open dropdown after navigation | |
| document.querySelectorAll('.nav-group.open').forEach(g=>g.classList.remove('open')); | |
| document.getElementById('topbar').classList.remove('menu-open'); | |
| if(history && history.replaceState) history.replaceState(null, '', '#'+id); | |
| window.scrollTo({top:0, behavior:'auto'}); | |
| if(id === 'api'){ setTimeout(()=>{ if(typeof sizeCalls==='function') sizeCalls(); if(typeof refreshApiMode==='function') refreshApiMode(); }, 400); } | |
| } | |
| window.goto = goto; | |
| function gotoIndex(i){ | |
| i = Math.max(0, Math.min(PAGE_ORDER.length-1, i)); | |
| const cur = document.querySelector('.page.active'); | |
| const curId = cur ? cur.getAttribute('data-page') : 'home'; | |
| const curIdx = pageIndex(curId); | |
| const dir = i < curIdx ? 'prev' : 'next'; | |
| goto(PAGE_ORDER[i].id, dir); | |
| } | |
| function gotoNext(){ const cur = document.querySelector('.page.active'); const i = pageIndex(cur?cur.getAttribute('data-page'):'home'); gotoIndex(i+1); } | |
| function gotoPrev(){ const cur = document.querySelector('.page.active'); const i = pageIndex(cur?cur.getAttribute('data-page'):'home'); gotoIndex(i-1); } | |
| document.addEventListener('click', (e)=>{ | |
| const a = e.target.closest('[data-link]'); | |
| if(a){ | |
| e.preventDefault(); | |
| const id = a.getAttribute('data-link'); | |
| const cur = document.querySelector('.page.active'); | |
| const curId = cur ? cur.getAttribute('data-page') : 'home'; | |
| const dir = pageIndex(id) < pageIndex(curId) ? 'prev' : 'next'; | |
| goto(id, dir); | |
| } | |
| }); | |
| window.addEventListener('hashchange', ()=>{ goto((location.hash||'').replace('#','')); }); | |
| document.getElementById('burger').addEventListener('click', ()=>{ | |
| document.getElementById('topbar').classList.toggle('menu-open'); | |
| }); | |
| (function(){ | |
| // Both dropdowns: chevron toggles, label-with-data-link still navigates. | |
| // Opening one closes the other. | |
| function wireGroup(id){ | |
| const grp = document.getElementById(id); | |
| if(!grp) return; | |
| const chev = grp.querySelector('.nav-item .chev'); | |
| if(chev){ | |
| chev.addEventListener('click', (e)=>{ | |
| e.stopPropagation(); | |
| e.preventDefault(); | |
| const wasOpen = grp.classList.contains('open'); | |
| document.querySelectorAll('.nav-group.open').forEach(g=>g.classList.remove('open')); | |
| if(!wasOpen) grp.classList.add('open'); | |
| }); | |
| } | |
| // For groups whose .nav-item has no data-link (features), clicking | |
| // the whole label also toggles. For Home (which has data-link), only | |
| // the chevron toggles; the label navigates as expected. | |
| const labelLink = grp.querySelector('.nav-item'); | |
| if(labelLink && !labelLink.hasAttribute('data-link')){ | |
| labelLink.addEventListener('click', (e)=>{ | |
| e.stopPropagation(); | |
| const wasOpen = grp.classList.contains('open'); | |
| document.querySelectorAll('.nav-group.open').forEach(g=>g.classList.remove('open')); | |
| if(!wasOpen) grp.classList.add('open'); | |
| }); | |
| } | |
| grp.querySelectorAll('.nav-dd a').forEach(a=>{ | |
| a.addEventListener('click', ()=>{ setTimeout(()=>grp.classList.remove('open'), 50); }); | |
| }); | |
| } | |
| wireGroup('home-group'); | |
| wireGroup('features-group'); | |
| // Click anywhere outside a nav-group → close all dropdowns | |
| document.addEventListener('click', (e)=>{ | |
| if(!e.target.closest('.nav-group')){ | |
| document.querySelectorAll('.nav-group.open').forEach(g=>g.classList.remove('open')); | |
| } | |
| }); | |
| })(); | |
| let touchStartX=0, touchStartY=0, touchActive=false; | |
| document.addEventListener('touchstart', (e)=>{ | |
| if(!e.touches.length) return; | |
| touchStartX = e.touches[0].clientX; touchStartY = e.touches[0].clientY; touchActive = true; | |
| }, {passive:true}); | |
| document.addEventListener('touchend', (e)=>{ | |
| if(!touchActive) return; touchActive=false; | |
| const t = e.changedTouches[0]; if(!t) return; | |
| const dx = t.clientX - touchStartX; const dy = t.clientY - touchStartY; | |
| if(Math.abs(dx) > 70 && Math.abs(dx) > Math.abs(dy)*1.4){ | |
| const target = e.target; | |
| if(target && target.closest && target.closest('.modal-bg.open')) return; | |
| if(target && target.closest && target.closest('textarea')) return; | |
| if(dx < 0) gotoNext(); else gotoPrev(); | |
| } | |
| }, {passive:true}); | |
| document.addEventListener('keydown', (e)=>{ | |
| if(document.querySelector('.modal-bg.open')) return; | |
| if(e.target && e.target.matches && (e.target.matches('input,textarea'))) return; | |
| if(e.key==='ArrowRight'){ gotoNext(); } | |
| else if(e.key==='ArrowLeft'){ gotoPrev(); } | |
| else if(e.key==='Home'){ goto('home'); } | |
| }); | |
| /* ============================================================ | |
| BAND LEGEND on home page | |
| ============================================================ */ | |
| function renderBandLegend(){ | |
| const root = document.getElementById('band-legend'); | |
| if(!root) return; | |
| root.innerHTML = Object.entries(SUBSPACES).map(([k,s])=>` | |
| <div class="band-card" data-band="${k}" onclick="goto('symbols')"> | |
| <div class="band-card-name"> | |
| <span class="glyph" style="color:${s.col}">${s.glyph}</span> | |
| <span>${s.name}</span> | |
| <span class="rng">${s.dims}d</span> | |
| </div> | |
| <div class="band-card-samples">${s.samples.slice(0,8).join(' ')}</div> | |
| <div class="band-card-state">range ${s.range}</div> | |
| </div> | |
| `).join(''); | |
| } | |
| </script> | |
| <script> | |
| /* ============================================================ | |
| HERO CANVAS — blockchain data-flow visualisation | |
| Nodes = swarm members; pulses = transactions flowing; symbols rain | |
| between blocks. Hover a node to see its summary. | |
| ============================================================ */ | |
| const hero = document.getElementById('hero'); | |
| const heroCanvas = document.getElementById('hero-canvas'); | |
| const hctx = heroCanvas.getContext('2d'); | |
| let hw=0, hh=0; | |
| let dpr = Math.min(window.devicePixelRatio||1, 2); | |
| function sizeHero(){ | |
| dpr = Math.min(window.devicePixelRatio||1, 2); | |
| hw = hero.clientWidth; hh = hero.clientHeight; | |
| heroCanvas.width = hw*dpr; heroCanvas.height = hh*dpr; | |
| heroCanvas.style.width = hw+'px'; heroCanvas.style.height = hh+'px'; | |
| hctx.setTransform(dpr,0,0,dpr,0,0); | |
| } | |
| // ───────────────────────────────────────────────────────────────── | |
| // HERO — Infinity-symbol blockchain visualization | |
| // Lemniscate of Bernoulli: x = a·cos(t)/(1+sin²t), y = a·sin(t)·cos(t)/(1+sin²t) | |
| // Nodes sit at evenly-spaced t along the curve. Pulses ride t with | |
| // individual speeds. A shimmering phase-wave runs around the figure-8 | |
| // continuously. Behind it, symbols flicker like vacuum fluctuations. | |
| // ───────────────────────────────────────────────────────────────── | |
| let nodes=[], pulses=[], qFluct=[]; | |
| const HERO_SYMS = ['∫','∂','∇','∑','∏','ℏ','ℵ','α','β','γ','δ','θ','λ','π','σ','φ','ψ','ω','一','二','道','心','智','☉','☽','♂','♀','⚛','🧬','🔮','⛓','⚡','🧠','🔬','⇒','↺','⟳','∞','⊕','⊗','≈','∈','⊂','∀','∃']; | |
| const HERO_TINTS = [ | |
| {r:125,g:240,b:168}, // green · math | |
| {r:122,g:208,b:255}, // blue · science | |
| {r:240,g:224,b:125}, // yellow · language | |
| {r:164,g:140,b:255}, // purple · occult | |
| {r:255,g:140,b:184}, // pink · emoji | |
| {r:233,g:233,b:238}, // off-w · control | |
| ]; | |
| function tintRgba(t, a){ return `rgba(${t.r},${t.g},${t.b},${a})`; } | |
| const INF = { cx:0, cy:0, ax:0, ay:0, N_NODES:36, CURVE_RES:240, PULSE_COUNT:6 }; | |
| function infPoint(t){ | |
| const s = Math.sin(t), c = Math.cos(t); | |
| const d = 1 + s*s; | |
| return { x: INF.cx + INF.ax * c / d, y: INF.cy + INF.ay * s * c / d }; | |
| } | |
| function buildHero(){ | |
| // Center + scale of the figure-8. ax is horizontal extent (the two loops), | |
| // ay is vertical (the loop height). Aspect tweak so it doesn't get squashed | |
| // tall on narrow screens. | |
| INF.cx = hw / 2; | |
| INF.cy = hh / 2; | |
| INF.ax = Math.min(hw * 0.40, 520); | |
| INF.ay = Math.min(hh * 0.32, INF.ax * 0.50); | |
| nodes = []; | |
| pulses = []; | |
| qFluct = []; | |
| for(let i=0; i<INF.N_NODES; i++){ | |
| const t = (i / INF.N_NODES) * Math.PI * 2; | |
| const p = infPoint(t); | |
| nodes.push({ | |
| t, x:p.x, y:p.y, | |
| r: 2 + Math.random()*2.2, | |
| rep: 30 + Math.random()*70, | |
| tint: HERO_TINTS[Math.floor(Math.random()*HERO_TINTS.length)], | |
| kind: Math.random() < 0.18 ? 'quantum' : 'classical', | |
| lastFire: -Infinity, | |
| }); | |
| } | |
| // Six pulses, scattered around the curve, each with its own speed | |
| for(let i=0; i<INF.PULSE_COUNT; i++){ | |
| pulses.push({ | |
| t: (i / INF.PULSE_COUNT) * Math.PI * 2, | |
| speed: 0.55 + Math.random()*0.55, // rad/sec base | |
| sym: HERO_SYMS[Math.floor(Math.random()*HERO_SYMS.length)], | |
| tint: HERO_TINTS[Math.floor(Math.random()*HERO_TINTS.length)], | |
| trail: [], | |
| }); | |
| } | |
| } | |
| let mouseH = {x:0, y:0, active:false}; | |
| hero.addEventListener('mousemove', e=>{ | |
| const r = hero.getBoundingClientRect(); | |
| mouseH.x = e.clientX - r.left; mouseH.y = e.clientY - r.top; mouseH.active = true; | |
| }); | |
| hero.addEventListener('mouseleave', ()=>mouseH.active=false); | |
| let tH = 0, lastFrame = performance.now(), lastFluct = 0; | |
| function heroFrame(){ | |
| const now = performance.now(); | |
| const dt = Math.min(0.06, (now - lastFrame) / 1000); | |
| lastFrame = now; | |
| tH += dt; | |
| // ── background ────────────────────────────────────────────── | |
| hctx.clearRect(0, 0, hw, hh); | |
| const bg = hctx.createRadialGradient(INF.cx, INF.cy, 0, INF.cx, INF.cy, Math.max(hw, hh)); | |
| bg.addColorStop(0, '#05050d'); | |
| bg.addColorStop(0.45, '#020208'); | |
| bg.addColorStop(1, '#000000'); | |
| hctx.fillStyle = bg; hctx.fillRect(0, 0, hw, hh); | |
| // ── quantum-fluctuation background symbols ───────────────── | |
| // Pop in, hold briefly, fade out. Very low alpha. | |
| if(tH - lastFluct > 0.04){ | |
| lastFluct = tH; | |
| for(let k=0; k<2; k++){ | |
| qFluct.push({ | |
| x: Math.random()*hw, | |
| y: Math.random()*hh, | |
| sym: HERO_SYMS[Math.floor(Math.random()*HERO_SYMS.length)], | |
| tint:HERO_TINTS[Math.floor(Math.random()*HERO_TINTS.length)], | |
| t0: tH, | |
| life:0.4 + Math.random()*1.6, | |
| amp: 0.05 + Math.random()*0.09, | |
| size:10 + Math.random()*22, | |
| }); | |
| } | |
| } | |
| qFluct = qFluct.filter(q => { | |
| const age = tH - q.t0; | |
| if(age >= q.life) return false; | |
| const u = age / q.life; | |
| const a = q.amp * Math.sin(Math.PI * u); // bell-shaped | |
| hctx.fillStyle = tintRgba(q.tint, a); | |
| hctx.font = `${q.size|0}px IBM Plex Mono, monospace`; | |
| hctx.fillText(q.sym, q.x, q.y); | |
| return true; | |
| }); | |
| // ── the infinity curve with shimmering phase wave ─────────── | |
| // Multi-pass for glow. Phase advances over time so the bright band runs. | |
| const phase = tH * 1.2; | |
| const STEPS = INF.CURVE_RES; | |
| // 1) faint base ring | |
| hctx.beginPath(); | |
| for(let i=0; i<=STEPS; i++){ | |
| const t = (i / STEPS) * Math.PI * 2; | |
| const p = infPoint(t); | |
| if(i===0) hctx.moveTo(p.x, p.y); | |
| else hctx.lineTo(p.x, p.y); | |
| } | |
| hctx.strokeStyle = 'rgba(255,255,255,0.10)'; | |
| hctx.lineWidth = 1.2; | |
| hctx.stroke(); | |
| // 2) segments coloured by phase wave — small overlapping arcs | |
| for(let i=0; i<STEPS; i++){ | |
| const t = (i / STEPS) * Math.PI * 2; | |
| const tn = ((i+1) / STEPS) * Math.PI * 2; | |
| const p = infPoint(t), q = infPoint(tn); | |
| const a = 0.04 + 0.42 * Math.max(0, Math.sin(t * 2 - phase * 2)); | |
| hctx.beginPath(); | |
| hctx.moveTo(p.x, p.y); | |
| hctx.lineTo(q.x, q.y); | |
| hctx.strokeStyle = `rgba(255,255,255,${a})`; | |
| hctx.lineWidth = 1.4 + a*1.3; | |
| hctx.stroke(); | |
| } | |
| // 3) second offset wave for layered shimmer | |
| for(let i=0; i<STEPS; i++){ | |
| const t = (i / STEPS) * Math.PI * 2; | |
| const tn = ((i+1) / STEPS) * Math.PI * 2; | |
| const p = infPoint(t), q = infPoint(tn); | |
| const a = 0.05 * Math.max(0, Math.sin(t * 3 - phase * 1.7 + 1.2)); | |
| if(a < 0.005) continue; | |
| hctx.beginPath(); | |
| hctx.moveTo(p.x, p.y); hctx.lineTo(q.x, q.y); | |
| hctx.strokeStyle = `rgba(150,210,255,${a*1.5})`; | |
| hctx.lineWidth = 0.8; | |
| hctx.stroke(); | |
| } | |
| // ── pulses travelling along the curve ─────────────────────── | |
| for(const pl of pulses){ | |
| pl.t = (pl.t + pl.speed * dt) % (Math.PI * 2); | |
| const p = infPoint(pl.t); | |
| // Trail: keep last 14 positions | |
| pl.trail.push({x:p.x, y:p.y}); | |
| if(pl.trail.length > 14) pl.trail.shift(); | |
| // Fire any nodes whose t is within delta of pulse.t (wrap-aware) | |
| const D = 0.08; | |
| for(const n of nodes){ | |
| let diff = Math.abs(((pl.t - n.t + Math.PI) % (Math.PI*2)) - Math.PI); | |
| if(diff < D && tH - n.lastFire > 0.18){ | |
| n.lastFire = tH; | |
| } | |
| } | |
| // Draw trail | |
| for(let k=0; k<pl.trail.length; k++){ | |
| const tp = pl.trail[k]; | |
| const u = k / pl.trail.length; | |
| hctx.fillStyle = tintRgba(pl.tint, 0.45 * u); | |
| hctx.beginPath(); hctx.arc(tp.x, tp.y, 1.4, 0, Math.PI*2); hctx.fill(); | |
| } | |
| // Glow head | |
| const g = hctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, 18); | |
| g.addColorStop(0, tintRgba(pl.tint, 0.85)); | |
| g.addColorStop(0.4, tintRgba(pl.tint, 0.45)); | |
| g.addColorStop(1, tintRgba(pl.tint, 0)); | |
| hctx.fillStyle = g; | |
| hctx.beginPath(); hctx.arc(p.x, p.y, 18, 0, Math.PI*2); hctx.fill(); | |
| // Bright core | |
| hctx.fillStyle = tintRgba(pl.tint, 1); | |
| hctx.beginPath(); hctx.arc(p.x, p.y, 2.6, 0, Math.PI*2); hctx.fill(); | |
| // Riding symbol | |
| hctx.fillStyle = tintRgba(pl.tint, 0.92); | |
| hctx.font = 'bold 12px IBM Plex Mono, monospace'; | |
| hctx.fillText(pl.sym, p.x + 6, p.y - 6); | |
| } | |
| // ── nodes on the curve ────────────────────────────────────── | |
| for(let i=0; i<nodes.length; i++){ | |
| const n = nodes[i]; | |
| const dtFire = tH - n.lastFire; | |
| const flash = dtFire < 0.5 ? Math.pow(1 - dtFire/0.5, 1.4) : 0; | |
| if(flash > 0){ | |
| // outer glow on fire | |
| const fg = hctx.createRadialGradient(n.x, n.y, 0, n.x, n.y, 28 * flash + 6); | |
| fg.addColorStop(0, tintRgba(n.tint, 0.7 * flash)); | |
| fg.addColorStop(0.6, tintRgba(n.tint, 0.25 * flash)); | |
| fg.addColorStop(1, tintRgba(n.tint, 0)); | |
| hctx.fillStyle = fg; | |
| hctx.beginPath(); hctx.arc(n.x, n.y, 28 * flash + 6, 0, Math.PI*2); hctx.fill(); | |
| } | |
| // hover glow | |
| if(mouseH.active){ | |
| const md = Math.hypot(mouseH.x - n.x, mouseH.y - n.y); | |
| if(md < 110){ | |
| const a = (1 - md/110) * 0.45; | |
| const mg = hctx.createRadialGradient(n.x, n.y, 0, n.x, n.y, 16); | |
| mg.addColorStop(0, `rgba(255,255,255,${a})`); | |
| mg.addColorStop(1, 'rgba(255,255,255,0)'); | |
| hctx.fillStyle = mg; | |
| hctx.beginPath(); hctx.arc(n.x, n.y, 16, 0, Math.PI*2); hctx.fill(); | |
| } | |
| if(md < 22){ | |
| const label = `node-${i.toString().padStart(3,'0')} · rep ${n.rep.toFixed(1)} · ${n.kind}`; | |
| hctx.font = '10px IBM Plex Mono, monospace'; | |
| const tw = hctx.measureText(label).width + 12; | |
| hctx.fillStyle = 'rgba(0,0,0,0.85)'; | |
| hctx.fillRect(n.x + 12, n.y - 26, tw, 18); | |
| hctx.fillStyle = '#fff'; | |
| hctx.fillText(label, n.x + 18, n.y - 13); | |
| } | |
| } | |
| // The node itself | |
| const baseA = 0.55 + flash * 0.45; | |
| const r = n.r + flash * 1.8; | |
| if(n.kind === 'quantum'){ | |
| hctx.fillStyle = `rgba(164,140,255,${baseA})`; | |
| } else { | |
| hctx.fillStyle = `rgba(255,255,255,${baseA})`; | |
| } | |
| hctx.beginPath(); hctx.arc(n.x, n.y, r, 0, Math.PI*2); hctx.fill(); | |
| } | |
| // ── center crossing point — a focal node at (cx, cy) ──────── | |
| // The figure-8 crosses itself at the center; mark it. | |
| const cphase = (Math.sin(tH * 2.1) + 1) * 0.5; | |
| const cgrad = hctx.createRadialGradient(INF.cx, INF.cy, 0, INF.cx, INF.cy, 12 + cphase * 4); | |
| cgrad.addColorStop(0, `rgba(255,255,255,${0.35 + cphase*0.30})`); | |
| cgrad.addColorStop(0.6, 'rgba(255,255,255,0.08)'); | |
| cgrad.addColorStop(1, 'rgba(255,255,255,0)'); | |
| hctx.fillStyle = cgrad; | |
| hctx.beginPath(); hctx.arc(INF.cx, INF.cy, 12 + cphase * 4, 0, Math.PI*2); hctx.fill(); | |
| hctx.fillStyle = 'rgba(255,255,255,0.9)'; | |
| hctx.beginPath(); hctx.arc(INF.cx, INF.cy, 1.6, 0, Math.PI*2); hctx.fill(); | |
| requestAnimationFrame(heroFrame); | |
| } | |
| window.addEventListener('resize', ()=>{ sizeHero(); buildHero(); }); | |
| /* ============================================================ | |
| CHAINSTATE SCAN — block explorer page | |
| ============================================================ */ | |
| let blocks = [], txs = []; | |
| function seedScan(){ | |
| blocks = []; txs = []; | |
| const now = Math.floor(Date.now()/1000); | |
| for(let i=0;i<50;i++){ | |
| const h = now - i*2; | |
| blocks.push({ | |
| height: 12480 - i, | |
| hash: '0x'+Math.random().toString(16).slice(2,10)+Math.random().toString(16).slice(2,10), | |
| proposer: 'node-'+Math.floor(Math.random()*40).toString().padStart(3,'0'), | |
| txn_count: Math.floor(Math.random()*50)+4, | |
| gas_used: (Math.random()*2.4+0.3).toFixed(4), | |
| time: h, | |
| }); | |
| } | |
| for(let i=0;i<60;i++){ | |
| const t = now - i*1; | |
| const SYMS_EX = ['∫∂x/∂t', '☉☽☿ in alchemy', 'F=ma', '🧬→protein', '一二三四五', 'Σ(1/n²)', '∇×B=μ₀J', '♂♀ Mars Venus', '⚛ ⇒ E=mc²', 'tr(ρ²)', 'π × e × i', 'Δψ in QM', '☥☦☪ unity', 'arg max f(x)', '🔮⇒🌐']; | |
| txs.push({ | |
| hash: '0x'+Math.random().toString(16).slice(2,10)+Math.random().toString(16).slice(2,10), | |
| from: '0x'+Math.random().toString(16).slice(2,10), | |
| query: SYMS_EX[Math.floor(Math.random()*SYMS_EX.length)], | |
| gas: (Math.random()*0.015+0.001).toFixed(5), | |
| confidence: (0.7+Math.random()*0.29).toFixed(3), | |
| time: t, | |
| }); | |
| } | |
| } | |
| function relTime(ts){ | |
| const d = Math.floor(Date.now()/1000) - ts; | |
| if(d<60) return d+'s ago'; | |
| if(d<3600) return Math.floor(d/60)+'m ago'; | |
| if(d<86400) return Math.floor(d/3600)+'h ago'; | |
| return Math.floor(d/86400)+'d ago'; | |
| } | |
| function renderExplorer(){ | |
| const root = document.querySelector('.page[data-page="explorer"]'); | |
| if(!root) return; | |
| if(!blocks.length) seedScan(); | |
| root.innerHTML = ` | |
| <div class="subhero"> | |
| <div class="eyebrow">module · CHAINSTATE SCAN</div> | |
| <h1>SCAN · Block Explorer</h1> | |
| <p class="lede">Live feed of the symbolic-weight chain. Each block is a batch of cognitive transactions; each transaction is a query resolved by the swarm. Click any block or tx for the full receipt — consensus state vector, participating nodes, confidence distribution, gas breakdown.</p> | |
| <div class="meta-row"> | |
| <span class="pill live"><span class="dot"></span>Base mainnet · 8453</span> | |
| <span class="pill live"><span class="dot"></span>2 s block time</span> | |
| <span class="pill beta"><span class="dot"></span>SCAN beta</span> | |
| ${csModeToggle()} | |
| </div> | |
| </div> | |
| <div class="wrap"> | |
| <section class="tight"> | |
| <div class="scan-stat-grid"> | |
| <div class="scan-stat"><div class="v" id="ss-height">${blocks[0].height.toLocaleString()}</div><div class="l">block height</div></div> | |
| <div class="scan-stat"><div class="v" id="ss-tps">${(Math.random()*8+22).toFixed(1)}</div><div class="l">tx / s</div></div> | |
| <div class="scan-stat"><div class="v" id="ss-nodes">42</div><div class="l">active nodes</div></div> | |
| <div class="scan-stat"><div class="v" id="ss-gas">${(Math.random()*0.5+0.8).toFixed(3)}</div><div class="l">avg gas · $STATE</div></div> | |
| </div> | |
| </section> | |
| <section class="bare"> | |
| <div class="scan-card shim"> | |
| <div class="scan-search"> | |
| <input id="scan-search" type="text" placeholder="🔍 Search by block height, tx hash, sender address, or query text…"> | |
| <button class="ghost sm" onclick="doScanSearch()">Search</button> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="tight"> | |
| <div class="scan-grid"> | |
| <div class="scan-card shim"> | |
| <div class="scan-card-head"> | |
| <h3>Latest blocks</h3> | |
| <span class="meta">live · 2 s tick</span> | |
| </div> | |
| <div class="scan-list" id="scan-blocks"> | |
| ${blocks.slice(0,15).map((b,i)=>` | |
| <div class="scan-row" onclick="openBlock(${b.height})"> | |
| <div class="ico bk">BK</div> | |
| <div> | |
| <div class="hash">#${b.height} · ${b.hash}</div> | |
| <div class="sub">proposed by ${b.proposer} · ${b.txn_count} txs · ${relTime(b.time)}</div> | |
| </div> | |
| <div class="v">${b.gas_used} <span class="l">$STATE</span></div> | |
| </div> | |
| `).join('')} | |
| </div> | |
| </div> | |
| <div class="scan-card shim"> | |
| <div class="scan-card-head"> | |
| <h3>Latest transactions</h3> | |
| <span class="meta">cognitive queries</span> | |
| </div> | |
| <div class="scan-list" id="scan-txs"> | |
| ${txs.slice(0,15).map(t=>` | |
| <div class="scan-row" onclick="openTx('${t.hash}')"> | |
| <div class="ico tx">TX</div> | |
| <div> | |
| <div class="hash">${t.hash} · ${t.query}</div> | |
| <div class="sub">from ${t.from} · conf ${t.confidence} · ${relTime(t.time)}</div> | |
| </div> | |
| <div class="v">${t.gas} <span class="l">$STATE</span></div> | |
| </div> | |
| `).join('')} | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="tight"> | |
| <div class="two-col"> | |
| <div class="col-card shim"> | |
| <h3>What you're looking at</h3> | |
| <p>Every transaction on CHAINSTATE is a cognitive query. The chain doesn't store fungible-token transfers as primitive — those are <em>special-case queries</em> like <code>transfer(0xabc, 100)</code> that the swarm resolves and the consensus layer settles. The receipt for every transaction includes:</p> | |
| <ul> | |
| <li><strong>Consensus state</strong> — the 65,536-d symbolic vector the swarm agreed on</li> | |
| <li><strong>Participating nodes</strong> — list of node_ids with their per-node confidence</li> | |
| <li><strong>Consensus depth</strong> — how many log-pooling rounds it took to converge</li> | |
| <li><strong>Gas breakdown</strong> — base + (n_nodes × coord) + (depth × verify) + (ms × compute)</li> | |
| <li><strong>Dilithium signature</strong> — from the proposer, over the full block</li> | |
| <li><strong>X-Cache</strong> — HIT means served from 5-min KV cache, no fresh inference</li> | |
| </ul> | |
| </div> | |
| <div class="col-card shim"> | |
| <h3>Wallet-bound SCAN</h3> | |
| <p>Connect a wallet via the top-right button to filter SCAN to your account: transactions you sent, queries you cached, nodes you stake on, blocks you proposed. The same wallet works across all NWO Capital services — CHAINSTATE here, NWO-ASM, NEURO, Cardiac, METASTATE.</p> | |
| <p>For dev usage, point your client at <code>https://chainstate-worker.<your-cf>.workers.dev</code> after deploying the edge worker. See the <span class="txt-mono" style="cursor:pointer;color:var(--math)" onclick="goto('deployment')">Deploy</span> page for the one-file deploy.</p> | |
| <div class="cta-row"> | |
| <button class="ghost" onclick="goto('query')">Run a query</button> | |
| <button class="ghost" onclick="goto('deployment')">Deploy your edge</button> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </div>`; | |
| // demo ticker — runs in both modes so the page is never blank (no real chain producing blocks yet) | |
| if(window.__scanTimer) clearInterval(window.__scanTimer); | |
| window.__scanTimer = setInterval(()=>{ | |
| const now = Math.floor(Date.now()/1000); | |
| blocks.unshift({ | |
| height: blocks[0].height+1, | |
| hash: '0x'+Math.random().toString(16).slice(2,10)+Math.random().toString(16).slice(2,10), | |
| proposer: 'node-'+Math.floor(Math.random()*40).toString().padStart(3,'0'), | |
| txn_count: Math.floor(Math.random()*50)+4, | |
| gas_used: (Math.random()*2.4+0.3).toFixed(4), | |
| time: now, | |
| }); | |
| if(blocks.length>200) blocks.pop(); | |
| const el = document.getElementById('scan-blocks'); | |
| const heightEl = document.getElementById('ss-height'); | |
| if(el){ | |
| el.innerHTML = blocks.slice(0,15).map(b=>` | |
| <div class="scan-row" onclick="openBlock(${b.height})"> | |
| <div class="ico bk">BK</div> | |
| <div> | |
| <div class="hash">#${b.height} · ${b.hash}</div> | |
| <div class="sub">proposed by ${b.proposer} · ${b.txn_count} txs · ${relTime(b.time)}</div> | |
| </div> | |
| <div class="v">${b.gas_used} <span class="l">$STATE</span></div> | |
| </div>`).join(''); | |
| } | |
| // In DEMO mode the height tile follows the seeded chain. In LIVE mode it | |
| // gets overwritten by the live /status fetcher below. | |
| if(heightEl && (typeof csIsLive !== 'function' || !csIsLive())) { | |
| heightEl.textContent = blocks[0].height.toLocaleString(); | |
| } | |
| }, 2200); | |
| // live KPI fetcher — only runs when mode is LIVE and a worker URL is set | |
| if(window.__scanLiveTimer) clearInterval(window.__scanLiveTimer); | |
| const liveFetch = ()=>{ | |
| if(typeof csIsLive !== 'function' || !csIsLive()) return; | |
| const w = window.__CHAINSTATE_WORKER; | |
| if(!w) return; | |
| fetch(w+'/status').then(r=>r.json()).then(s=>{ | |
| const h = document.getElementById('ss-height'); | |
| const t = document.getElementById('ss-tps'); | |
| const n = document.getElementById('ss-nodes'); | |
| const g = document.getElementById('ss-gas'); | |
| if(h && s.height != null) h.textContent = Number(s.height).toLocaleString(); | |
| else if(h) h.textContent = '—'; | |
| if(t) t.textContent = (s.tps != null) ? Number(s.tps).toFixed(1) : '—'; | |
| if(n) n.textContent = (s.nodes_known != null) ? s.nodes_known : '—'; | |
| if(g) g.textContent = (s.avg_gas != null) ? Number(s.avg_gas).toFixed(3) : '—'; | |
| }).catch(()=>{ | |
| ['ss-height','ss-tps','ss-nodes','ss-gas'].forEach(id=>{ | |
| const e = document.getElementById(id); if(e) e.textContent = '—'; | |
| }); | |
| }); | |
| }; | |
| liveFetch(); | |
| window.__scanLiveTimer = setInterval(liveFetch, 4000); | |
| } | |
| function openBlock(h){ | |
| const b = blocks.find(x=>x.height===h); | |
| if(!b) return; | |
| openModal('Block #'+h, ` | |
| <p><strong>Hash:</strong> <code>${b.hash}</code></p> | |
| <p><strong>Proposer:</strong> ${b.proposer}</p> | |
| <p><strong>Time:</strong> ${new Date(b.time*1000).toISOString()} (${relTime(b.time)})</p> | |
| <p><strong>Transactions:</strong> ${b.txn_count}</p> | |
| <p><strong>Gas used:</strong> ${b.gas_used} $STATE</p> | |
| <h4>Consensus root</h4> | |
| <pre class="code">${Array.from({length:8},()=>Math.random().toString(16).slice(2,10)).join(' ')} | |
| ${Array.from({length:8},()=>Math.random().toString(16).slice(2,10)).join(' ')} | |
| ${Array.from({length:8},()=>Math.random().toString(16).slice(2,10)).join(' ')} | |
| ${Array.from({length:8},()=>Math.random().toString(16).slice(2,10)).join(' ')}</pre> | |
| <h4>Block signature (Dilithium FIPS 204)</h4> | |
| <pre class="code">${b.hash.slice(2)}...${'fa9e3c'.repeat(4)}</pre> | |
| <div style="margin-top:14px"><button class="ghost" onclick="closeModal()">Close</button></div>`); | |
| } | |
| function openTx(h){ | |
| const t = txs.find(x=>x.hash===h); | |
| if(!t) return; | |
| openModal('Transaction', ` | |
| <p><strong>Hash:</strong> <code>${t.hash}</code></p> | |
| <p><strong>From:</strong> <code>${t.from}</code></p> | |
| <p><strong>Query:</strong> <code>${t.query}</code></p> | |
| <p><strong>Confidence:</strong> ${t.confidence}</p> | |
| <p><strong>Gas paid:</strong> ${t.gas} $STATE</p> | |
| <p><strong>Time:</strong> ${new Date(t.time*1000).toISOString()} (${relTime(t.time)})</p> | |
| <h4>Participating nodes (top 5 by reputation)</h4> | |
| <pre class="code">node-${Math.floor(Math.random()*40).toString().padStart(3,'0')} rep 87.3 conf 0.921 | |
| node-${Math.floor(Math.random()*40).toString().padStart(3,'0')} rep 82.1 conf 0.918 | |
| node-${Math.floor(Math.random()*40).toString().padStart(3,'0')} rep 78.5 conf 0.903 | |
| node-${Math.floor(Math.random()*40).toString().padStart(3,'0')} rep 74.2 conf 0.881 | |
| node-${Math.floor(Math.random()*40).toString().padStart(3,'0')} rep 70.9 conf 0.872</pre> | |
| <h4>Consensus depth</h4> | |
| <p>${Math.floor(Math.random()*4)+3} rounds · converged at 0.95 cosine</p> | |
| <div style="margin-top:14px"><button class="ghost" onclick="closeModal()">Close</button></div>`); | |
| } | |
| function doScanSearch(){ | |
| const q = (document.getElementById('scan-search').value||'').trim(); | |
| if(!q){ return; } | |
| if(/^#?\d+$/.test(q)){ | |
| const h = parseInt(q.replace('#',''),10); | |
| if(blocks.find(b=>b.height===h)) openBlock(h); | |
| else openModal('Not found', '<p>No block at height '+h+' in the local sample.</p>'); | |
| return; | |
| } | |
| if(/^0x[a-f0-9]/.test(q)){ | |
| const tx = txs.find(t=>t.hash.startsWith(q)); | |
| if(tx) openTx(tx.hash); | |
| else openModal('Not found', '<p>No tx matching <code>'+q+'</code> in the local sample.</p>'); | |
| return; | |
| } | |
| // query-text match | |
| const tx = txs.find(t=>t.query.toLowerCase().includes(q.toLowerCase())); | |
| if(tx) openTx(tx.hash); | |
| else openModal('No match', '<p>No tx matching <code>'+q+'</code>.</p>'); | |
| } | |
| window.openBlock = openBlock; window.openTx = openTx; window.doScanSearch = doScanSearch; | |
| </script> | |
| <script> | |
| </script> | |
| <script> | |
| </script> | |
| <script> | |
| </script> | |
| <script> | |
| </script> | |
| <script> | |
| /* ============================================================ | |
| MODAL · PDF · WALLET · INIT | |
| ============================================================ */ | |
| function openModal(title, html){ | |
| document.getElementById('modal-title').textContent = title || '—'; | |
| document.getElementById('modal-body').innerHTML = html || ''; | |
| document.getElementById('modal-bg').classList.add('open'); | |
| } | |
| function closeModal(){ document.getElementById('modal-bg').classList.remove('open'); } | |
| window.openModal=openModal; window.closeModal=closeModal; | |
| document.getElementById('modal-x').addEventListener('click', closeModal); | |
| document.getElementById('modal-bg').addEventListener('click', (e)=>{ if(e.target.id==='modal-bg') closeModal(); }); | |
| function openPdf(url, title){ | |
| document.getElementById('pdf-title').textContent = title || 'PDF'; | |
| document.getElementById('pdf-frame').src = url; | |
| document.getElementById('pdf-open-tab').href = url; | |
| document.getElementById('pdf-modal-bg').classList.add('open'); | |
| } | |
| function closePdf(){ document.getElementById('pdf-modal-bg').classList.remove('open'); document.getElementById('pdf-frame').src='about:blank'; } | |
| window.openPdf=openPdf; window.closePdf=closePdf; | |
| document.getElementById('pdf-modal-x').addEventListener('click', closePdf); | |
| document.getElementById('pdf-modal-bg').addEventListener('click', (e)=>{ if(e.target.id==='pdf-modal-bg') closePdf(); }); | |
| document.addEventListener('keydown', (e)=>{ | |
| if(e.key==='Escape'){ closeModal(); closePdf(); } | |
| }); | |
| /* ============== WALLET ============== */ | |
| function shortAddr(a){ return a ? a.slice(0,6)+'…'+a.slice(-4) : ''; } | |
| function updateWalletUI(){ | |
| const btn = document.getElementById('wallet-btn'); | |
| if(!btn) return; | |
| const dot = btn.querySelector('span'); | |
| const addr = btn.querySelector('.addr'); | |
| if(window.__WALLET){ | |
| if(dot) dot.style.background = 'var(--live)'; | |
| if(addr) addr.textContent = shortAddr(window.__WALLET); | |
| } else { | |
| if(dot) dot.style.background = 'var(--w3)'; | |
| if(addr) addr.textContent = 'Connect Wallet'; | |
| } | |
| updateAffiliate(); | |
| if(typeof updateAffiliatePanel === 'function') updateAffiliatePanel(); | |
| } | |
| async function connectWallet(){ | |
| if(!window.ethereum){ alert('No EVM wallet detected. Install MetaScasask / Rabby / Coinbase Wallet.'); return; } | |
| try{ | |
| const accs = await window.ethereum.request({ method:'eth_requestAccounts' }); | |
| if(!accs || !accs.length) return; | |
| window.__WALLET = accs[0]; | |
| // request Base mainnet | |
| try{ | |
| await window.ethereum.request({ method:'wallet_switchEthereumChain', params:[{chainId:'0x2105'}] }); | |
| } catch(switchErr){ | |
| if(switchErr.code === 4902){ | |
| await window.ethereum.request({ method:'wallet_addEthereumChain', params:[{ | |
| chainId:'0x2105', chainName:'Base', nativeCurrency:{name:'ETH',symbol:'ETH',decimals:18}, | |
| rpcUrls:['https://mainnet.base.org'], blockExplorerUrls:['https://basescan.org'] | |
| }]}); | |
| } | |
| } | |
| updateWalletUI(); | |
| refreshApiMode(); | |
| } catch(e){ console.error(e); } | |
| } | |
| document.getElementById('wallet-btn').addEventListener('click', connectWallet); | |
| window.connectWallet = connectWallet; | |
| if(window.ethereum){ | |
| window.ethereum.request({ method:'eth_accounts' }).then(accs=>{ | |
| if(accs && accs.length){ window.__WALLET = accs[0]; updateWalletUI(); } | |
| }).catch(()=>{}); | |
| window.ethereum.on && window.ethereum.on('accountsChanged', (accs)=>{ | |
| window.__WALLET = accs && accs[0] ? accs[0] : null; | |
| updateWalletUI(); refreshApiMode(); | |
| }); | |
| } | |
| /* ============== FOOTER CAP TOGGLE ============== */ | |
| document.getElementById('cap-toggle').addEventListener('click', ()=>{ | |
| document.getElementById('cap-toggle').classList.toggle('open'); | |
| document.getElementById('cap-menu').classList.toggle('open'); | |
| }); | |
| /* ============== INIT ============== */ | |
| function init(){ | |
| renderBandLegend(); | |
| sizeHero(); buildHero(); requestAnimationFrame(heroFrame); | |
| renderExplorer(); | |
| renderQuery(); | |
| renderTerminal(); | |
| renderSymbols(); | |
| renderFeaturePages(); | |
| renderArchitecture(); | |
| renderInstructions(); | |
| renderRoadmap(); | |
| renderAPI(); | |
| renderRnD(); | |
| renderDeployment(); | |
| renderAffiliates(); | |
| updateWalletUI(); | |
| // Apply referrer from query string into UI | |
| const m = location.search.match(/[?&]ref=([^&]+)/); | |
| if(m){ window.__REF = decodeURIComponent(m[1]); } | |
| // Honor initial hash | |
| const h = (location.hash||'').replace('#',''); | |
| if(h) goto(h); | |
| // ── Mode-toggle: instant refresh on flip ── | |
| // The toggle buttons exist inside multiple pages; when state changes, | |
| // re-render the affected pages so the new mode's data appears immediately. | |
| document.addEventListener('cs:modechange', ()=>{ | |
| // SCAN — fastest visible feedback: re-run the live KPI fetcher / clear tiles | |
| if(typeof renderExplorer === 'function') { | |
| try { renderExplorer(); } catch(e){} | |
| } | |
| // API affiliate panel — re-fetch /affiliate or swap to demo immediately | |
| if(typeof updateAffiliatePanel === 'function') { | |
| try { updateAffiliatePanel(); } catch(e){} | |
| } | |
| // The API ticker self-replicates and checks the mode on each tick — no | |
| // explicit re-render needed; the next tick (within ~1.5 s) picks up the | |
| // new mode. Query checks the mode on submit. Terminal commands check | |
| // the mode at execution time. | |
| }); | |
| } | |
| if(document.readyState === 'loading'){ document.addEventListener('DOMContentLoaded', init); } | |
| else init(); | |
| </script> | |
| </body> | |
| </html> | |