File size: 27,329 Bytes
7500ff7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quillan-Ronin v5.4.0 ONI — AAA 3D EvoMoE Neural Architecture Canvas</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Orbitron:wght@400;600;700;900&family=Cinzel:wght@700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{
  background:#020408;overflow:hidden;font-family:'JetBrains Mono',monospace;
  color:#ccc;width:100vw;height:100vh;user-select:none;
}
#webgl-container{position:absolute;inset:0;width:100%;height:100%;z-index:1}

/* Sci-Fi HUD Header */
#hud-header{
  position:fixed;top:0;left:0;right:0;display:flex;align-items:center;justify-content:space-between;
  padding:12px 24px;background:linear-gradient(180deg,rgba(4,8,18,0.95) 0%,rgba(4,8,18,0.7) 80%,transparent 100%);
  pointer-events:auto;z-index:20;border-bottom:1px solid rgba(0,240,255,0.2);backdrop-filter:blur(14px);
  transition:transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.35s ease;
}
#hud-header h1{
  font-family:'Orbitron',monospace;font-size:13.5px;font-weight:900;
  color:#ffd700;letter-spacing:1.8px;text-shadow:0 0 15px rgba(255,215,0,0.5);display:flex;align-items:center;gap:8px;
}
#hud-header .sub{font-size:9.5px;color:#00f0ff;letter-spacing:1.2px;margin-top:2px}

/* Left & Right Sci-Fi Telemetry Sidebars */
#left-panel{
  position:fixed;left:16px;top:65px;bottom:62px;width:230px;
  background:rgba(4,8,18,0.85);border:1px solid rgba(0,240,255,0.25);border-radius:10px;
  padding:14px;overflow-y:auto;pointer-events:auto;z-index:15;backdrop-filter:blur(14px);
  box-shadow:0 0 30px rgba(0,240,255,0.12);transition:transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.35s ease;
}
#right-panel{
  position:fixed;right:16px;top:65px;bottom:62px;width:245px;
  background:rgba(4,8,18,0.85);border:1px solid rgba(255,215,0,0.25);border-radius:10px;
  padding:14px;overflow-y:auto;pointer-events:auto;z-index:15;backdrop-filter:blur(14px);
  box-shadow:0 0 30px rgba(255,215,0,0.12);transition:transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.35s ease;
}

/* Hidden States for Panels */
.hud-hidden #left-panel{transform:translateX(-270px);opacity:0;pointer-events:none;}
.hud-hidden #right-panel{transform:translateX(280px);opacity:0;pointer-events:none;}
.hud-hidden #hud-header{transform:translateY(-90px);opacity:0;pointer-events:none;}

.panel-header-row{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;padding-bottom:5px;border-bottom:1px solid rgba(255,255,255,0.08);}
.panel-title{
  font-family:'Orbitron',monospace;font-size:10.5px;letter-spacing:1.5px;
  color:#ffd700;text-transform:uppercase;font-weight:700;
}

