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

Update capabilities.html

Browse files
Files changed (1) hide show
  1. capabilities.html +408 -107
capabilities.html CHANGED
@@ -1,3 +1,4 @@
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
@@ -70,7 +71,7 @@
70
  .dot-proto { background: rgba(139,92,246,0.9); }
71
  .dot-validated { background: rgba(16,185,129,0.9); }
72
 
73
- /* Subtle β€œbay” grid */
74
  .bay-grid {
75
  background-image:
76
  linear-gradient(rgba(148,163,184,0.06) 1px, transparent 1px),
@@ -80,7 +81,7 @@
80
  }
81
 
82
  /* Active card state (minimal, consistent with design) */
83
- .program-card.is-active {
84
  border-color: rgba(99,102,241,0.55) !important;
85
  box-shadow: 0 0 0 1px rgba(99,102,241,0.22), 0 0 28px rgba(99,102,241,0.08);
86
  transform: translateY(-1px);
@@ -103,13 +104,13 @@
103
 
104
  <div class="flex items-center space-x-3">
105
  <button id="lab-nav-btn"
106
- class="w-10 h-10 rounded-full border border-indigo-500/40 bg-gray-900/20 hover:bg-gray-900/40 backdrop-blur-sm transition flex items-center justify-center"
107
  aria-label="Open Lab Navigator" title="Lab Navigator" aria-controls="lab-navigator" aria-haspopup="dialog">
108
  <i class="fas fa-asterisk text-indigo-300 text-sm"></i>
109
  </button>
110
 
111
  <button id="access-btn"
112
- class="px-6 py-2 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-full hover:opacity-90 transition"
113
  aria-controls="access-modal" aria-haspopup="dialog">
114
  Access
115
  </button>
@@ -164,7 +165,7 @@
164
 
165
  <!-- MCAP -->
166
  <button type="button"
167
- class="program-card text-left rounded-2xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/55 hover:bg-gray-900/45 transition p-5 conscious-element"
168
  data-dossier="mcap" aria-label="Open dossier: MCAP" aria-pressed="false">
169
  <div class="flex items-start justify-between gap-4">
170
  <div>
@@ -184,7 +185,7 @@
184
 
185
  <!-- CHAI -->
186
  <button type="button"
187
- class="program-card text-left rounded-2xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/55 hover:bg-gray-900/45 transition p-5 conscious-element"
188
  data-dossier="chai" aria-label="Open dossier: CHAI" aria-pressed="false">
189
  <div class="flex items-start justify-between gap-4">
190
  <div>
@@ -204,7 +205,7 @@
204
 
205
  <!-- Quantum Lambda -->
206
  <button type="button"
207
- class="program-card text-left rounded-2xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/55 hover:bg-gray-900/45 transition p-5 conscious-element"
208
  data-dossier="quantum_lambda" aria-label="Open dossier: Quantum Lambda" aria-pressed="false">
209
  <div class="flex items-start justify-between gap-4">
210
  <div>
@@ -224,7 +225,7 @@
224
 
225
  <!-- AI Scientist -->
226
  <button type="button"
227
- class="program-card text-left rounded-2xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/55 hover:bg-gray-900/45 transition p-5 conscious-element"
228
  data-dossier="ai_scientist" aria-label="Open dossier: AI Scientist" aria-pressed="false">
229
  <div class="flex items-start justify-between gap-4">
230
  <div>
@@ -244,7 +245,7 @@
244
 
245
  <!-- Agentic Workforce -->
246
  <button type="button"
247
- class="program-card text-left rounded-2xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/55 hover:bg-gray-900/45 transition p-5 conscious-element md:col-span-2"
248
  data-dossier="agentic_workforce" aria-label="Open dossier: Agentic Workforce" aria-pressed="false">
249
  <div class="flex items-start justify-between gap-4">
250
  <div>
@@ -254,7 +255,7 @@
254
  <span class="badge"><span class="dot dot-concept"></span>Concept</span>
255
  </div>
256
  <p class="text-sm text-gray-300 mt-4 leading-relaxed">
257
- β€œAI employees” as controlled agents: scoped permissions, logging, approval gates, and outcome verification.
258
  </p>
259
  <div class="mt-4 text-xs text-gray-500 flex items-center gap-2">
260
  <i class="fas fa-key"></i>
@@ -312,11 +313,11 @@
312
 
313
  <div class="flex flex-col gap-3">
314
  <button id="dossier-primary"
315
- class="px-5 py-3 rounded-xl bg-gradient-to-r from-indigo-600 to-purple-600 hover:opacity-90 transition">
316
  Request Access
317
  </button>
318
  <button id="dossier-secondary"
319
- class="px-5 py-3 rounded-xl border border-gray-700 bg-gray-900/20 hover:bg-gray-900/35 transition">
320
  Open Console
321
  </button>
322
  </div>
@@ -399,7 +400,7 @@
399
  <h3 class="text-xl font-bold" id="access-modal-title">Request Access</h3>
400
  <p class="text-gray-400 mt-1">Curated access for research and evaluation</p>
401
  </div>
402
- <button id="close-access-modal" class="text-gray-400 hover:text-white" aria-label="Close">
403
  <i class="fas fa-times"></i>
404
  </button>
405
  </div>
@@ -412,14 +413,17 @@
412
  <div>
413
  <label for="name" class="block text-sm font-medium mb-1">Full Name</label>
414
  <input type="text" id="name" class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus-ring" autocomplete="name">
 
415
  </div>
416
  <div>
417
  <label for="email" class="block text-sm font-medium mb-1">Email</label>
418
  <input type="email" id="email" class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus-ring" autocomplete="email">
 
419
  </div>
420
  <div>
421
  <label for="institution" class="block text-sm font-medium mb-1">Institution/Organization</label>
422
  <input type="text" id="institution" class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus-ring" autocomplete="organization">
 
423
  </div>
424
  <div>
425
  <label for="purpose" class="block text-sm font-medium mb-1">Purpose</label>
@@ -430,9 +434,10 @@
430
  <option value="partnership">Partnership</option>
431
  <option value="other">Other</option>
432
  </select>
 
433
  </div>
434
  <div class="pt-2">
435
- <button type="submit" class="w-full py-3 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-lg hover:opacity-90 transition">
436
  Submit Request
437
  </button>
438
  </div>
@@ -463,7 +468,7 @@
463
  </div>
464
 
465
  <button id="lab-nav-close"
466
- 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"
467
  aria-label="Close Lab Navigator">
468
  <i class="fas fa-times text-gray-300 text-sm"></i>
469
  </button>
@@ -475,34 +480,34 @@
475
  radial-gradient(circle at 70% 70%, rgba(236,72,153,0.10), transparent 50%);"></div>
476
 
477
  <div class="relative grid grid-cols-1 sm:grid-cols-2 gap-3">
478
- <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"
479
- data-nav="index.html">
480
  <div class="text-sm text-gray-200 font-medium">Start Here</div>
481
  <div class="text-xs text-gray-500 mt-1">Entry interface</div>
482
  </button>
483
 
484
- <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"
485
- data-nav="capabilities.html">
486
  <div class="text-sm text-gray-200 font-medium">Programs</div>
487
  <div class="text-xs text-gray-500 mt-1">This page</div>
488
  </button>
489
 
490
- <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"
491
- data-nav="chat.html">
492
  <div class="text-sm text-gray-200 font-medium">Console</div>
493
  <div class="text-xs text-gray-500 mt-1">Controlled chat</div>
494
  </button>
495
 
496
- <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"
497
- data-nav="research.html">
498
  <div class="text-sm text-gray-200 font-medium">Research</div>
499
  <div class="text-xs text-gray-500 mt-1">Notes and briefs</div>
500
  </button>
501
 
502
- <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"
503
- data-nav="contact.html">
504
- <div class="text-sm text-gray-200 font-medium">Contact</div>
505
- <div class="text-xs text-gray-500 mt-1">Direct channel</div>
506
  </button>
507
  </div>
508
 
@@ -514,12 +519,45 @@
514
 
515
  <div class="relative rounded-2xl border border-gray-800 bg-gray-900/30 overflow-hidden">
516
  <div class="px-6 py-5 border-b border-gray-800/60">
517
- <div class="text-lg font-semibold text-gray-100">Navigation</div>
518
- <div class="text-xs text-gray-500 mt-1">No top menu; only the lab interface.</div>
 
 
 
 
 
 
 
 
519
  </div>
520
- <div class="p-6 text-sm text-gray-300 leading-relaxed">
521
- SILENTPATTERN uses a reduced navigation surface to maintain a β€œlab console” feel.
522
- Pages are modules. Each module is accessed through this navigator.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
523
  </div>
524
  </div>
525
 
@@ -528,37 +566,53 @@
528
  </div>
529
 
530
  <script>
 
 
 
 
 
 
531
  /* -------------------------------------------------------------
532
- VANTA BACKGROUND (guarded)
533
  ------------------------------------------------------------- */
534
- let vantaEffect = null;
535
- try {
536
- if (window.VANTA && typeof VANTA.NET === 'function') {
537
- vantaEffect = VANTA.NET({
538
- el: "#vanta-bg",
539
- mouseControls: true,
540
- touchControls: true,
541
- gyroControls: false,
542
- minHeight: 200.00,
543
- minWidth: 200.00,
544
- scale: 1.00,
545
- scaleMobile: 1.00,
546
- color: 0x4f46e5,
547
- backgroundColor: 0x020617,
548
- points: 12.00,
549
- maxDistance: 20.00,
550
- spacing: 15.00
551
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
  }
553
- } catch (_) {
554
- vantaEffect = null;
555
  }
556
- window.addEventListener('resize', () => {
557
- if (vantaEffect && typeof vantaEffect.resize === 'function') vantaEffect.resize();
558
- });
559
 
560
  /* -------------------------------------------------------------
561
- MODAL HELPERS (focus trap + restore opener focus)
562
  ------------------------------------------------------------- */
563
  function trapFocus(modal) {
564
  const focusable = modal.querySelectorAll('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');
@@ -588,7 +642,6 @@
588
 
589
  const toggleModal = (modal, show) => {
590
  if (show) {
591
- modal._opener = document.activeElement;
592
  modal.classList.remove('modal-hidden');
593
  modal.classList.add('modal-visible');
594
  document.body.style.overflow = 'hidden';
@@ -598,13 +651,38 @@
598
  modal.classList.add('modal-hidden');
599
  document.body.style.overflow = '';
600
  untrapFocus(modal);
601
- if (modal._opener && typeof modal._opener.focus === 'function') {
602
- modal._opener.focus();
603
- }
604
- modal._opener = null;
605
  }
606
  };
607
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
608
  /* -------------------------------------------------------------
609
  ACCESS MODAL + INLINE FEEDBACK
610
  ------------------------------------------------------------- */
@@ -614,7 +692,18 @@
614
  const accessForm = document.getElementById('access-form');
615
  const accessFeedback = document.getElementById('access-feedback');
616
 
 
 
 
 
 
 
 
 
 
 
617
  function setAccessFeedback(kind, text) {
 
618
  accessFeedback.classList.remove('hidden');
619
  accessFeedback.classList.remove('border-red-500/30', 'bg-red-900/10', 'text-red-200');
620
  accessFeedback.classList.remove('border-emerald-500/30', 'bg-emerald-900/10', 'text-emerald-200');
@@ -631,7 +720,8 @@
631
  accessFeedback.textContent = text;
632
  }
633
 
634
- function clearAccessFeedback() {
 
635
  accessFeedback.textContent = '';
636
  accessFeedback.classList.add('hidden');
637
  accessFeedback.classList.remove(
@@ -641,40 +731,87 @@
641
  );
642
  }
643
 
644
- accessBtn.addEventListener('click', () => {
645
- clearAccessFeedback();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
646
  toggleModal(accessModal, true);
647
- setTimeout(() => document.getElementById('name').focus(), 50);
648
- });
 
649
 
650
- closeAccessModal.addEventListener('click', () => toggleModal(accessModal, false));
651
- accessModal.addEventListener('click', (e) => { if (e.target === accessModal) toggleModal(accessModal, false); });
 
 
652
 
653
- function isValidEmail(email) {
654
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
 
 
 
 
 
 
655
  }
656
 
657
- accessForm.addEventListener('submit', (e) => {
658
- e.preventDefault();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
659
 
660
- const name = document.getElementById('name').value.trim();
661
- const email = document.getElementById('email').value.trim();
662
- const institution = document.getElementById('institution').value.trim();
663
- const purpose = document.getElementById('purpose').value;
664
 
665
- if (!name || !email || !institution || !purpose) {
666
- setAccessFeedback('error', 'Please fill in all fields.');
667
- return;
668
- }
669
- if (!isValidEmail(email)) {
670
- setAccessFeedback('error', 'Please enter a valid email address.');
671
- return;
672
- }
673
 
674
- setAccessFeedback('success', 'Request received. You will be contacted after review.');
675
- accessForm.reset();
676
- setTimeout(() => toggleModal(accessModal, false), 900);
677
- });
 
 
 
 
 
 
 
 
 
 
678
 
679
  /* -------------------------------------------------------------
680
  LAB NAVIGATOR
@@ -683,26 +820,170 @@
683
  const labNavBtn = document.getElementById('lab-nav-btn');
684
  const labNavClose = document.getElementById('lab-nav-close');
685
 
686
- function openLabNav() { toggleModal(labNav, true); setTimeout(() => labNav.focus(), 0); }
687
- function closeLabNav() { toggleModal(labNav, false); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
688
 
689
- labNavBtn.addEventListener('click', openLabNav);
690
- labNavClose.addEventListener('click', closeLabNav);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
691
 
692
  labNav.addEventListener('click', (e) => {
693
  const shouldClose = e.target && e.target.getAttribute('data-lab-close') === 'true';
694
- if (shouldClose) closeLabNav();
695
  });
696
 
697
  document.querySelectorAll('.lab-node').forEach(btn => {
698
  btn.addEventListener('click', () => {
699
- const href = btn.getAttribute('data-nav');
700
- if (href) window.location.href = href;
701
  });
702
  });
703
 
704
  /* -------------------------------------------------------------
705
- DOSSIERS
706
  + Hash deep-linking (#mcap, #chai, etc.)
707
  + Active-card state (aria-pressed)
708
  + popstate handling for back/forward reliability
@@ -723,7 +1004,7 @@
723
  "Public-facing language should emphasize: a research principle, an evaluation harness, and transparent baselines. Avoid performance claims until replicated.",
724
  eval:
725
  "Evaluation focus: (1) identifiability assumptions, (2) interventional accuracy, (3) stability under distribution shift, (4) ablation against simpler baselines. Prefer preregistered protocols where possible.",
726
- primary: { label: "Request Access", action: () => accessBtn.click() },
727
  secondary: { label: "Open Console", action: () => { window.location.href = "chat.html"; } },
728
  updated: "β€”"
729
  },
@@ -739,10 +1020,10 @@
739
  "Planned: calibration and uncertainty reporting"
740
  ],
741
  public:
742
- "Public copy should emphasize methodology and evaluation (walk-forward, leakage prevention, calibration). Avoid any statement implying guaranteed returns or β€œhigh accuracy.”",
743
  eval:
744
  "Evaluation focus: strict temporal splits, realistic transaction cost modeling, sensitivity to slippage assumptions, and robustness across assets/regimes. Report uncertainty and failure modes.",
745
- primary: { label: "Request Access", action: () => accessBtn.click() },
746
  secondary: { label: "Open Console", action: () => { window.location.href = "chat.html"; } },
747
  updated: "β€”"
748
  },
@@ -761,7 +1042,7 @@
761
  "Public copy should focus on systems engineering (constraints, risk, audit trails). Do not imply edge without verification. Emphasize that this is research, not a trading service.",
762
  eval:
763
  "Evaluation focus: execution realism, latency budgets, out-of-sample stability, and adversarial conditions. If assumptions are not auditable, results are not meaningful.",
764
- primary: { label: "Request Access", action: () => accessBtn.click() },
765
  secondary: { label: "Open Console", action: () => { window.location.href = "chat.html"; } },
766
  updated: "β€”"
767
  },
@@ -770,7 +1051,7 @@
770
  subtitle: "Hypothesis β†’ Experiment β†’ Report",
771
  status: "PROTOTYPE",
772
  body:
773
- "The AI Scientist is the lab’s internal instrument: it standardizes experiments, manages baselines, logs assumptions, and produces concise research notes with uncertainty and reproducibility hooks.",
774
  evidence: [
775
  "Experiment templates (dataset β†’ protocol β†’ metrics)",
776
  "Baseline registry + ablation tracking",
@@ -799,7 +1080,7 @@
799
  "Public positioning: a governed agent platform for research ops and internal productivity. Avoid anthropomorphic claims; emphasize controls, accountability, and measurable outcomes.",
800
  eval:
801
  "Evaluation focus: error rates, containment failures avoided, auditability, and ROI in constrained workflows (data prep, experiments, reporting). Fail-closed behaviors are required.",
802
- primary: { label: "Request Access", action: () => accessBtn.click() },
803
  secondary: { label: "Contact", action: () => { window.location.href = "contact.html"; } },
804
  updated: "β€”"
805
  }
@@ -821,7 +1102,7 @@
821
  function setActiveCard(key) {
822
  programCards.forEach(btn => {
823
  const isMatch = btn.getAttribute('data-dossier') === key;
824
- btn.classList.toggle('is-active', isMatch);
825
  btn.setAttribute('aria-pressed', String(isMatch));
826
  });
827
  }
@@ -903,15 +1184,35 @@
903
  renderDossier(keyFromHash, { setHash: false, replaceHash: false, setActive: true });
904
  });
905
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
906
  /* -------------------------------------------------------------
907
  GLOBAL ESC BEHAVIOR
908
  ------------------------------------------------------------- */
909
  document.addEventListener('keydown', (e) => {
910
  if (e.key === 'Escape') {
911
- if (labNav && !labNav.classList.contains('modal-hidden')) closeLabNav();
912
- if (accessModal && !accessModal.classList.contains('modal-hidden')) toggleModal(accessModal, false);
913
  }
914
  });
 
 
 
915
  </script>
916
  </body>
917
- </html>
 
1
+ <!-- SILENTPATTERN FINAL BUILD: 2025-12-15 | pages: 10 | features: hash-deep-linking, lab-navigator, access-modal, form-validation, program-dossiers, active-card-states -->
2
  <!DOCTYPE html>
3
  <html lang="en">
4
  <head>
 
71
  .dot-proto { background: rgba(139,92,246,0.9); }
72
  .dot-validated { background: rgba(16,185,129,0.9); }
73
 
74
+ /* Subtle "bay" grid */
75
  .bay-grid {
76
  background-image:
77
  linear-gradient(rgba(148,163,184,0.06) 1px, transparent 1px),
 
81
  }
82
 
83
  /* Active card state (minimal, consistent with design) */
84
+ .program-card.active {
85
  border-color: rgba(99,102,241,0.55) !important;
86
  box-shadow: 0 0 0 1px rgba(99,102,241,0.22), 0 0 28px rgba(99,102,241,0.08);
87
  transform: translateY(-1px);
 
104
 
105
  <div class="flex items-center space-x-3">
106
  <button id="lab-nav-btn"
107
+ class="w-10 h-10 rounded-full border border-indigo-500/40 bg-gray-900/20 hover:bg-gray-900/40 backdrop-blur-sm transition flex items-center justify-center focus-ring"
108
  aria-label="Open Lab Navigator" title="Lab Navigator" aria-controls="lab-navigator" aria-haspopup="dialog">
109
  <i class="fas fa-asterisk text-indigo-300 text-sm"></i>
110
  </button>
111
 
112
  <button id="access-btn"
113
+ class="px-6 py-2 bg-gradient-to-r from-indigo-600 to-purple-600 rounded-full hover:opacity-90 transition focus-ring"
114
  aria-controls="access-modal" aria-haspopup="dialog">
115
  Access
116
  </button>
 
165
 
166
  <!-- MCAP -->
167
  <button type="button"
168
+ class="program-card text-left rounded-2xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/55 hover:bg-gray-900/45 transition p-5 conscious-element focus-ring"
169
  data-dossier="mcap" aria-label="Open dossier: MCAP" aria-pressed="false">
170
  <div class="flex items-start justify-between gap-4">
171
  <div>
 
185
 
186
  <!-- CHAI -->
187
  <button type="button"
188
+ class="program-card text-left rounded-2xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/55 hover:bg-gray-900/45 transition p-5 conscious-element focus-ring"
189
  data-dossier="chai" aria-label="Open dossier: CHAI" aria-pressed="false">
190
  <div class="flex items-start justify-between gap-4">
191
  <div>
 
205
 
206
  <!-- Quantum Lambda -->
207
  <button type="button"
208
+ class="program-card text-left rounded-2xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/55 hover:bg-gray-900/45 transition p-5 conscious-element focus-ring"
209
  data-dossier="quantum_lambda" aria-label="Open dossier: Quantum Lambda" aria-pressed="false">
210
  <div class="flex items-start justify-between gap-4">
211
  <div>
 
225
 
226
  <!-- AI Scientist -->
227
  <button type="button"
228
+ class="program-card text-left rounded-2xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/55 hover:bg-gray-900/45 transition p-5 conscious-element focus-ring"
229
  data-dossier="ai_scientist" aria-label="Open dossier: AI Scientist" aria-pressed="false">
230
  <div class="flex items-start justify-between gap-4">
231
  <div>
 
245
 
246
  <!-- Agentic Workforce -->
247
  <button type="button"
248
+ class="program-card text-left rounded-2xl border border-gray-800 bg-gray-900/30 hover:border-indigo-500/55 hover:bg-gray-900/45 transition p-5 conscious-element focus-ring md:col-span-2"
249
  data-dossier="agentic_workforce" aria-label="Open dossier: Agentic Workforce" aria-pressed="false">
250
  <div class="flex items-start justify-between gap-4">
251
  <div>
 
255
  <span class="badge"><span class="dot dot-concept"></span>Concept</span>
256
  </div>
257
  <p class="text-sm text-gray-300 mt-4 leading-relaxed">
258
+ "AI employees" as controlled agents: scoped permissions, logging, approval gates, and outcome verification.
259
  </p>
260
  <div class="mt-4 text-xs text-gray-500 flex items-center gap-2">
261
  <i class="fas fa-key"></i>
 
313
 
314
  <div class="flex flex-col gap-3">
315
  <button id="dossier-primary"
316
+ class="px-5 py-3 rounded-xl bg-gradient-to-r from-indigo-600 to-purple-600 hover:opacity-90 transition focus-ring">
317
  Request Access
318
  </button>
319
  <button id="dossier-secondary"
320
+ class="px-5 py-3 rounded-xl border border-gray-700 bg-gray-900/20 hover:bg-gray-900/35 transition focus-ring">
321
  Open Console
322
  </button>
323
  </div>
 
400
  <h3 class="text-xl font-bold" id="access-modal-title">Request Access</h3>
401
  <p class="text-gray-400 mt-1">Curated access for research and evaluation</p>
402
  </div>
403
+ <button id="close-access-modal" class="text-gray-400 hover:text-white focus-ring" aria-label="Close">
404
  <i class="fas fa-times"></i>
405
  </button>
406
  </div>
 
413
  <div>
414
  <label for="name" class="block text-sm font-medium mb-1">Full Name</label>
415
  <input type="text" id="name" class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus-ring" autocomplete="name">
416
+ <p id="name-error" class="hidden mt-1 text-xs text-red-300">Please enter your full name.</p>
417
  </div>
418
  <div>
419
  <label for="email" class="block text-sm font-medium mb-1">Email</label>
420
  <input type="email" id="email" class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus-ring" autocomplete="email">
421
+ <p id="email-error" class="hidden mt-1 text-xs text-red-300">Please enter a valid email address.</p>
422
  </div>
423
  <div>
424
  <label for="institution" class="block text-sm font-medium mb-1">Institution/Organization</label>
425
  <input type="text" id="institution" class="w-full bg-gray-800/50 border border-gray-700 rounded-lg px-4 py-2 focus-ring" autocomplete="organization">
426
+ <p id="institution-error" class="hidden mt-1 text-xs text-red-300">Please enter your institution/organization.</p>
427
  </div>
428
  <div>
429
  <label for="purpose" class="block text-sm font-medium mb-1">Purpose</label>
 
434
  <option value="partnership">Partnership</option>
435
  <option value="other">Other</option>
436
  </select>
437
+ <p id="purpose-error" class="hidden mt-1 text-xs text-red-300">Please select a purpose.</p>
438
  </div>
439
  <div class="pt-2">
440
+ <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">
441
  Submit Request
442
  </button>
443
  </div>
 
468
  </div>
469
 
470
  <button id="lab-nav-close"
471
+ 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"
472
  aria-label="Close Lab Navigator">
473
  <i class="fas fa-times text-gray-300 text-sm"></i>
474
  </button>
 
480
  radial-gradient(circle at 70% 70%, rgba(236,72,153,0.10), transparent 50%);"></div>
481
 
482
  <div class="relative grid grid-cols-1 sm:grid-cols-2 gap-3">
483
+ <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"
484
+ data-dossier="start" aria-current="false">
485
  <div class="text-sm text-gray-200 font-medium">Start Here</div>
486
  <div class="text-xs text-gray-500 mt-1">Entry interface</div>
487
  </button>
488
 
489
+ <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"
490
+ data-dossier="programs" aria-current="false">
491
  <div class="text-sm text-gray-200 font-medium">Programs</div>
492
  <div class="text-xs text-gray-500 mt-1">This page</div>
493
  </button>
494
 
495
+ <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"
496
+ data-dossier="console" aria-current="false">
497
  <div class="text-sm text-gray-200 font-medium">Console</div>
498
  <div class="text-xs text-gray-500 mt-1">Controlled chat</div>
499
  </button>
500
 
501
+ <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"
502
+ data-dossier="research" aria-current="false">
503
  <div class="text-sm text-gray-200 font-medium">Research</div>
504
  <div class="text-xs text-gray-500 mt-1">Notes and briefs</div>
505
  </button>
506
 
507
+ <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 sm:col-span-2"
508
+ data-dossier="access" aria-current="false">
509
+ <div class="text-sm text-gray-200 font-medium">Access</div>
510
+ <div class="text-xs text-gray-500 mt-1">Curated entry</div>
511
  </button>
512
  </div>
513
 
 
519
 
520
  <div class="relative rounded-2xl border border-gray-800 bg-gray-900/30 overflow-hidden">
521
  <div class="px-6 py-5 border-b border-gray-800/60">
522
+ <div class="flex items-start justify-between gap-4">
523
+ <div>
524
+ <div id="lab-dossier-title" class="text-lg font-semibold text-gray-100">Lab Dossier</div>
525
+ <div id="lab-dossier-subtitle" class="text-xs text-gray-500 mt-1">Select a node to load details.</div>
526
+ </div>
527
+ <div id="lab-dossier-status"
528
+ class="text-xs px-2.5 py-1 rounded-full border border-indigo-500/30 text-indigo-200 bg-indigo-900/15">
529
+ READY
530
+ </div>
531
+ </div>
532
  </div>
533
+
534
+ <div class="p-6 space-y-5 max-h-[560px] overflow-auto thin-scroll">
535
+ <div id="lab-dossier-body" class="text-sm text-gray-300 leading-relaxed">
536
+ This interface reveals SILENTPATTERN as a set of research programs and operational systems.
537
+ The public layer is minimal by design; depth is opened intentionally.
538
+ </div>
539
+
540
+ <div class="rounded-xl border border-gray-800 bg-black/20 p-4">
541
+ <div class="text-xs text-gray-400 uppercase tracking-wider mb-2">Evidence Capsule</div>
542
+ <ul id="lab-dossier-evidence" class="text-sm text-gray-300 space-y-1">
543
+ <li class="text-gray-500">No dossier selected.</li>
544
+ </ul>
545
+ </div>
546
+
547
+ <div class="flex flex-col sm:flex-row gap-3">
548
+ <button id="lab-dossier-primary"
549
+ 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">
550
+ Open
551
+ </button>
552
+ <button id="lab-dossier-secondary"
553
+ 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">
554
+ View Note
555
+ </button>
556
+ </div>
557
+
558
+ <div id="lab-dossier-meta" class="text-xs text-gray-500">
559
+ Last updated: <span class="text-gray-300">β€”</span>
560
+ </div>
561
  </div>
562
  </div>
563
 
 
566
  </div>
567
 
568
  <script>
569
+ // Site-wide configuration
570
+ const CONFIG = {
571
+ MODAL_HASHES: new Set(['lab', 'access']),
572
+ DOSSIER_HASHES: new Set(['mcap', 'chai', 'quantum_lambda', 'ai_scientist', 'agentic_workforce'])
573
+ };
574
+
575
  /* -------------------------------------------------------------
576
+ UTILITY FUNCTIONS (consistent with index.html)
577
  ------------------------------------------------------------- */
578
+ function escapeHtml(str) {
579
+ return String(str)
580
+ .replaceAll('&', '&amp;')
581
+ .replaceAll('<', '&lt;')
582
+ .replaceAll('>', '&gt;')
583
+ .replaceAll('"', '&quot;')
584
+ .replaceAll("'", '&#039;');
585
+ }
586
+
587
+ function isValidEmail(email) {
588
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
589
+ }
590
+
591
+ function currentHashKey() {
592
+ const h = (window.location.hash || '').replace('#', '').trim();
593
+ return h;
594
+ }
595
+
596
+ function setHash(key, replace = false) {
597
+ if (!key) return;
598
+ if (window.location.hash.replace('#', '') === key) return;
599
+ if (replace) {
600
+ history.replaceState(null, '', '#' + key);
601
+ } else {
602
+ history.pushState(null, '', '#' + key);
603
+ }
604
+ }
605
+
606
+ function clearHashIf(key) {
607
+ const h = currentHashKey();
608
+ if (!h) return;
609
+ if (!key || h === key) {
610
+ history.replaceState(null, '', window.location.pathname + window.location.search);
611
  }
 
 
612
  }
 
 
 
613
 
614
  /* -------------------------------------------------------------
615
+ MODAL HELPERS (consistent with index.html)
616
  ------------------------------------------------------------- */
617
  function trapFocus(modal) {
618
  const focusable = modal.querySelectorAll('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');
 
642
 
643
  const toggleModal = (modal, show) => {
644
  if (show) {
 
645
  modal.classList.remove('modal-hidden');
646
  modal.classList.add('modal-visible');
647
  document.body.style.overflow = 'hidden';
 
651
  modal.classList.add('modal-hidden');
652
  document.body.style.overflow = '';
653
  untrapFocus(modal);
 
 
 
 
654
  }
655
  };
656
 
657
+ /* -------------------------------------------------------------
658
+ VANTA BACKGROUND (guarded)
659
+ ------------------------------------------------------------- */
660
+ let vantaEffect = null;
661
+ try {
662
+ if (window.VANTA && typeof VANTA.NET === 'function') {
663
+ vantaEffect = VANTA.NET({
664
+ el: "#vanta-bg",
665
+ mouseControls: true,
666
+ touchControls: true,
667
+ gyroControls: false,
668
+ minHeight: 200.00,
669
+ minWidth: 200.00,
670
+ scale: 1.00,
671
+ scaleMobile: 1.00,
672
+ color: 0x4f46e5,
673
+ backgroundColor: 0x020617,
674
+ points: 12.00,
675
+ maxDistance: 20.00,
676
+ spacing: 15.00
677
+ });
678
+ }
679
+ } catch (_) {
680
+ vantaEffect = null;
681
+ }
682
+ window.addEventListener('resize', () => {
683
+ if (vantaEffect && typeof vantaEffect.resize === 'function') vantaEffect.resize();
684
+ });
685
+
686
  /* -------------------------------------------------------------
687
  ACCESS MODAL + INLINE FEEDBACK
688
  ------------------------------------------------------------- */
 
692
  const accessForm = document.getElementById('access-form');
693
  const accessFeedback = document.getElementById('access-feedback');
694
 
695
+ const nameEl = document.getElementById('name');
696
+ const emailEl = document.getElementById('email');
697
+ const institutionEl = document.getElementById('institution');
698
+ const purposeEl = document.getElementById('purpose');
699
+
700
+ const nameErr = document.getElementById('name-error');
701
+ const emailErr = document.getElementById('email-error');
702
+ const institutionErr = document.getElementById('institution-error');
703
+ const purposeErr = document.getElementById('purpose-error');
704
+
705
  function setAccessFeedback(kind, text) {
706
+ if (!accessFeedback) return;
707
  accessFeedback.classList.remove('hidden');
708
  accessFeedback.classList.remove('border-red-500/30', 'bg-red-900/10', 'text-red-200');
709
  accessFeedback.classList.remove('border-emerald-500/30', 'bg-emerald-900/10', 'text-emerald-200');
 
720
  accessFeedback.textContent = text;
721
  }
722
 
723
+ function hideAccessFeedback() {
724
+ if (!accessFeedback) return;
725
  accessFeedback.textContent = '';
726
  accessFeedback.classList.add('hidden');
727
  accessFeedback.classList.remove(
 
731
  );
732
  }
733
 
734
+ function setFieldError(inputEl, errorEl, isError) {
735
+ if (!inputEl || !errorEl) return;
736
+ if (isError) {
737
+ errorEl.classList.remove('hidden');
738
+ inputEl.setAttribute('aria-invalid', 'true');
739
+ inputEl.classList.add('border-red-500/60');
740
+ } else {
741
+ errorEl.classList.add('hidden');
742
+ inputEl.removeAttribute('aria-invalid');
743
+ inputEl.classList.remove('border-red-500/60');
744
+ }
745
+ }
746
+
747
+ function resetAccessErrors() {
748
+ hideAccessFeedback();
749
+ setFieldError(nameEl, nameErr, false);
750
+ setFieldError(emailEl, emailErr, false);
751
+ setFieldError(institutionEl, institutionErr, false);
752
+ setFieldError(purposeEl, purposeErr, false);
753
+ }
754
+
755
+ function openAccessModal(setHashFlag = true) {
756
+ resetAccessErrors();
757
  toggleModal(accessModal, true);
758
+ if (setHashFlag) setHash('access');
759
+ setTimeout(() => nameEl && nameEl.focus(), 80);
760
+ }
761
 
762
+ function closeAccessModal(clearHashFlag = true) {
763
+ toggleModal(accessModal, false);
764
+ if (clearHashFlag) clearHashIf('access');
765
+ }
766
 
767
+ accessBtn.addEventListener('click', () => openAccessModal(true));
768
+
769
+ if (closeAccessModal) closeAccessModal.addEventListener('click', () => closeAccessModal(true));
770
+
771
+ if (accessModal) {
772
+ accessModal.addEventListener('click', (e) => {
773
+ if (e.target === accessModal) closeAccessModal(true);
774
+ });
775
  }
776
 
777
+ if (accessForm) {
778
+ // Clear per-field errors on input
779
+ [nameEl, emailEl, institutionEl, purposeEl].forEach(el => {
780
+ if (!el) return;
781
+ el.addEventListener('input', () => {
782
+ if (el === nameEl) setFieldError(nameEl, nameErr, !nameEl.value.trim());
783
+ if (el === emailEl) setFieldError(emailEl, emailErr, !isValidEmail(emailEl.value.trim()));
784
+ if (el === institutionEl) setFieldError(institutionEl, institutionErr, !institutionEl.value.trim());
785
+ if (el === purposeEl) setFieldError(purposeEl, purposeErr, !purposeEl.value);
786
+ });
787
+ el.addEventListener('change', () => el.dispatchEvent(new Event('input')));
788
+ });
789
+
790
+ accessForm.addEventListener('submit', (e) => {
791
+ e.preventDefault();
792
+ resetAccessErrors();
793
 
794
+ const name = (nameEl?.value || '').trim();
795
+ const email = (emailEl?.value || '').trim();
796
+ const institution = (institutionEl?.value || '').trim();
797
+ const purpose = (purposeEl?.value || '').trim();
798
 
799
+ let ok = true;
 
 
 
 
 
 
 
800
 
801
+ if (!name) { setFieldError(nameEl, nameErr, true); ok = false; }
802
+ if (!email || !isValidEmail(email)) { setFieldError(emailEl, emailErr, true); ok = false; }
803
+ if (!institution) { setFieldError(institutionEl, institutionErr, true); ok = false; }
804
+ if (!purpose) { setFieldError(purposeEl, purposeErr, true); ok = false; }
805
+
806
+ if (!ok) {
807
+ setAccessFeedback('error', 'Please correct the highlighted fields and resubmit.');
808
+ return;
809
+ }
810
+
811
+ setAccessFeedback('success', 'Request received. You will be contacted after review.');
812
+ accessForm.reset();
813
+ });
814
+ }
815
 
816
  /* -------------------------------------------------------------
817
  LAB NAVIGATOR
 
820
  const labNavBtn = document.getElementById('lab-nav-btn');
821
  const labNavClose = document.getElementById('lab-nav-close');
822
 
823
+ const LAB_DOSSIERS = {
824
+ start: {
825
+ title: "Start Here",
826
+ subtitle: "Entry interface",
827
+ status: "ACTIVE",
828
+ body: "Return to the main interface.",
829
+ evidence: ["Public entry layer", "Programs as dossiers", "Console for controlled interaction"],
830
+ primary: { label: "Go to Index", action: () => { window.location.href = "index.html"; } },
831
+ secondary: { label: "Programs", action: () => { window.location.href = "capabilities.html"; } },
832
+ updated: "β€”"
833
+ },
834
+ programs: {
835
+ title: "Programs",
836
+ subtitle: "This page",
837
+ status: "ACTIVE",
838
+ body: "Program Bay: MCAP, CHAI, Quantum Lambda, AI Scientist, Agentic Workforce.",
839
+ evidence: ["Dossiers with maturity levels", "Evidence capsules", "Access gates"],
840
+ primary: { label: "Close Navigator", action: () => closeLabNav(true) },
841
+ secondary: { label: "View Note", action: () => {
842
+ // Demo note viewer
843
+ const modal = document.createElement('div');
844
+ modal.className = 'fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm modal modal-visible';
845
+ modal.innerHTML = `
846
+ <div class="bg-gray-900/90 border border-gray-800 rounded-xl max-w-2xl w-full mx-4 relative overflow-hidden">
847
+ <div class="absolute inset-x-0 top-0 h-1 bg-gradient-to-r from-indigo-600 to-purple-600"></div>
848
+ <div class="p-6">
849
+ <div class="flex justify-between items-start mb-6">
850
+ <h3 class="text-xl font-bold">Program Technical Note</h3>
851
+ <button class="text-gray-400 hover:text-white close-note-viewer focus-ring">
852
+ <i class="fas fa-times"></i>
853
+ </button>
854
+ </div>
855
+ <p class="text-gray-300 mb-4">Technical notes contain evaluation protocols, assumptions, and evidence capsules. Available to qualified researchers.</p>
856
+ <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">
857
+ Close
858
+ </button>
859
+ </div>
860
+ </div>
861
+ `;
862
+ document.body.appendChild(modal);
863
+
864
+ const closeBtn = modal.querySelector('.close-note-viewer');
865
+ closeBtn.addEventListener('click', () => {
866
+ toggleModal(modal, false);
867
+ setTimeout(() => modal.remove(), 300);
868
+ });
869
+ modal.addEventListener('click', (e) => {
870
+ if (e.target === modal) {
871
+ toggleModal(modal, false);
872
+ setTimeout(() => modal.remove(), 300);
873
+ }
874
+ });
875
+ toggleModal(modal, true);
876
+ } },
877
+ updated: "β€”"
878
+ },
879
+ console: {
880
+ title: "Console",
881
+ subtitle: "Controlled chat",
882
+ status: "DRAFT",
883
+ body: "Controlled chat with exportable transcripts. Model access must remain server-side.",
884
+ evidence: ["No client-side secrets", "Audit-ready transcripts", "Fail-closed behaviors"],
885
+ primary: { label: "Open Console", action: () => { window.location.href = "chat.html"; } },
886
+ secondary: { label: "Research", action: () => { window.location.href = "research.html"; } },
887
+ updated: "β€”"
888
+ },
889
+ research: {
890
+ title: "Research",
891
+ subtitle: "Notes and briefs",
892
+ status: "DRAFT",
893
+ body: "Technical notes, evaluation methodology, and changelogs.",
894
+ evidence: ["Evaluation philosophy", "Benchmarks + baselines", "Limitations and failure modes"],
895
+ primary: { label: "Open Research", action: () => { window.location.href = "research.html"; } },
896
+ secondary: { label: "Contact", action: () => { window.location.href = "contact.html"; } },
897
+ updated: "β€”"
898
+ },
899
+ access: {
900
+ title: "Access",
901
+ subtitle: "Curated entry",
902
+ status: "ACTIVE",
903
+ body: "Request access for controlled demos and evaluation workflows.",
904
+ evidence: ["Application-based", "Segmented by intent", "Controlled demos"],
905
+ primary: { label: "Request Access", action: () => { closeLabNav(true); openAccessModal(true); } },
906
+ secondary: { label: "Contact", action: () => { window.location.href = "contact.html"; } },
907
+ updated: "β€”"
908
+ }
909
+ };
910
+
911
+ const labDossierTitle = document.getElementById('lab-dossier-title');
912
+ const labDossierSubtitle = document.getElementById('lab-dossier-subtitle');
913
+ const labDossierStatus = document.getElementById('lab-dossier-status');
914
+ const labDossierBody = document.getElementById('lab-dossier-body');
915
+ const labDossierEvidence = document.getElementById('lab-dossier-evidence');
916
+ const labDossierPrimary = document.getElementById('lab-dossier-primary');
917
+ const labDossierSecondary = document.getElementById('lab-dossier-secondary');
918
+ const labDossierMeta = document.getElementById('lab-dossier-meta');
919
+
920
+ function setActiveLabNode(key) {
921
+ document.querySelectorAll('.lab-node').forEach(btn => {
922
+ const isActive = btn.getAttribute('data-dossier') === key;
923
+ btn.classList.toggle('active', isActive);
924
+ btn.setAttribute('aria-current', isActive ? 'true' : 'false');
925
+ });
926
+ }
927
+
928
+ function renderLabDossier(key) {
929
+ const d = LAB_DOSSIERS[key];
930
+ if (!d) return;
931
+
932
+ setActiveLabNode(key);
933
 
934
+ labDossierTitle.textContent = d.title;
935
+ labDossierSubtitle.textContent = d.subtitle;
936
+ labDossierStatus.textContent = d.status;
937
+ labDossierBody.textContent = d.body;
938
+
939
+ labDossierEvidence.innerHTML = "";
940
+ d.evidence.forEach(item => {
941
+ const li = document.createElement('li');
942
+ li.textContent = item;
943
+ labDossierEvidence.appendChild(li);
944
+ });
945
+
946
+ labDossierPrimary.textContent = d.primary.label;
947
+ labDossierPrimary.onclick = d.primary.action;
948
+
949
+ labDossierSecondary.textContent = d.secondary.label;
950
+ labDossierSecondary.onclick = d.secondary.action;
951
+
952
+ labDossierMeta.innerHTML = `Last updated: <span class="text-gray-300">${d.updated}</span>`;
953
+ }
954
+
955
+ function openLabNav(setHashFlag = true) {
956
+ toggleModal(labNav, true);
957
+ if (setHashFlag) setHash('lab');
958
+ setTimeout(() => labNav.focus(), 0);
959
+
960
+ // Ensure a stable default selection when opened
961
+ const alreadyActive = document.querySelector('.lab-node.active');
962
+ if (!alreadyActive) renderLabDossier('programs');
963
+ }
964
+
965
+ function closeLabNav(clearHashFlag = true) {
966
+ toggleModal(labNav, false);
967
+ if (clearHashFlag) clearHashIf('lab');
968
+ }
969
+
970
+ labNavBtn.addEventListener('click', () => openLabNav(true));
971
+ labNavClose.addEventListener('click', () => closeLabNav(true));
972
 
973
  labNav.addEventListener('click', (e) => {
974
  const shouldClose = e.target && e.target.getAttribute('data-lab-close') === 'true';
975
+ if (shouldClose) closeLabNav(true);
976
  });
977
 
978
  document.querySelectorAll('.lab-node').forEach(btn => {
979
  btn.addEventListener('click', () => {
980
+ const key = btn.getAttribute('data-dossier');
981
+ renderLabDossier(key);
982
  });
983
  });
984
 
985
  /* -------------------------------------------------------------
986
+ PROGRAM DOSSIERS
987
  + Hash deep-linking (#mcap, #chai, etc.)
988
  + Active-card state (aria-pressed)
989
  + popstate handling for back/forward reliability
 
1004
  "Public-facing language should emphasize: a research principle, an evaluation harness, and transparent baselines. Avoid performance claims until replicated.",
1005
  eval:
1006
  "Evaluation focus: (1) identifiability assumptions, (2) interventional accuracy, (3) stability under distribution shift, (4) ablation against simpler baselines. Prefer preregistered protocols where possible.",
1007
+ primary: { label: "Request Access", action: () => openAccessModal(true) },
1008
  secondary: { label: "Open Console", action: () => { window.location.href = "chat.html"; } },
1009
  updated: "β€”"
1010
  },
 
1020
  "Planned: calibration and uncertainty reporting"
1021
  ],
1022
  public:
1023
+ "Public copy should emphasize methodology and evaluation (walk-forward, leakage prevention, calibration). Avoid any statement implying guaranteed returns or 'high accuracy.'",
1024
  eval:
1025
  "Evaluation focus: strict temporal splits, realistic transaction cost modeling, sensitivity to slippage assumptions, and robustness across assets/regimes. Report uncertainty and failure modes.",
1026
+ primary: { label: "Request Access", action: () => openAccessModal(true) },
1027
  secondary: { label: "Open Console", action: () => { window.location.href = "chat.html"; } },
1028
  updated: "β€”"
1029
  },
 
1042
  "Public copy should focus on systems engineering (constraints, risk, audit trails). Do not imply edge without verification. Emphasize that this is research, not a trading service.",
1043
  eval:
1044
  "Evaluation focus: execution realism, latency budgets, out-of-sample stability, and adversarial conditions. If assumptions are not auditable, results are not meaningful.",
1045
+ primary: { label: "Request Access", action: () => openAccessModal(true) },
1046
  secondary: { label: "Open Console", action: () => { window.location.href = "chat.html"; } },
1047
  updated: "β€”"
1048
  },
 
1051
  subtitle: "Hypothesis β†’ Experiment β†’ Report",
1052
  status: "PROTOTYPE",
1053
  body:
1054
+ "The AI Scientist is the lab's internal instrument: it standardizes experiments, manages baselines, logs assumptions, and produces concise research notes with uncertainty and reproducibility hooks.",
1055
  evidence: [
1056
  "Experiment templates (dataset β†’ protocol β†’ metrics)",
1057
  "Baseline registry + ablation tracking",
 
1080
  "Public positioning: a governed agent platform for research ops and internal productivity. Avoid anthropomorphic claims; emphasize controls, accountability, and measurable outcomes.",
1081
  eval:
1082
  "Evaluation focus: error rates, containment failures avoided, auditability, and ROI in constrained workflows (data prep, experiments, reporting). Fail-closed behaviors are required.",
1083
+ primary: { label: "Request Access", action: () => openAccessModal(true) },
1084
  secondary: { label: "Contact", action: () => { window.location.href = "contact.html"; } },
1085
  updated: "β€”"
1086
  }
 
1102
  function setActiveCard(key) {
1103
  programCards.forEach(btn => {
1104
  const isMatch = btn.getAttribute('data-dossier') === key;
1105
+ btn.classList.toggle('active', isMatch);
1106
  btn.setAttribute('aria-pressed', String(isMatch));
1107
  });
1108
  }
 
1184
  renderDossier(keyFromHash, { setHash: false, replaceHash: false, setActive: true });
1185
  });
1186
 
1187
+ /* -------------------------------------------------------------
1188
+ HASH ROUTER: handle modal hashes too
1189
+ ------------------------------------------------------------- */
1190
+ function applyHashState() {
1191
+ const key = currentHashKey();
1192
+
1193
+ if (CONFIG.MODAL_HASHES.has(key)) {
1194
+ if (key === 'lab') openLabNav(false);
1195
+ if (key === 'access') openAccessModal(false);
1196
+ } else if (CONFIG.DOSSIER_HASHES.has(key)) {
1197
+ // Already handled by hashchange/popstate above
1198
+ }
1199
+ }
1200
+
1201
+ window.addEventListener('hashchange', applyHashState);
1202
+ applyHashState(); // Initial load
1203
+
1204
  /* -------------------------------------------------------------
1205
  GLOBAL ESC BEHAVIOR
1206
  ------------------------------------------------------------- */
1207
  document.addEventListener('keydown', (e) => {
1208
  if (e.key === 'Escape') {
1209
+ if (labNav && !labNav.classList.contains('modal-hidden')) closeLabNav(true);
1210
+ if (accessModal && !accessModal.classList.contains('modal-hidden')) closeAccessModal(true);
1211
  }
1212
  });
1213
+
1214
+ // Initial lab dossier render
1215
+ renderLabDossier('programs');
1216
  </script>
1217
  </body>
1218
+ </html>