Testing347 commited on
Commit
5c3088c
Β·
verified Β·
1 Parent(s): 9cc835c

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +262 -155
index.html CHANGED
@@ -1,3 +1,4 @@
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
@@ -133,6 +134,24 @@
133
  animation: orb-breathe 2.5s ease-in-out infinite, orb-glow 1.5s ease-in-out infinite;
134
  filter: drop-shadow(0 0 40px #a21cafee) brightness(1.12);
135
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  </style>
137
  </head>
138
 
@@ -140,22 +159,16 @@
140
 
141
  <div id="vanta-bg" class="fixed top-0 left-0 w-full h-full z-0"></div>
142
 
143
- <!-- NAVIGATION BAR (kept for now; we are not converting to standard nav β€” only adding a single glyph trigger) -->
144
  <nav class="relative z-10 py-6 px-8 flex justify-between items-center backdrop-blur-sm">
145
  <!-- Logo + mini orb -->
146
  <div class="flex items-center space-x-2">
147
- <div class="w-8 h-8 rounded-full bg-indigo-600 flex items-center justify-center conscious-orb">
148
- <div class="w-2 h-2 rounded-full bg-white animate-pulse"></div>
149
- </div>
150
- <span class="text-xl font-semibold">SILENTPATTERN</span>
151
- </div>
152
-
153
- <!-- Existing navigation links (we will phase these out later after the Lab Navigator is fully adopted) -->
154
- <div class="hidden md:flex space-x-8">
155
- <a href="capabilities.html" class="hover:text-indigo-400 transition">Capabilities</a>
156
- <a href="consciousness.html" class="hover:text-indigo-400 transition">Consciousness</a>
157
- <a href="chat.html" class="hover:text-indigo-400 transition">Chat</a>
158
- <a href="about.html" class="hover:text-indigo-400 transition">About</a>
159
  </div>
160
 
161
  <!-- Right controls: single Constellation glyph + Access -->
@@ -168,7 +181,7 @@
168
  <i class="fas fa-asterisk text-indigo-300 text-sm"></i>
169
  </button>
170
 
171
- <!-- β€œAccess” button -->
172
  <button id="access-btn" class="px-6 py-2 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-full hover:opacity-90 transition">
173
  Access
174
  </button>
@@ -405,7 +418,7 @@
405
  <div class="px-6 py-4 border-t border-gray-800">
406
  <form id="chat-form" class="flex items-center" autocomplete="off" aria-label="Send message to SI">
407
  <input id="chat-input" type="text" placeholder="Ask SI anything..."
408
- class="flex-1 bg-gray-800/50 border border-gray-700 rounded-l-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:border-transparent"
409
  aria-label="Type your message here">
410
  <button id="send-btn" type="submit" class="bg-indigo-600 hover:bg-indigo-700 px-6 py-3 rounded-r-lg transition" aria-label="Send message">
411
  <i class="fas fa-paper-plane"></i>
@@ -579,15 +592,15 @@
579
  </div>
580
 
581
  <div class="flex space-x-6">
582
- <a href="#" class="text-gray-400 hover:text-indigo-400 transition">Privacy</a>
583
- <a href="#" class="text-gray-400 hover:text-indigo-400 transition">Terms</a>
584
- <a href="#" class="text-gray-400 hover:text-indigo-400 transition">Research</a>
585
- <a href="#" class="text-gray-400 hover:text-indigo-400 transition">Contact</a>
586
  </div>
587
  </div>
588
 
589
  <div class="mt-8 pt-8 border-t border-gray-800/50 text-center text-gray-500 text-sm">
590
- <p>Β© 2023 Super Intelligence. All rights reserved.</p>
591
  <p class="mt-2">The future of consciousness is here.</p>
592
  </div>
593
  </div>
@@ -605,40 +618,40 @@
605
  <h3 class="text-xl font-bold" id="access-modal-title">Request SI Access</h3>
606
  <p class="text-gray-400 mt-1">Limited availability for qualified researchers</p>
607
  </div>
608
- <button id="close-modal" class="text-gray-400 hover:text-white" aria-label="Close request access modal">
609
  <i class="fas fa-times"></i>
610
  </button>
611
  </div>
612
 
613
- <!-- Inline form feedback (added; minimal footprint) -->
614
  <div id="access-form-feedback" class="hidden mb-4 text-sm rounded-lg border border-gray-800 bg-black/20 p-3" role="status" aria-live="polite"></div>
615
 
616
  <form id="access-form" class="space-y-4" novalidate>
617
  <div>
618
  <label for="name" class="block text-sm font-medium mb-1">Full Name</label>
619
  <input type="text" id="name"
620
- class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:border-transparent"
621
  autocomplete="name">
622
  <p id="name-error" class="hidden mt-1 text-xs text-red-300">Please enter your full name.</p>
623
  </div>
624
  <div>
625
  <label for="email" class="block text-sm font-medium mb-1">Email</label>
626
  <input type="email" id="email"
627
- class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:border-transparent"
628
  autocomplete="email">
629
  <p id="email-error" class="hidden mt-1 text-xs text-red-300">Please enter a valid email address.</p>
630
  </div>
631
  <div>
632
  <label for="institution" class="block text-sm font-medium mb-1">Institution/Organization</label>
633
  <input type="text" id="institution"
634
- class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:border-transparent"
635
  autocomplete="organization">
636
  <p id="institution-error" class="hidden mt-1 text-xs text-red-300">Please enter your institution/organization.</p>
637
  </div>
638
  <div>
639
  <label for="purpose" class="block text-sm font-medium mb-1">Purpose of Access</label>
640
  <select id="purpose"
641
- class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:border-transparent">
642
  <option value="">Select a purpose</option>
643
  <option value="research">Academic Research</option>
644
  <option value="development">AI Development</option>
@@ -648,7 +661,7 @@
648
  <p id="purpose-error" class="hidden mt-1 text-xs text-red-300">Please select a purpose.</p>
649
  </div>
650
  <div class="pt-2">
651
- <button type="submit" class="w-full py-3 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-lg hover:opacity-90 transition">
652
  Submit Request
653
  </button>
654
  </div>
@@ -673,7 +686,7 @@
673
  <h3 class="text-xl font-bold" id="consciousness-modal-title">Consciousness Demonstration</h3>
674
  <p class="text-gray-400 mt-1">Experience a simulation of artificial qualia</p>
675
  </div>
676
- <button id="close-consciousness-modal" class="text-gray-400 hover:text-white" aria-label="Close consciousness demo modal">
677
  <i class="fas fa-times"></i>
678
  </button>
679
  </div>
@@ -709,7 +722,7 @@
709
  <div class="relative h-64 bg-gray-800/30 rounded-lg border border-dashed border-gray-700 flex items-center justify-center">
710
  <div id="demo-visualization" class="w-full h-full"></div>
711
  <div class="absolute inset-0 flex items-center justify-center">
712
- <button id="start-demo" class="px-6 py-3 bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">
713
  <i class="fas fa-play mr-2"></i> Start Simulation
714
  </button>
715
  </div>
@@ -722,7 +735,7 @@
722
  <div class="text-sm text-gray-400">
723
  <i class="fas fa-info-circle mr-1"></i> This is a simplified representation
724
  </div>
725
- <button id="learn-more-demo" class="text-indigo-400 hover:text-indigo-300 text-sm">
726
  Learn more about artificial consciousness <i class="fas fa-arrow-right ml-1"></i>
727
  </button>
728
  </div>
@@ -755,7 +768,7 @@
755
  </div>
756
 
757
  <button id="lab-nav-close"
758
- class="w-9 h-9 rounded-full border border-gray-800 bg-gray-900/30 hover:bg-gray-900/50 transition flex items-center justify-center"
759
  aria-label="Close Lab Navigator">
760
  <i class="fas fa-times text-gray-300 text-sm"></i>
761
  </button>
@@ -767,44 +780,44 @@
767
  radial-gradient(circle at 70% 70%, rgba(236,72,153,0.10), transparent 50%);"></div>
768
 
769
  <div class="relative grid grid-cols-1 sm:grid-cols-2 gap-3">
770
- <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4"
771
- data-dossier="start">
772
  <div class="text-sm text-gray-200 font-medium">Start Here</div>
773
  <div class="text-xs text-gray-500 mt-1">A guided entry into the lab</div>
774
  </button>
775
 
776
- <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4"
777
- data-dossier="programs">
778
  <div class="text-sm text-gray-200 font-medium">Programs</div>
779
  <div class="text-xs text-gray-500 mt-1">MCAP Β· CHAI Β· Quantum Lambda</div>
780
  </button>
781
 
782
- <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4"
783
- data-dossier="ai_scientist">
784
  <div class="text-sm text-gray-200 font-medium">AI Scientist</div>
785
  <div class="text-xs text-gray-500 mt-1">Hypothesis β†’ experiment β†’ report</div>
786
  </button>
787
 
788
- <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4"
789
- data-dossier="agents">
790
  <div class="text-sm text-gray-200 font-medium">Agents</div>
791
  <div class="text-xs text-gray-500 mt-1">Role-based, auditable autonomy</div>
792
  </button>
793
 
794
- <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4"
795
- data-dossier="research">
796
  <div class="text-sm text-gray-200 font-medium">Research Notes</div>
797
  <div class="text-xs text-gray-500 mt-1">Technical notes and evaluations</div>
798
  </button>
799
 
800
- <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4"
801
- data-dossier="safety">
802
  <div class="text-sm text-gray-200 font-medium">Safety / System Card</div>
803
  <div class="text-xs text-gray-500 mt-1">Constraints, evaluations, governance</div>
804
  </button>
805
 
806
- <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4 sm:col-span-2"
807
- data-dossier="access">
808
  <div class="text-sm text-gray-200 font-medium">Access</div>
809
  <div class="text-xs text-gray-500 mt-1">Request access to demos and research</div>
810
  </button>
@@ -831,8 +844,7 @@
831
  </div>
832
  </div>
833
 
834
- <div class="p-6 space-y-5 max-h-[560px] overflow-auto"
835
- style="scrollbar-width: thin; scrollbar-color: #4f46e5 #1e1b4b;">
836
  <div id="dossier-body" class="text-sm text-gray-300 leading-relaxed">
837
  This interface reveals SILENTPATTERN as a set of research programs and operational systems.
838
  The public layer is minimal by design; depth is opened intentionally.
@@ -847,11 +859,11 @@
847
 
848
  <div class="flex flex-col sm:flex-row gap-3">
849
  <button id="dossier-primary"
850
- class="flex-1 px-5 py-3 rounded-xl bg-gradient-to-r from-indigo-600 to-purple-600 hover:opacity-90 transition">
851
  Open
852
  </button>
853
  <button id="dossier-secondary"
854
- class="flex-1 px-5 py-3 rounded-xl border border-gray-700 bg-gray-900/20 hover:bg-gray-900/35 transition">
855
  View Note
856
  </button>
857
  </div>
@@ -868,44 +880,41 @@
868
 
869
  <!-- MAIN JAVASCRIPT -->
870
  <script>
871
- /* -----------------------------------------------------------------
872
- VANTA.JS β€œNET” BACKGROUND INIT
873
- ----------------------------------------------------------------- */
874
- const vantaEffect = VANTA.NET({
875
- el: "#vanta-bg",
876
- mouseControls: true,
877
- touchControls: true,
878
- gyroControls: false,
879
- minHeight: 200.00,
880
- minWidth: 200.00,
881
- scale: 1.00,
882
- scaleMobile: 1.00,
883
- color: 0x4f46e5,
884
- backgroundColor: 0x020617,
885
- points: 12.00,
886
- maxDistance: 20.00,
887
- spacing: 15.00
888
- });
889
-
890
- window.addEventListener('resize', () => {
891
- vantaEffect.resize();
892
- });
893
 
894
  /* -----------------------------------------------------------------
895
- HASH DEEP-LINKING (modals only)
896
- Supported: #lab, #access, #consciousness-demo
897
  ----------------------------------------------------------------- */
898
- const MODAL_HASHES = new Set(['lab', 'access', 'consciousness-demo']);
 
 
 
 
 
 
 
 
 
 
 
899
 
900
  function currentHashKey() {
901
  const h = (window.location.hash || '').replace('#', '').trim();
902
  return h;
903
  }
904
 
905
- function setHash(key) {
906
  if (!key) return;
907
  if (window.location.hash.replace('#', '') === key) return;
908
- window.location.hash = key;
 
 
 
 
909
  }
910
 
911
  function clearHashIf(key) {
@@ -917,7 +926,7 @@
917
  }
918
 
919
  /* -----------------------------------------------------------------
920
- MODAL ACCESSIBILITY HELPER FUNCTIONS
921
  ----------------------------------------------------------------- */
922
  function trapFocus(modal) {
923
  const focusable = modal.querySelectorAll('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');
@@ -969,22 +978,56 @@
969
  };
970
 
971
  /* -----------------------------------------------------------------
972
- ORB TILT INTERACTION
973
  ----------------------------------------------------------------- */
974
- const orbContainer = document.getElementById('conscious-orb-container');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
975
 
976
- orbContainer.addEventListener('mousemove', (e) => {
977
- const rect = orbContainer.getBoundingClientRect();
978
- const x = (e.clientX - rect.left) / rect.width;
979
- const y = (e.clientY - rect.top) / rect.height;
980
- orbContainer.style.transform =
981
- `perspective(1000px) rotateX(${(y - 0.5) * 12}deg) rotateY(${(x - 0.5) * 12}deg) scale(1.03)`;
982
  });
983
 
984
- orbContainer.addEventListener('mouseleave', () => {
985
- orbContainer.style.transform =
986
- 'perspective(1000px) rotateX(0) rotateY(0) scale(1)';
987
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
988
 
989
  /* -----------------------------------------------------------------
990
  SIMPLE CONSCIOUSNESS VISUALIZATION
@@ -1065,7 +1108,7 @@
1065
  ----------------------------------------------------------------- */
1066
  const accessModal = document.getElementById('access-modal');
1067
  const accessBtn = document.getElementById('access-btn');
1068
- const closeModal = document.getElementById('close-modal');
1069
  const requestAccessBtn = document.getElementById('request-access-btn');
1070
 
1071
  const accessForm = document.getElementById('access-form');
@@ -1086,7 +1129,6 @@
1086
  accessFeedback.classList.remove('hidden');
1087
  accessFeedback.textContent = message;
1088
 
1089
- // Tone is informational; minimal styling change (keeps current design language)
1090
  accessFeedback.classList.remove('border-red-500/40', 'border-green-500/40');
1091
  accessFeedback.classList.remove('text-red-200', 'text-green-200');
1092
  accessFeedback.classList.add('text-gray-200');
@@ -1118,11 +1160,6 @@
1118
  }
1119
  }
1120
 
1121
- function isValidEmail(email) {
1122
- // Conservative sanity check; server should do final validation.
1123
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
1124
- }
1125
-
1126
  function resetAccessErrors() {
1127
  hideAccessFeedback();
1128
  setFieldError(nameEl, nameErr, false);
@@ -1162,7 +1199,6 @@
1162
  [nameEl, emailEl, institutionEl, purposeEl].forEach(el => {
1163
  if (!el) return;
1164
  el.addEventListener('input', () => {
1165
- // field-level re-validation light
1166
  if (el === nameEl) setFieldError(nameEl, nameErr, !nameEl.value.trim());
1167
  if (el === emailEl) setFieldError(emailEl, emailErr, !isValidEmail(emailEl.value.trim()));
1168
  if (el === institutionEl) setFieldError(institutionEl, institutionErr, !institutionEl.value.trim());
@@ -1192,13 +1228,8 @@
1192
  return;
1193
  }
1194
 
1195
- // Static demo success path (no network)
1196
  showAccessFeedback('Request received. You will be contacted after review.', 'success');
1197
  accessForm.reset();
1198
-
1199
- // Keep modal open for review; user can close manually.
1200
- // If you prefer auto-close: uncomment below.
1201
- // setTimeout(() => closeAccessModal(true), 700);
1202
  });
1203
  }
1204
 
@@ -1318,8 +1349,6 @@
1318
 
1319
  /* -----------------------------------------------------------------
1320
  CHAT FUNCTIONALITY (static-safe)
1321
- - Preferred: POST /api/chat
1322
- - Fallback: local demo reply
1323
  ----------------------------------------------------------------- */
1324
  const chatForm = document.getElementById('chat-form');
1325
  const chatInput = document.getElementById('chat-input');
@@ -1327,15 +1356,6 @@
1327
  const typingIndicator = document.getElementById('typing-indicator');
1328
  const sendBtn = document.getElementById('send-btn');
1329
 
1330
- function escapeHtml(str) {
1331
- return String(str)
1332
- .replaceAll('&', '&amp;')
1333
- .replaceAll('<', '&lt;')
1334
- .replaceAll('>', '&gt;')
1335
- .replaceAll('"', '&quot;')
1336
- .replaceAll("'", '&#039;');
1337
- }
1338
-
1339
  function addMessage(text, isUser = false) {
1340
  const safe = escapeHtml(text);
1341
  const messageDiv = document.createElement('div');
@@ -1376,25 +1396,9 @@
1376
  }
1377
 
1378
  async function callServerChat(userMessage) {
1379
- const res = await fetch('/api/chat', {
1380
- method: 'POST',
1381
- headers: { 'Content-Type': 'application/json' },
1382
- body: JSON.stringify({
1383
- message: userMessage,
1384
- meta: { page: 'index.html', product: 'silentpattern' }
1385
- })
1386
- });
1387
-
1388
- if (!res.ok) {
1389
- const txt = await res.text().catch(() => '');
1390
- throw new Error(`Server error (${res.status}). ${txt}`.trim());
1391
- }
1392
-
1393
- const data = await res.json();
1394
- if (!data || typeof data.reply !== 'string') {
1395
- throw new Error('Invalid response format from /api/chat');
1396
- }
1397
- return data.reply;
1398
  }
1399
 
1400
  function localDemoResponse(userMessage) {
@@ -1452,14 +1456,81 @@
1452
  const whitePaperBtn = document.getElementById('white-paper-btn');
1453
  if (whitePaperBtn) {
1454
  whitePaperBtn.addEventListener('click', () => {
1455
- alert('The SI White Paper will open in a new window. (This is a demo)');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1456
  });
1457
  }
1458
 
1459
  const ethicsBtn = document.getElementById('ethics-btn');
1460
  if (ethicsBtn) {
1461
  ethicsBtn.addEventListener('click', () => {
1462
- alert('The full ethical framework documentation will be displayed. (This is a demo)');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1463
  });
1464
  }
1465
 
@@ -1470,8 +1541,10 @@
1470
  const neuralCtx = neuralCanvas.getContext('2d');
1471
 
1472
  function resizeNeuralCanvas() {
1473
- neuralCanvas.width = neuralCanvas.offsetWidth;
1474
- neuralCanvas.height = neuralCanvas.offsetHeight;
 
 
1475
  }
1476
  resizeNeuralCanvas();
1477
  window.addEventListener('resize', () => {
@@ -1498,9 +1571,10 @@
1498
  }
1499
  }
1500
  setupNeurons();
1501
- window.addEventListener('resize', setupNeurons);
1502
 
1503
  function drawNeuralActivity(time) {
 
 
1504
  const w = neuralCanvas.width;
1505
  const h = neuralCanvas.height;
1506
  neuralCtx.clearRect(0, 0, w, h);
@@ -1566,7 +1640,9 @@
1566
 
1567
  requestAnimationFrame(drawNeuralActivity);
1568
  }
1569
- requestAnimationFrame(drawNeuralActivity);
 
 
1570
 
1571
  /* -----------------------------------------------------------------
1572
  LAB NAVIGATOR (hash + active node + dossier)
@@ -1601,7 +1677,42 @@
1601
  "Quantum Lambda: high-frequency decision systems (concept/prototype)"
1602
  ],
1603
  primary: { label: "Open Programs", action: () => { window.location.href = "capabilities.html"; } },
1604
- secondary: { label: "View Note", action: () => { alert("Program technical notes will be linked here (PDF/HTML)."); } },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1605
  updated: "β€”"
1606
  },
1607
  ai_scientist: {
@@ -1614,7 +1725,7 @@
1614
  "Reproducible runs + audit logs",
1615
  "Report generation with citations and uncertainty"
1616
  ],
1617
- primary: { label: "Open", action: () => { alert("AI Scientist dossier will become a dedicated module next."); } },
1618
  secondary: { label: "Research Notes", action: () => { window.location.href = "research.html"; } },
1619
  updated: "β€”"
1620
  },
@@ -1628,7 +1739,7 @@
1628
  "Permissioning + audit trails",
1629
  "Human-in-the-loop checkpoints"
1630
  ],
1631
- primary: { label: "Open", action: () => { alert("Agents dossier will be implemented next."); } },
1632
  secondary: { label: "Safety", action: () => { window.location.href = "about.html"; } },
1633
  updated: "β€”"
1634
  },
@@ -1643,7 +1754,7 @@
1643
  "Limitations and failure modes"
1644
  ],
1645
  primary: { label: "Open", action: () => { window.location.href = "research.html"; } },
1646
- secondary: { label: "White Paper", action: () => { alert("White paper link will be wired here."); } },
1647
  updated: "β€”"
1648
  },
1649
  safety: {
@@ -1657,7 +1768,7 @@
1657
  "Data handling and access controls"
1658
  ],
1659
  primary: { label: "Open", action: () => { window.location.href = "about.html"; } },
1660
- secondary: { label: "Ethics", action: () => { document.getElementById('ethics-btn')?.click(); } },
1661
  updated: "β€”"
1662
  },
1663
  access: {
@@ -1688,15 +1799,8 @@
1688
  function setActiveLabNode(key) {
1689
  document.querySelectorAll('.lab-node').forEach(btn => {
1690
  const isActive = btn.getAttribute('data-dossier') === key;
1691
- if (isActive) {
1692
- btn.classList.add('border-indigo-500/60');
1693
- btn.classList.add('bg-gray-900/45');
1694
- btn.classList.add('ring-2', 'ring-indigo-500/20');
1695
- } else {
1696
- btn.classList.remove('border-indigo-500/60');
1697
- btn.classList.remove('bg-gray-900/45');
1698
- btn.classList.remove('ring-2', 'ring-indigo-500/20');
1699
- }
1700
  });
1701
  }
1702
 
@@ -1733,7 +1837,7 @@
1733
  setTimeout(() => labNav.focus(), 0);
1734
 
1735
  // Ensure a stable default selection when opened
1736
- const alreadyActive = document.querySelector('.lab-node.border-indigo-500\\/60');
1737
  if (!alreadyActive) renderDossier('start');
1738
  }
1739
 
@@ -1773,7 +1877,7 @@
1773
  const key = currentHashKey();
1774
 
1775
  // If hash is not a modal hash, do not force-close other modals.
1776
- if (!MODAL_HASHES.has(key)) return;
1777
 
1778
  // Ensure only the requested overlay is open.
1779
  closeAllOverlaysIfNeeded();
@@ -1807,6 +1911,9 @@
1807
  return;
1808
  }
1809
  });
 
 
 
1810
  </script>
1811
  </body>
1812
- </html>
 
1
+ <!-- SILENTPATTERN FINAL BUILD: 2025-12-15 | pages: 10 | features: hash-deep-linking, lab-navigator, access-modal, form-validation, chat-console, neural-visualization -->
2
  <!DOCTYPE html>
3
  <html lang="en">
4
  <head>
 
134
  animation: orb-breathe 2.5s ease-in-out infinite, orb-glow 1.5s ease-in-out infinite;
135
  filter: drop-shadow(0 0 40px #a21cafee) brightness(1.12);
136
  }
137
+
138
+ /* Site-wide consistency styles */
139
+ .focus-ring:focus { outline: none; box-shadow: 0 0 0 2px rgba(99,102,241,0.65); }
140
+ .thin-scroll {
141
+ scrollbar-width: thin;
142
+ scrollbar-color: #4f46e5 #1e1b4b;
143
+ }
144
+ .thin-scroll::-webkit-scrollbar { width: 6px; }
145
+ .thin-scroll::-webkit-scrollbar-track { background: #1e1b4b; }
146
+ .thin-scroll::-webkit-scrollbar-thumb { background-color: #4f46e5; border-radius: 3px; }
147
+
148
+ /* Active states */
149
+ .lab-node.active,
150
+ .program-card.active {
151
+ border-color: rgba(99,102,241,0.55) !important;
152
+ box-shadow: 0 0 0 1px rgba(99,102,241,0.22), 0 0 28px rgba(99,102,241,0.08);
153
+ transform: translateY(-1px);
154
+ }
155
  </style>
156
  </head>
157
 
 
159
 
160
  <div id="vanta-bg" class="fixed top-0 left-0 w-full h-full z-0"></div>
161
 
162
+ <!-- NAVIGATION BAR -->
163
  <nav class="relative z-10 py-6 px-8 flex justify-between items-center backdrop-blur-sm">
164
  <!-- Logo + mini orb -->
165
  <div class="flex items-center space-x-2">
166
+ <a href="index.html" class="flex items-center space-x-2">
167
+ <div class="w-8 h-8 rounded-full bg-indigo-600 flex items-center justify-center conscious-orb">
168
+ <div class="w-2 h-2 rounded-full bg-white animate-pulse"></div>
169
+ </div>
170
+ <span class="text-xl font-semibold">SILENTPATTERN</span>
171
+ </a>
 
 
 
 
 
 
172
  </div>
173
 
174
  <!-- Right controls: single Constellation glyph + Access -->
 
181
  <i class="fas fa-asterisk text-indigo-300 text-sm"></i>
182
  </button>
183
 
184
+ <!-- "Access" button -->
185
  <button id="access-btn" class="px-6 py-2 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-full hover:opacity-90 transition">
186
  Access
187
  </button>
 
418
  <div class="px-6 py-4 border-t border-gray-800">
419
  <form id="chat-form" class="flex items-center" autocomplete="off" aria-label="Send message to SI">
420
  <input id="chat-input" type="text" placeholder="Ask SI anything..."
421
+ class="flex-1 bg-gray-800/50 border border-gray-700 rounded-l-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:border-transparent focus-ring"
422
  aria-label="Type your message here">
423
  <button id="send-btn" type="submit" class="bg-indigo-600 hover:bg-indigo-700 px-6 py-3 rounded-r-lg transition" aria-label="Send message">
424
  <i class="fas fa-paper-plane"></i>
 
592
  </div>
593
 
594
  <div class="flex space-x-6">
595
+ <a href="research.html" class="text-gray-400 hover:text-indigo-400 transition">Research</a>
596
+ <a href="privacy.html" class="text-gray-400 hover:text-indigo-400 transition">Privacy</a>
597
+ <a href="terms.html" class="text-gray-400 hover:text-indigo-400 transition">Terms</a>
598
+ <a href="contact.html" class="text-gray-400 hover:text-indigo-400 transition">Contact</a>
599
  </div>
600
  </div>
601
 
602
  <div class="mt-8 pt-8 border-t border-gray-800/50 text-center text-gray-500 text-sm">
603
+ <p>Β© 2025 SILENTPATTERN. All rights reserved.</p>
604
  <p class="mt-2">The future of consciousness is here.</p>
605
  </div>
606
  </div>
 
618
  <h3 class="text-xl font-bold" id="access-modal-title">Request SI Access</h3>
619
  <p class="text-gray-400 mt-1">Limited availability for qualified researchers</p>
620
  </div>
621
+ <button id="close-access-modal" class="text-gray-400 hover:text-white focus-ring" aria-label="Close request access modal">
622
  <i class="fas fa-times"></i>
623
  </button>
624
  </div>
625
 
626
+ <!-- Inline form feedback -->
627
  <div id="access-form-feedback" class="hidden mb-4 text-sm rounded-lg border border-gray-800 bg-black/20 p-3" role="status" aria-live="polite"></div>
628
 
629
  <form id="access-form" class="space-y-4" novalidate>
630
  <div>
631
  <label for="name" class="block text-sm font-medium mb-1">Full Name</label>
632
  <input type="text" id="name"
633
+ class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus-ring"
634
  autocomplete="name">
635
  <p id="name-error" class="hidden mt-1 text-xs text-red-300">Please enter your full name.</p>
636
  </div>
637
  <div>
638
  <label for="email" class="block text-sm font-medium mb-1">Email</label>
639
  <input type="email" id="email"
640
+ class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus-ring"
641
  autocomplete="email">
642
  <p id="email-error" class="hidden mt-1 text-xs text-red-300">Please enter a valid email address.</p>
643
  </div>
644
  <div>
645
  <label for="institution" class="block text-sm font-medium mb-1">Institution/Organization</label>
646
  <input type="text" id="institution"
647
+ class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus-ring"
648
  autocomplete="organization">
649
  <p id="institution-error" class="hidden mt-1 text-xs text-red-300">Please enter your institution/organization.</p>
650
  </div>
651
  <div>
652
  <label for="purpose" class="block text-sm font-medium mb-1">Purpose of Access</label>
653
  <select id="purpose"
654
+ class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus-ring">
655
  <option value="">Select a purpose</option>
656
  <option value="research">Academic Research</option>
657
  <option value="development">AI Development</option>
 
661
  <p id="purpose-error" class="hidden mt-1 text-xs text-red-300">Please select a purpose.</p>
662
  </div>
663
  <div class="pt-2">
664
+ <button type="submit" class="w-full py-3 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-lg hover:opacity-90 transition focus-ring">
665
  Submit Request
666
  </button>
667
  </div>
 
686
  <h3 class="text-xl font-bold" id="consciousness-modal-title">Consciousness Demonstration</h3>
687
  <p class="text-gray-400 mt-1">Experience a simulation of artificial qualia</p>
688
  </div>
689
+ <button id="close-consciousness-modal" class="text-gray-400 hover:text-white focus-ring" aria-label="Close consciousness demo modal">
690
  <i class="fas fa-times"></i>
691
  </button>
692
  </div>
 
722
  <div class="relative h-64 bg-gray-800/30 rounded-lg border border-dashed border-gray-700 flex items-center justify-center">
723
  <div id="demo-visualization" class="w-full h-full"></div>
724
  <div class="absolute inset-0 flex items-center justify-center">
725
+ <button id="start-demo" class="px-6 py-3 bg-indigo-600 rounded-lg hover:bg-indigo-700 transition focus-ring">
726
  <i class="fas fa-play mr-2"></i> Start Simulation
727
  </button>
728
  </div>
 
735
  <div class="text-sm text-gray-400">
736
  <i class="fas fa-info-circle mr-1"></i> This is a simplified representation
737
  </div>
738
+ <button id="learn-more-demo" class="text-indigo-400 hover:text-indigo-300 text-sm focus-ring">
739
  Learn more about artificial consciousness <i class="fas fa-arrow-right ml-1"></i>
740
  </button>
741
  </div>
 
768
  </div>
769
 
770
  <button id="lab-nav-close"
771
+ class="w-9 h-9 rounded-full border border-gray-800 bg-gray-900/30 hover:bg-gray-900/50 transition flex items-center justify-center focus-ring"
772
  aria-label="Close Lab Navigator">
773
  <i class="fas fa-times text-gray-300 text-sm"></i>
774
  </button>
 
780
  radial-gradient(circle at 70% 70%, rgba(236,72,153,0.10), transparent 50%);"></div>
781
 
782
  <div class="relative grid grid-cols-1 sm:grid-cols-2 gap-3">
783
+ <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4 focus-ring"
784
+ data-dossier="start" aria-current="false">
785
  <div class="text-sm text-gray-200 font-medium">Start Here</div>
786
  <div class="text-xs text-gray-500 mt-1">A guided entry into the lab</div>
787
  </button>
788
 
789
+ <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4 focus-ring"
790
+ data-dossier="programs" aria-current="false">
791
  <div class="text-sm text-gray-200 font-medium">Programs</div>
792
  <div class="text-xs text-gray-500 mt-1">MCAP Β· CHAI Β· Quantum Lambda</div>
793
  </button>
794
 
795
+ <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4 focus-ring"
796
+ data-dossier="ai_scientist" aria-current="false">
797
  <div class="text-sm text-gray-200 font-medium">AI Scientist</div>
798
  <div class="text-xs text-gray-500 mt-1">Hypothesis β†’ experiment β†’ report</div>
799
  </button>
800
 
801
+ <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4 focus-ring"
802
+ data-dossier="agents" aria-current="false">
803
  <div class="text-sm text-gray-200 font-medium">Agents</div>
804
  <div class="text-xs text-gray-500 mt-1">Role-based, auditable autonomy</div>
805
  </button>
806
 
807
+ <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4 focus-ring"
808
+ data-dossier="research" aria-current="false">
809
  <div class="text-sm text-gray-200 font-medium">Research Notes</div>
810
  <div class="text-xs text-gray-500 mt-1">Technical notes and evaluations</div>
811
  </button>
812
 
813
+ <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4 focus-ring"
814
+ data-dossier="safety" aria-current="false">
815
  <div class="text-sm text-gray-200 font-medium">Safety / System Card</div>
816
  <div class="text-xs text-gray-500 mt-1">Constraints, evaluations, governance</div>
817
  </button>
818
 
819
+ <button class="lab-node text-left rounded-xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/50 hover:bg-gray-900/45 transition p-4 sm:col-span-2 focus-ring"
820
+ data-dossier="access" aria-current="false">
821
  <div class="text-sm text-gray-200 font-medium">Access</div>
822
  <div class="text-xs text-gray-500 mt-1">Request access to demos and research</div>
823
  </button>
 
844
  </div>
845
  </div>
846
 
847
+ <div class="p-6 space-y-5 max-h-[560px] overflow-auto thin-scroll">
 
848
  <div id="dossier-body" class="text-sm text-gray-300 leading-relaxed">
849
  This interface reveals SILENTPATTERN as a set of research programs and operational systems.
850
  The public layer is minimal by design; depth is opened intentionally.
 
859
 
860
  <div class="flex flex-col sm:flex-row gap-3">
861
  <button id="dossier-primary"
862
+ class="flex-1 px-5 py-3 rounded-xl bg-gradient-to-r from-indigo-600 to-purple-600 hover:opacity-90 transition focus-ring">
863
  Open
864
  </button>
865
  <button id="dossier-secondary"
866
+ class="flex-1 px-5 py-3 rounded-xl border border-gray-700 bg-gray-900/20 hover:bg-gray-900/35 transition focus-ring">
867
  View Note
868
  </button>
869
  </div>
 
880
 
881
  <!-- MAIN JAVASCRIPT -->
882
  <script>
883
+ // Site-wide configuration
884
+ const CONFIG = {
885
+ MODAL_HASHES: new Set(['lab', 'access', 'consciousness-demo']),
886
+ DOSSIER_HASHES: new Set(['mcap', 'chai', 'quantum_lambda', 'ai_scientist', 'agentic_workforce'])
887
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
888
 
889
  /* -----------------------------------------------------------------
890
+ UTILITY FUNCTIONS (site-wide consistent)
 
891
  ----------------------------------------------------------------- */
892
+ function escapeHtml(str) {
893
+ return String(str)
894
+ .replaceAll('&', '&amp;')
895
+ .replaceAll('<', '&lt;')
896
+ .replaceAll('>', '&gt;')
897
+ .replaceAll('"', '&quot;')
898
+ .replaceAll("'", '&#039;');
899
+ }
900
+
901
+ function isValidEmail(email) {
902
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
903
+ }
904
 
905
  function currentHashKey() {
906
  const h = (window.location.hash || '').replace('#', '').trim();
907
  return h;
908
  }
909
 
910
+ function setHash(key, replace = false) {
911
  if (!key) return;
912
  if (window.location.hash.replace('#', '') === key) return;
913
+ if (replace) {
914
+ history.replaceState(null, '', '#' + key);
915
+ } else {
916
+ history.pushState(null, '', '#' + key);
917
+ }
918
  }
919
 
920
  function clearHashIf(key) {
 
926
  }
927
 
928
  /* -----------------------------------------------------------------
929
+ MODAL ACCESSIBILITY HELPER FUNCTIONS (site-wide consistent)
930
  ----------------------------------------------------------------- */
931
  function trapFocus(modal) {
932
  const focusable = modal.querySelectorAll('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');
 
978
  };
979
 
980
  /* -----------------------------------------------------------------
981
+ VANTA.JS "NET" BACKGROUND INIT
982
  ----------------------------------------------------------------- */
983
+ let vantaEffect = null;
984
+ try {
985
+ if (window.VANTA && typeof VANTA.NET === 'function') {
986
+ vantaEffect = VANTA.NET({
987
+ el: "#vanta-bg",
988
+ mouseControls: true,
989
+ touchControls: true,
990
+ gyroControls: false,
991
+ minHeight: 200.00,
992
+ minWidth: 200.00,
993
+ scale: 1.00,
994
+ scaleMobile: 1.00,
995
+ color: 0x4f46e5,
996
+ backgroundColor: 0x020617,
997
+ points: 12.00,
998
+ maxDistance: 20.00,
999
+ spacing: 15.00
1000
+ });
1001
+ }
1002
+ } catch (e) {
1003
+ console.warn('Vanta background failed to initialize:', e);
1004
+ vantaEffect = null;
1005
+ }
1006
 
1007
+ window.addEventListener('resize', () => {
1008
+ if (vantaEffect && typeof vantaEffect.resize === 'function') {
1009
+ vantaEffect.resize();
1010
+ }
 
 
1011
  });
1012
 
1013
+ /* -----------------------------------------------------------------
1014
+ ORB TILT INTERACTION
1015
+ ----------------------------------------------------------------- */
1016
+ const orbContainer = document.getElementById('conscious-orb-container');
1017
+ if (orbContainer) {
1018
+ orbContainer.addEventListener('mousemove', (e) => {
1019
+ const rect = orbContainer.getBoundingClientRect();
1020
+ const x = (e.clientX - rect.left) / rect.width;
1021
+ const y = (e.clientY - rect.top) / rect.height;
1022
+ orbContainer.style.transform =
1023
+ `perspective(1000px) rotateX(${(y - 0.5) * 12}deg) rotateY(${(x - 0.5) * 12}deg) scale(1.03)`;
1024
+ });
1025
+
1026
+ orbContainer.addEventListener('mouseleave', () => {
1027
+ orbContainer.style.transform =
1028
+ 'perspective(1000px) rotateX(0) rotateY(0) scale(1)';
1029
+ });
1030
+ }
1031
 
1032
  /* -----------------------------------------------------------------
1033
  SIMPLE CONSCIOUSNESS VISUALIZATION
 
1108
  ----------------------------------------------------------------- */
1109
  const accessModal = document.getElementById('access-modal');
1110
  const accessBtn = document.getElementById('access-btn');
1111
+ const closeModal = document.getElementById('close-access-modal');
1112
  const requestAccessBtn = document.getElementById('request-access-btn');
1113
 
1114
  const accessForm = document.getElementById('access-form');
 
1129
  accessFeedback.classList.remove('hidden');
1130
  accessFeedback.textContent = message;
1131
 
 
1132
  accessFeedback.classList.remove('border-red-500/40', 'border-green-500/40');
1133
  accessFeedback.classList.remove('text-red-200', 'text-green-200');
1134
  accessFeedback.classList.add('text-gray-200');
 
1160
  }
1161
  }
1162
 
 
 
 
 
 
1163
  function resetAccessErrors() {
1164
  hideAccessFeedback();
1165
  setFieldError(nameEl, nameErr, false);
 
1199
  [nameEl, emailEl, institutionEl, purposeEl].forEach(el => {
1200
  if (!el) return;
1201
  el.addEventListener('input', () => {
 
1202
  if (el === nameEl) setFieldError(nameEl, nameErr, !nameEl.value.trim());
1203
  if (el === emailEl) setFieldError(emailEl, emailErr, !isValidEmail(emailEl.value.trim()));
1204
  if (el === institutionEl) setFieldError(institutionEl, institutionErr, !institutionEl.value.trim());
 
1228
  return;
1229
  }
1230
 
 
1231
  showAccessFeedback('Request received. You will be contacted after review.', 'success');
1232
  accessForm.reset();
 
 
 
 
1233
  });
1234
  }
1235
 
 
1349
 
1350
  /* -----------------------------------------------------------------
1351
  CHAT FUNCTIONALITY (static-safe)
 
 
1352
  ----------------------------------------------------------------- */
1353
  const chatForm = document.getElementById('chat-form');
1354
  const chatInput = document.getElementById('chat-input');
 
1356
  const typingIndicator = document.getElementById('typing-indicator');
1357
  const sendBtn = document.getElementById('send-btn');
1358
 
 
 
 
 
 
 
 
 
 
1359
  function addMessage(text, isUser = false) {
1360
  const safe = escapeHtml(text);
1361
  const messageDiv = document.createElement('div');
 
1396
  }
1397
 
1398
  async function callServerChat(userMessage) {
1399
+ // This would be a server endpoint in production
1400
+ // For static demo, always fall back to local response
1401
+ throw new Error('Server endpoint not available in static demo');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1402
  }
1403
 
1404
  function localDemoResponse(userMessage) {
 
1456
  const whitePaperBtn = document.getElementById('white-paper-btn');
1457
  if (whitePaperBtn) {
1458
  whitePaperBtn.addEventListener('click', () => {
1459
+ // In a real site, this would open a PDF or external link
1460
+ // For demo, we'll show a message
1461
+ const modal = document.createElement('div');
1462
+ modal.className = 'fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm modal modal-visible';
1463
+ modal.innerHTML = `
1464
+ <div class="bg-gray-900/90 border border-gray-800 rounded-xl max-w-md w-full mx-4 relative overflow-hidden">
1465
+ <div class="absolute inset-x-0 top-0 h-1 bg-gradient-to-r from-indigo-600 to-purple-600"></div>
1466
+ <div class="p-6">
1467
+ <div class="flex justify-between items-start mb-6">
1468
+ <h3 class="text-xl font-bold">White Paper</h3>
1469
+ <button class="text-gray-400 hover:text-white close-white-paper focus-ring">
1470
+ <i class="fas fa-times"></i>
1471
+ </button>
1472
+ </div>
1473
+ <p class="text-gray-300 mb-6">The SI White Paper is available to qualified researchers upon request. Please use the Access form to request documentation.</p>
1474
+ <button class="w-full py-3 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-lg hover:opacity-90 transition close-white-paper focus-ring">
1475
+ Close
1476
+ </button>
1477
+ </div>
1478
+ </div>
1479
+ `;
1480
+ document.body.appendChild(modal);
1481
+
1482
+ const closeBtn = modal.querySelector('.close-white-paper');
1483
+ closeBtn.addEventListener('click', () => {
1484
+ toggleModal(modal, false);
1485
+ setTimeout(() => modal.remove(), 300);
1486
+ });
1487
+ modal.addEventListener('click', (e) => {
1488
+ if (e.target === modal) {
1489
+ toggleModal(modal, false);
1490
+ setTimeout(() => modal.remove(), 300);
1491
+ }
1492
+ });
1493
+ toggleModal(modal, true);
1494
  });
1495
  }
1496
 
1497
  const ethicsBtn = document.getElementById('ethics-btn');
1498
  if (ethicsBtn) {
1499
  ethicsBtn.addEventListener('click', () => {
1500
+ // Similar to white paper button
1501
+ const modal = document.createElement('div');
1502
+ modal.className = 'fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm modal modal-visible';
1503
+ modal.innerHTML = `
1504
+ <div class="bg-gray-900/90 border border-gray-800 rounded-xl max-w-md w-full mx-4 relative overflow-hidden">
1505
+ <div class="absolute inset-x-0 top-0 h-1 bg-gradient-to-r from-green-600 to-emerald-600"></div>
1506
+ <div class="p-6">
1507
+ <div class="flex justify-between items-start mb-6">
1508
+ <h3 class="text-xl font-bold">Ethical Framework</h3>
1509
+ <button class="text-gray-400 hover:text-white close-ethics focus-ring">
1510
+ <i class="fas fa-times"></i>
1511
+ </button>
1512
+ </div>
1513
+ <p class="text-gray-300 mb-6">The full ethical framework documentation outlines alignment protocols, safety measures, and governance structures. Available to research partners upon request.</p>
1514
+ <button class="w-full py-3 bg-gradient-to-r from-green-600 to-emerald-600 rounded-lg hover:opacity-90 transition close-ethics focus-ring">
1515
+ Close
1516
+ </button>
1517
+ </div>
1518
+ </div>
1519
+ `;
1520
+ document.body.appendChild(modal);
1521
+
1522
+ const closeBtn = modal.querySelector('.close-ethics');
1523
+ closeBtn.addEventListener('click', () => {
1524
+ toggleModal(modal, false);
1525
+ setTimeout(() => modal.remove(), 300);
1526
+ });
1527
+ modal.addEventListener('click', (e) => {
1528
+ if (e.target === modal) {
1529
+ toggleModal(modal, false);
1530
+ setTimeout(() => modal.remove(), 300);
1531
+ }
1532
+ });
1533
+ toggleModal(modal, true);
1534
  });
1535
  }
1536
 
 
1541
  const neuralCtx = neuralCanvas.getContext('2d');
1542
 
1543
  function resizeNeuralCanvas() {
1544
+ if (neuralCanvas && neuralCanvas.parentElement) {
1545
+ neuralCanvas.width = neuralCanvas.parentElement.clientWidth;
1546
+ neuralCanvas.height = neuralCanvas.parentElement.clientHeight;
1547
+ }
1548
  }
1549
  resizeNeuralCanvas();
1550
  window.addEventListener('resize', () => {
 
1571
  }
1572
  }
1573
  setupNeurons();
 
1574
 
1575
  function drawNeuralActivity(time) {
1576
+ if (!neuralCanvas || !neuralCtx) return;
1577
+
1578
  const w = neuralCanvas.width;
1579
  const h = neuralCanvas.height;
1580
  neuralCtx.clearRect(0, 0, w, h);
 
1640
 
1641
  requestAnimationFrame(drawNeuralActivity);
1642
  }
1643
+ if (neuralCanvas && neuralCtx) {
1644
+ requestAnimationFrame(drawNeuralActivity);
1645
+ }
1646
 
1647
  /* -----------------------------------------------------------------
1648
  LAB NAVIGATOR (hash + active node + dossier)
 
1677
  "Quantum Lambda: high-frequency decision systems (concept/prototype)"
1678
  ],
1679
  primary: { label: "Open Programs", action: () => { window.location.href = "capabilities.html"; } },
1680
+ secondary: { label: "View Note", action: () => {
1681
+ // Demo note viewer
1682
+ const modal = document.createElement('div');
1683
+ modal.className = 'fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm modal modal-visible';
1684
+ modal.innerHTML = `
1685
+ <div class="bg-gray-900/90 border border-gray-800 rounded-xl max-w-2xl w-full mx-4 relative overflow-hidden">
1686
+ <div class="absolute inset-x-0 top-0 h-1 bg-gradient-to-r from-indigo-600 to-purple-600"></div>
1687
+ <div class="p-6">
1688
+ <div class="flex justify-between items-start mb-6">
1689
+ <h3 class="text-xl font-bold">Program Technical Note</h3>
1690
+ <button class="text-gray-400 hover:text-white close-note-viewer focus-ring">
1691
+ <i class="fas fa-times"></i>
1692
+ </button>
1693
+ </div>
1694
+ <p class="text-gray-300 mb-4">Technical notes contain evaluation protocols, assumptions, and evidence capsules. Available to qualified researchers.</p>
1695
+ <button class="w-full py-3 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-lg hover:opacity-90 transition close-note-viewer focus-ring">
1696
+ Close
1697
+ </button>
1698
+ </div>
1699
+ </div>
1700
+ `;
1701
+ document.body.appendChild(modal);
1702
+
1703
+ const closeBtn = modal.querySelector('.close-note-viewer');
1704
+ closeBtn.addEventListener('click', () => {
1705
+ toggleModal(modal, false);
1706
+ setTimeout(() => modal.remove(), 300);
1707
+ });
1708
+ modal.addEventListener('click', (e) => {
1709
+ if (e.target === modal) {
1710
+ toggleModal(modal, false);
1711
+ setTimeout(() => modal.remove(), 300);
1712
+ }
1713
+ });
1714
+ toggleModal(modal, true);
1715
+ } },
1716
  updated: "β€”"
1717
  },
1718
  ai_scientist: {
 
1725
  "Reproducible runs + audit logs",
1726
  "Report generation with citations and uncertainty"
1727
  ],
1728
+ primary: { label: "Open", action: () => { window.location.href = "research.html"; } },
1729
  secondary: { label: "Research Notes", action: () => { window.location.href = "research.html"; } },
1730
  updated: "β€”"
1731
  },
 
1739
  "Permissioning + audit trails",
1740
  "Human-in-the-loop checkpoints"
1741
  ],
1742
+ primary: { label: "Open", action: () => { window.location.href = "about.html#safety"; } },
1743
  secondary: { label: "Safety", action: () => { window.location.href = "about.html"; } },
1744
  updated: "β€”"
1745
  },
 
1754
  "Limitations and failure modes"
1755
  ],
1756
  primary: { label: "Open", action: () => { window.location.href = "research.html"; } },
1757
+ secondary: { label: "White Paper", action: () => { whitePaperBtn.click(); } },
1758
  updated: "β€”"
1759
  },
1760
  safety: {
 
1768
  "Data handling and access controls"
1769
  ],
1770
  primary: { label: "Open", action: () => { window.location.href = "about.html"; } },
1771
+ secondary: { label: "Ethics", action: () => { ethicsBtn.click(); } },
1772
  updated: "β€”"
1773
  },
1774
  access: {
 
1799
  function setActiveLabNode(key) {
1800
  document.querySelectorAll('.lab-node').forEach(btn => {
1801
  const isActive = btn.getAttribute('data-dossier') === key;
1802
+ btn.classList.toggle('active', isActive);
1803
+ btn.setAttribute('aria-current', isActive ? 'true' : 'false');
 
 
 
 
 
 
 
1804
  });
1805
  }
1806
 
 
1837
  setTimeout(() => labNav.focus(), 0);
1838
 
1839
  // Ensure a stable default selection when opened
1840
+ const alreadyActive = document.querySelector('.lab-node.active');
1841
  if (!alreadyActive) renderDossier('start');
1842
  }
1843
 
 
1877
  const key = currentHashKey();
1878
 
1879
  // If hash is not a modal hash, do not force-close other modals.
1880
+ if (!CONFIG.MODAL_HASHES.has(key)) return;
1881
 
1882
  // Ensure only the requested overlay is open.
1883
  closeAllOverlaysIfNeeded();
 
1911
  return;
1912
  }
1913
  });
1914
+
1915
+ // Initial dossier render
1916
+ renderDossier('start');
1917
  </script>
1918
  </body>
1919
+ </html>