.stage-btn{
  display:flex;align-items:center;gap:9px;margin-bottom:6px;cursor:pointer;
  padding:8px 10px;border-radius:6px;border:1px solid transparent;background:rgba(255,255,255,0.02);
  transition:all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.stage-btn:hover{border-color:#00f0ff;background:rgba(0,240,255,0.12);transform:translateX(4px);}
.stage-btn.active{border-color:#ffd700;background:rgba(255,215,0,0.12);box-shadow:0 0 12px rgba(255,215,0,0.25);}
.stage-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0;box-shadow:0 0 8px currentColor;}
.stage-name{font-size:10px;color:#fff;font-weight:600;}

.stat-row{
  display:flex;justify-content:space-between;align-items:center;
  margin-bottom:8px;padding:4px 0;border-bottom:1px solid rgba(255,255,255,0.04);
}
.stat-label{font-size:9.5px;color:#94a3b8}
.stat-val{font-family:'Orbitron',monospace;font-size:11px;font-weight:700;color:#00f0ff}

/* Bottom Control Bar */
#hud-footer{
  position:fixed;bottom:0;left:0;right:0;display:flex;align-items:center;justify-content:center;
  gap:10px;padding:9px 18px;background:linear-gradient(0deg,rgba(4,8,18,0.95) 0%,rgba(4,8,18,0.7) 80%,transparent 100%);
  pointer-events:auto;z-index:20;border-top:1px solid rgba(0,240,255,0.2);backdrop-filter:blur(14px);
  flex-wrap:wrap;
}
.btn-control{
  background:rgba(10,20,38,0.9);border:1px solid rgba(0,240,255,0.35);color:#00f0ff;
  padding:6px 13px;font-family:'JetBrains Mono',monospace;font-size:10.5px;font-weight:700;cursor:pointer;
  border-radius:5px;transition:all 0.25s cubic-bezier(0.16, 1, 0.3, 1);display:flex;align-items:center;gap:6px;
}
.btn-control:hover{background:#00f0ff;color:#040712;box-shadow:0 0 16px rgba(0,240,255,0.6);transform:translateY(-1px);}
.btn-control.active{background:rgba(255,215,0,0.2);border-color:#ffd700;color:#ffd700;box-shadow:0 0 12px rgba(255,215,0,0.3);}

/* Floating Toggle HUD Icon */
#hud-toggle-floating{
  position:fixed;top:12px;right:16px;z-index:30;background:rgba(4,8,18,0.85);
  border:1px solid var(--accent-cyan,#00f0ff);color:#00f0ff;padding:6px 13px;border-radius:6px;
  cursor:pointer;font-family:'JetBrains Mono';font-size:11px;font-weight:700;display:flex;align-items:center;gap:6px;
  backdrop-filter:blur(10px);transition:all 0.25s ease;box-shadow:0 0 15px rgba(0,240,255,0.2);
}
#hud-toggle-floating:hover{background:#00f0ff;color:#000;box-shadow:0 0 22px #00f0ff;}

/* Node Tooltip */
#node-tooltip{
  position:fixed;display:none;background:rgba(4,8,18,0.95);border:1px solid #00f0ff;
  padding:12px 16px;border-radius:8px;font-family:'JetBrains Mono';font-size:11px;color:#fff;
  pointer-events:none;z-index:50;box-shadow:0 0 30px rgba(0,240,255,0.4);backdrop-filter:blur(12px);
  max-width:260px;line-height:1.45;
}
#node-tooltip h4{font-family:'Orbitron';color:#ffd700;font-size:12px;margin-bottom:5px;display:flex;align-items:center;gap:6px;}

@media (max-width:850px){
  #left-panel{display:none;}
  #right-panel{display:none;}
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
</head>
<body>

<button id="hud-toggle-floating" onclick="toggleHUD()" title="Toggle Telemetry HUD">
  <span id="hud-toggle-icon">👁️</span> <span id="hud-toggle-text">HUD</span>
</button>

<div id="hud-header">
  <div>
    <h1>👑 QUILLAN-RONIN v5.4.0 ONI · 3D SYNAPSE CANVAS</h1>
    <div class="sub">34-COUNCIL EvoMoE · BITNET 1.58b STE · VECTORIZED INDEX_ADD_ GRAPH</div>
  </div>
  <div style="font-size:10.5px; color:#ffd700; font-family:'Orbitron'; padding-right:85px;">
    [3D ORBIT & HOLOGRAPHIC RAYCAST ACTIVE]
  </div>
</div>

<div id="left-panel">
  <div class="panel-header-row">
    <div class="panel-title">Architectural Layers</div>
  </div>
  <div class="stage-btn" onclick="focusLayer(0)"><span class="stage-dot" style="background:#ffd700; color:#ffd700;"></span><span class="stage-name">1. Dual Ingest Bridge</span></div>
  <div class="stage-btn" onclick="focusLayer(1)"><span class="stage-dot" style="background:#ff0055; color:#ff0055;"></span><span class="stage-name">2. 9-Vector Prism</span></div>
  <div class="stage-btn" onclick="focusLayer(2)"><span class="stage-dot" style="background:#00f0ff; color:#00f0ff;"></span><span class="stage-name">3. Complexity Router</span></div>
  <div class="stage-btn" onclick="focusLayer(3)"><span class="stage-dot" style="background:#00ff88; color:#00ff88;"></span><span class="stage-name">4. Top-4 Sparse Gating</span></div>
  <div class="stage-btn" onclick="focusLayer(4)"><span class="stage-dot" style="background:#a855f7; color:#a855f7;"></span><span class="stage-name">5. 34-Council Swarms</span></div>
  <div class="stage-btn" onclick="focusLayer(5)"><span class="stage-dot" style="background:#3a86ff; color:#3a86ff;"></span><span class="stage-name">6. Flash Diffusion Core</span></div>
  <div class="stage-btn" onclick="focusLayer(6)"><span class="stage-dot" style="background:#ffd700; color:#ffd700;"></span><span class="stage-name">7. Sovereign Head</span></div>
</div>

<div id="right-panel">
  <div class="panel-header-row">
    <div class="panel-title">Live Model Telemetry</div>
  </div>
  <div class="stat-row"><span class="stat-label">Throughput:</span><span class="stat-val" id="tele-flops">251.40 GFLOPS</span></div>
  <div class="stat-row"><span class="stat-label">Latency Floor:</span><span class="stat-val" id="tele-lat">0.38 ms</span></div>
  <div class="stat-row"><span class="stat-label">Active Gating:</span><span class="stat-val">Top-4 / 34</span></div>
  <div class="stat-row"><span class="stat-label">Ternary Quant:</span><span class="stat-val">BitNet {-1,0,+1}</span></div>
  <div class="stat-row"><span class="stat-label">Virtual Swarm:</span><span class="stat-val">9.0B Agents</span></div>
  <div class="stat-row"><span class="stat-label">E_ICE Safety:</span><span class="stat-val" style="color:#00ff88;">100.0% Clean</span></div>
  <div style="margin-top:12px; padding:10px; background:rgba(0,240,255,0.05); border:1px solid rgba(0,240,255,0.2); border-radius:6px; font-size:10px; color:#aaa; line-height:1.5;">
    <strong style="color:#fff;">3D Interactions:</strong><br>
    • Click node: Focus & orbit synapse<br>
    • Hover node: Inspect expert architecture<br>
    • Right click: Pan view · Scroll: Zoom
  </div>
</div>

<div id="webgl-container"></div>

<div id="node-tooltip">
  <h4 id="tooltip-title">Node Info</h4>
  <div id="tooltip-desc" style="color:#94a3b8; font-size:10px; margin-bottom:4px;">Details</div>
  <div id="tooltip-extra" style="color:#00f0ff; font-size:9.5px; font-family:'JetBrains Mono';">Quant: BitNet 1.58b STE · Active</div>
</div>

<div id="hud-footer">
  <button class="btn-control" onclick="resetCamera()">🎯 Reset View</button>
  <button class="btn-control" onclick="setCameraAngle('top')">📐 Top Flow</button>
  <button class="btn-control" onclick="setCameraAngle('side')">📊 Layer Depth</button>
  <button class="btn-control" onclick="setCameraAngle('front')">🔭 Front Horizon</button>
  <button class="btn-control" id="btn-pulse" onclick="togglePulse()">⚡ Overdrive Pulse</button>
  <button class="btn-control" id="btn-rotate" onclick="toggleAutoRotate()">🔄 Orbit: ON</button>
  <button class="btn-control" onclick="toggleFullscreen()">⛶ Fullscreen</button>
</div>

<script>
// --- THREE.JS AAA 3D EvoMoE NEURAL ARCHITECTURE CANVAS ---
const container = document.getElementById('webgl-container');
const scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x020408, 0.016);

const camera = new THREE.PerspectiveCamera(54, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 3, 25);

const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, powerPreference: "high-performance" });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
container.appendChild(renderer.domElement);

const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.06;
controls.autoRotate = true;
controls.autoRotateSpeed = 0.45;

// Camera Smooth Transition Targets
let targetCamPos = null;
let targetLookAt = null;
const currentLookAt = new THREE.Vector3(0, 0, 0);

// 7 Architectural Layers with Distinct Geometric Personalities
const LAYERS = [
  {
    name: "Dual Ingest Bridge", count: 4, x: -16.5, color: 0xffd700,
    type: "dual_torus",
    desc: "Q1 Analytical & Q2 Intuitive dual-brain embedding bridge with gated compaction"
  },
  {
    name: "9-Vector Prism", count: 9, x: -11.5, color: 0xff0055,
    type: "octahedron",
    desc: "Language, Sentiment, Context, Intent, Meta, Creative, Ethics, Strategy, Constraint"
  },
  {
    name: "Complexity Router", count: 3, x: -5.5, color: 0x00f0ff,
    type: "dodecahedron",
    desc: "BitLinear neural dispatch router classifying fast, balanced, & diffusion paths"
  },
  {
    name: "Top-4 Sparse Gating", count: 4, x: 0, color: 0x00ff88,
    type: "tetrahedron",
    desc: "Dynamic top-k softmax routing selecting 4 active experts per token"
  },
  {
    name: "34-Council Swarms", count: 18, x: 6.5, color: 0xa855f7,
    type: "swarm_icosa",
    desc: "Rank-24 EGGROLL low-rank adaptation Council Experts C0-C33 (9B Virtual Swarm)"
  },
  {
    name: "Flash Diffusion Core", count: 6, x: 12.5, color: 0x3a86ff,
    type: "dual_shell",
    desc: "14-step CouilAttention flash diffusion bridge for continuous multi-modal synthesis"
  },
  {
    name: "Sovereign Head", count: 4, x: 17.5, color: 0xffd700,
    type: "crown_poly",
    desc: "Tied embedding output projection with Lee-Mach-6 thermal governor safety clamping"
  }
];

const nodes = [];
const allNodeMeshes = [];
const rotatingElements = [];
const layerGroups = [];

LAYERS.forEach((layer, lIdx) => {
  const grp = new THREE.Group();
  const layerNodes = [];
  const spacing = 1.35;
  const startY = -((layer.count - 1) * spacing) / 2;

  for (let i = 0; i < layer.count; i++) {
    const nodeRoot = new THREE.Group();
    const zOffset = Math.sin(i * 1.6 + lIdx) * 2.4;
    nodeRoot.position.set(layer.x, startY + i * spacing, zOffset);

    // Inner Core Sphere
    const coreGeo = new THREE.SphereGeometry(0.32, 16, 16);
    const coreMat = new THREE.MeshBasicMaterial({ color: layer.color });
    const core = new THREE.Mesh(coreGeo, coreMat);
    nodeRoot.add(core);

    // Layer-specific custom geometry
    if (layer.type === "dual_torus") {
      const tGeo = new THREE.TorusGeometry(0.55, 0.03, 8, 24);
      const tMat = new THREE.MeshBasicMaterial({ color: layer.color, wireframe: true });
      const ring1 = new THREE.Mesh(tGeo, tMat);
      const ring2 = new THREE.Mesh(tGeo, tMat);
      ring2.rotation.x = Math.PI / 2;
      nodeRoot.add(ring1);
      nodeRoot.add(ring2);
      rotatingElements.push({ mesh: ring1, rx: 0.02, ry: 0.01 });
      rotatingElements.push({ mesh: ring2, rx: -0.01, ry: 0.02 });
    } else if (layer.type === "octahedron") {
      const oGeo = new THREE.OctahedronGeometry(0.55);
      const oMat = new THREE.MeshBasicMaterial({ color: layer.color, wireframe: true, transparent: true, opacity: 0.5 });
      const octa = new THREE.Mesh(oGeo, oMat);
      nodeRoot.add(octa);
      rotatingElements.push({ mesh: octa, rx: 0.015, ry: 0.025 });
    } else if (layer.type === "dodecahedron") {
      const dGeo = new THREE.DodecahedronGeometry(0.52);
      const dMat = new THREE.MeshBasicMaterial({ color: layer.color, wireframe: true, transparent: true, opacity: 0.5 });
      const dodeca = new THREE.Mesh(dGeo, dMat);
      nodeRoot.add(dodeca);
      rotatingElements.push({ mesh: dodeca, rx: -0.02, ry: 0.015 });
    } else if (layer.type === "tetrahedron") {
      const tGeo = new THREE.TetrahedronGeometry(0.58);
      const tMat = new THREE.MeshBasicMaterial({ color: layer.color, wireframe: true, transparent: true, opacity: 0.6 });
      const tetra = new THREE.Mesh(tGeo, tMat);
      nodeRoot.add(tetra);
      rotatingElements.push({ mesh: tetra, rx: 0.02, ry: -0.02 });
    } else if (layer.type === "swarm_icosa") {
      const iGeo = new THREE.IcosahedronGeometry(0.55);
      const iMat = new THREE.MeshBasicMaterial({ color: layer.color, wireframe: true, transparent: true, opacity: 0.5 });
      const icosa = new THREE.Mesh(iGeo, iMat);
      nodeRoot.add(icosa);
      rotatingElements.push({ mesh: icosa, rx: 0.01, ry: 0.02 });

      // Mini-satellite drone
      const satGeo = new THREE.SphereGeometry(0.08, 8, 8);
      const satMat = new THREE.MeshBasicMaterial({ color: 0x00f0ff });
      const sat = new THREE.Mesh(satGeo, satMat);
      nodeRoot.add(sat);
      rotatingElements.push({
        mesh: sat, isOrbit: true, radius: 0.8, speed: 0.04 + (i * 0.005), angle: i
      });
    } else if (layer.type === "dual_shell") {
      const s1Geo = new THREE.SphereGeometry(0.52, 12, 12);
      const s1Mat = new THREE.MeshBasicMaterial({ color: layer.color, wireframe: true, transparent: true, opacity: 0.4 });
      const s1 = new THREE.Mesh(s1Geo, s1Mat);
      nodeRoot.add(s1);
      rotatingElements.push({ mesh: s1, rx: 0.015, ry: -0.015 });
    } else {
      // Crown Poly
      const cGeo = new THREE.IcosahedronGeometry(0.62);
      const cMat = new THREE.MeshBasicMaterial({ color: 0xffd700, wireframe: true, transparent: true, opacity: 0.65 });
      const crown = new THREE.Mesh(cGeo, cMat);
      nodeRoot.add(crown);
      rotatingElements.push({ mesh: crown, rx: 0.025, ry: 0.025 });
    }

    core.userData = {
      root: nodeRoot,
      layerIdx: lIdx,
      layerName: layer.name,
      nodeIndex: i + 1,
      desc: layer.desc,
      color: layer.color,
      initialY: startY + i * spacing,
      initialZ: zOffset
    };

    grp.add(nodeRoot);
    layerNodes.push(core);
    allNodeMeshes.push(core);
  }
  scene.add(grp);
  layerGroups.push(grp);
  nodes.push(layerNodes);
});

// Synaptic Laser Conduits with Streamer Photon Trains
const connections = [];
const photonTrains = [];
const photonGeo = new THREE.SphereGeometry(0.09, 8, 8);

for (let l = 0; l < nodes.length - 1; l++) {
  const fromNodes = nodes[l];
  const toNodes = nodes[l + 1];

  fromNodes.forEach(fn => {
    toNodes.forEach(tn => {
      if (Math.random() > 0.46) {
        const startPos = fn.userData.root.position;
        const endPos = tn.userData.root.position;
        const points = [startPos, endPos];
        const lineGeo = new THREE.BufferGeometry().setFromPoints(points);
        
        // Gradient synapse color
        const lineColor = (l % 2 === 0 ? 0x00f0ff : 0xa855f7);
        const lineMat = new THREE.LineBasicMaterial({
          color: lineColor,
          transparent: true,
          opacity: 0.18
        });
        const line = new THREE.Line(lineGeo, lineMat);
        scene.add(line);
        connections.push({ fn, tn, line, startPos, endPos });

        // Multi-packet photon stream (leader + 2 trailing particles)
        const leaderMat = new THREE.MeshBasicMaterial({ color: 0xffffff });
        const tailMat = new THREE.MeshBasicMaterial({ color: lineColor, transparent: true, opacity: 0.6 });
        
        const pLeader = new THREE.Mesh(photonGeo, leaderMat);
        const pTail1 = new THREE.Mesh(photonGeo, tailMat);
        const pTail2 = new THREE.Mesh(photonGeo, tailMat);
        pTail1.scale.set(0.7, 0.7, 0.7);
        pTail2.scale.set(0.45, 0.45, 0.45);

        scene.add(pLeader);
        scene.add(pTail1);
        scene.add(pTail2);

        photonTrains.push({
          leader: pLeader,
          tail1: pTail1,
          tail2: pTail2,
          start: startPos,
          end: endPos,
          progress: Math.random(),
          speed: 0.007 + Math.random() * 0.012
        });
      }
    });
  });
}

// Background Cyber Grid & Floor Rings
const grid = new THREE.GridHelper(64, 64, 0x00f0ff, 0x07152b);
grid.position.y = -9.5;
scene.add(grid);

// Concentric Rotating Hologram Floor Rings
const floorRingGeo1 = new THREE.RingGeometry(12, 12.2, 64);
const floorRingMat1 = new THREE.MeshBasicMaterial({ color: 0x00f0ff, side: THREE.DoubleSide, transparent: true, opacity: 0.35 });
const floorRing1 = new THREE.Mesh(floorRingGeo1, floorRingMat1);
floorRing1.rotation.x = Math.PI / 2;
floorRing1.position.y = -9.4;
scene.add(floorRing1);

const floorRingGeo2 = new THREE.RingGeometry(18, 18.3, 64);
const floorRingMat2 = new THREE.MeshBasicMaterial({ color: 0xffd700, side: THREE.DoubleSide, transparent: true, opacity: 0.25 });
const floorRing2 = new THREE.Mesh(floorRingGeo2, floorRingMat2);
floorRing2.rotation.x = Math.PI / 2;
floorRing2.position.y = -9.4;
scene.add(floorRing2);

// Ambient Floating Cyber Dust (450 particles)
const starGeo = new THREE.BufferGeometry();
const starCount = 450;
const starPositions = new Float32Array(starCount * 3);
for (let i = 0; i < starCount * 3; i += 3) {
  starPositions[i] = (Math.random() - 0.5) * 80;
  starPositions[i + 1] = (Math.random() - 0.5) * 40;
  starPositions[i + 2] = (Math.random() - 0.5) * 60;
}
starGeo.setAttribute('position', new THREE.BufferAttribute(starPositions, 3));
const starMat = new THREE.PointsMaterial({ color: 0x00f0ff, size: 0.3, transparent: true, opacity: 0.6 });
const starField = new THREE.Points(starGeo, starMat);
scene.add(starField);

// --- INTERACTIVE RAYCASTING & TOOLTIPS ---
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
const tooltip = document.getElementById('node-tooltip');
const tooltipTitle = document.getElementById('tooltip-title');
const tooltipDesc = document.getElementById('tooltip-desc');
const tooltipExtra = document.getElementById('tooltip-extra');
let hoveredNode = null;

window.addEventListener('mousemove', (e) => {
  mouse.x = (e.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);
  const intersects = raycaster.intersectObjects(allNodeMeshes);

  if (intersects.length > 0) {
    const target = intersects[0].object;
    if (hoveredNode !== target) {
      if (hoveredNode) hoveredNode.scale.set(1, 1, 1);
      hoveredNode = target;
      hoveredNode.scale.set(1.45, 1.45, 1.45);
      document.body.style.cursor = 'pointer';

      tooltipTitle.innerHTML = `<span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:#ffd700;"></span> ${target.userData.layerName} #${target.userData.nodeIndex}`;
      tooltipDesc.innerText = target.userData.desc;
      tooltipExtra.innerText = `Quant: BitNet 1.58b STE · Tensor Scale: 1.000 · Status: ACTIVE`;
      tooltip.style.display = 'block';
    }
    tooltip.style.left = `${Math.min(window.innerWidth - 280, e.clientX + 18)}px`;
    tooltip.style.top = `${Math.min(window.innerHeight - 120, e.clientY + 18)}px`;
  } else {
    if (hoveredNode) {
      hoveredNode.scale.set(1, 1, 1);
      hoveredNode = null;
      document.body.style.cursor = 'default';
      tooltip.style.display = 'none';
    }
  }
});

// Click Node to Focus & Orbit
window.addEventListener('click', (e) => {
  if (e.target.closest('#left-panel, #right-panel, #hud-footer, #hud-toggle-floating, #hud-header')) return;
  raycaster.setFromCamera(mouse, camera);
  const intersects = raycaster.intersectObjects(allNodeMeshes);
  if (intersects.length > 0) {
    const target = intersects[0].object;
    const pos = target.userData.root.position;
    smoothTransition(pos.x, pos.y, pos.z + 7, pos.x, pos.y, pos.z);
    
    // Highlight layer button
    document.querySelectorAll('.stage-btn').forEach((b, i) => {
      b.classList.toggle('active', i === target.userData.layerIdx);
    });
  }
});

// Camera Smooth Transition Engine
function smoothTransition(cx, cy, cz, tx, ty, tz) {
  targetCamPos = new THREE.Vector3(cx, cy, cz);
  targetLookAt = new THREE.Vector3(tx, ty, tz);
  controls.autoRotate = false;
  document.getElementById('btn-rotate').innerText = '⏸️ Orbit: OFF';
}

function resetCamera() {
  smoothTransition(0, 3, 25, 0, 0, 0);
  controls.autoRotate = true;
  document.getElementById('btn-rotate').innerText = '🔄 Orbit: ON';
  document.querySelectorAll('.stage-btn').forEach(b => b.classList.remove('active'));
}

function setCameraAngle(angle) {
  if (angle === 'top') {
    smoothTransition(0, 28, 0.1, 0, 0, 0);
  } else if (angle === 'side') {
    smoothTransition(30, 0, 0, 0, 0, 0);
  } else if (angle === 'front') {
    smoothTransition(0, 0, 28, 0, 0, 0);
  }
}

function toggleAutoRotate() {
  controls.autoRotate = !controls.autoRotate;
  document.getElementById('btn-rotate').innerText = controls.autoRotate ? '🔄 Orbit: ON' : '⏸️ Orbit: OFF';
}

let isOverdrive = false;
function togglePulse() {
  isOverdrive = !isOverdrive;
  const mult = isOverdrive ? 3.5 : 1.0;
  photonTrains.forEach(p => p.speed = (0.007 + Math.random() * 0.012) * mult);
  const btn = document.getElementById('btn-pulse');
  btn.classList.toggle('active', isOverdrive);
  btn.innerText = isOverdrive ? '⚡ Overdrive: ACTIVE' : '⚡ Overdrive Pulse';
}

function focusLayer(idx) {
  if (LAYERS[idx]) {
    const lx = LAYERS[idx].x;
    smoothTransition(lx, 2, 10, lx, 0, 0);
    
    document.querySelectorAll('.stage-btn').forEach((b, i) => {
      b.classList.toggle('active', i === idx);
    });
  }
}

let hudVisible = true;
function toggleHUD() {
  hudVisible = !hudVisible;
  document.body.classList.toggle('hud-hidden', !hudVisible);
  document.getElementById('hud-toggle-text').innerText = hudVisible ? 'HUD' : 'SHOW HUD';
  document.getElementById('hud-toggle-icon').innerText = hudVisible ? '👁️' : '👁️‍🗨️';
}

function toggleFullscreen() {
  if (!document.fullscreenElement) {
    document.documentElement.requestFullscreen().catch(() => {});
  } else {
    document.exitFullscreen().catch(() => {});
  }
}

// Live Telemetry Stream Simulation
setInterval(() => {
  const flops = (248 + Math.random() * 7).toFixed(2);
  const lat = (0.36 + Math.random() * 0.06).toFixed(2);
  document.getElementById('tele-flops').innerText = `${flops} GFLOPS`;
  document.getElementById('tele-lat').innerText = `${lat} ms`;
}, 1600);

let clock = 0;
function animate() {
  requestAnimationFrame(animate);
  clock += 0.02;

  // Smooth Camera Lerp
  if (targetCamPos && targetLookAt) {
    camera.position.lerp(targetCamPos, 0.05);
    currentLookAt.lerp(targetLookAt, 0.05);
    controls.target.copy(currentLookAt);
    if (camera.position.distanceTo(targetCamPos) < 0.08 && currentLookAt.distanceTo(targetLookAt) < 0.08) {
      targetCamPos = null;
      targetLookAt = null;
    }
  }

  controls.update();

  // Rotate Holographic Gyro Frames & Satellites
  rotatingElements.forEach(item => {
    if (item.isOrbit) {
      item.angle += item.speed;
      item.mesh.position.set(
        Math.cos(item.angle) * item.radius,
        Math.sin(item.angle * 1.5) * 0.35,
        Math.sin(item.angle) * item.radius
      );
    } else {
      if (item.rx) item.mesh.rotation.x += item.rx;
      if (item.ry) item.mesh.rotation.y += item.ry;
    }
  });

  // Floating gentle oscillation of nodes
  allNodeMeshes.forEach((core, idx) => {
    const root = core.userData.root;
    root.position.y = core.userData.initialY + Math.sin(clock + idx * 0.4) * 0.12;
  });

  // Update Synapse Lines to follow floating node movements
  connections.forEach(c => {
    const p1 = c.fn.userData.root.position;
    const p2 = c.tn.userData.root.position;
    const posAttr = c.line.geometry.attributes.position;
    posAttr.setXYZ(0, p1.x, p1.y, p1.z);
    posAttr.setXYZ(1, p2.x, p2.y, p2.z);
    posAttr.needsUpdate = true;
  });

  // Animate Photon Streamer Trains
  photonTrains.forEach(pt => {
    pt.progress += pt.speed;
    if (pt.progress > 1.0) pt.progress = 0.0;

    const pLeader = pt.progress;
    const pTail1 = Math.max(0, pLeader - 0.035);
    const pTail2 = Math.max(0, pLeader - 0.07);

    pt.leader.position.lerpVectors(pt.start, pt.end, pLeader);
    pt.tail1.position.lerpVectors(pt.start, pt.end, pTail1);
    pt.tail2.position.lerpVectors(pt.start, pt.end, pTail2);
  });

  // Rotate Floor Rings & Starfield
  floorRing1.rotation.z += 0.005;
  floorRing2.rotation.z -= 0.003;
  starField.rotation.y = clock * 0.015;

  renderer.render(scene, camera);
}
animate();

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>