File size: 59,348 Bytes
263b5eb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e9389ca
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
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
<!DOCTYPE html>
<html lang="en">
<head>
  <link rel="stylesheet" href="/cesium/Widgets/widgets.css">
  <script src="/cesium/Cesium.js"></script>

  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>God's Eye View</title>
  <link rel="icon" type="image/svg+xml" href="/logo.svg" />
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet" />
  <!-- Icon font subset to the glyphs this app renders. Keep `icon_names` in sync
       with the sources: src/materialSymbolsSubset.test.mjs fails when a source
       names a glyph this list is missing, because a missing glyph does not draw
       a box — the ligature never forms and the element renders the literal word. -->
  <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20,400,0,0&icon_names=adjust,arrow_drop_down,arrow_forward,arrow_left,arrow_right,bolt,chevron_left,chevron_right,close,close_fullscreen,dark_mode,draw,east,flare,flight,layers_clear,light_mode,local_fire_department,my_location,navigation,normal,on,open_in_full,public,radar,radio,right_panel_close,right_panel_open,rocket_launch,skip_next,skip_previous,view_in_ar" rel="stylesheet" />
  <script type="module" crossorigin src="/assets/index-DTY4d2sy.js"></script>
  <link rel="stylesheet" crossorigin href="/assets/index-3Y0cSMVc.css">
</head>
<body>
  <div id="cesiumContainer"></div>
  <div id="world-overlay-root" aria-hidden="true">
    <canvas id="world-overlay-canvas"></canvas>
  </div>
  <div id="world-overlay-actions" class="world-overlay-accessibility" role="region" aria-label="Visible map targets">
    <div id="world-overlay-action-list"></div>
    <div id="world-overlay-status" role="status" aria-live="polite" aria-atomic="true"></div>
  </div>

  <!-- Title -->
  <div id="title-bar">
    <div class="title-glow"></div>
    <h1><span class="title-logo brand-logo" data-logo-gaze data-logo-src="/logo.svg" aria-hidden="true"><img src="/logo.svg" alt="" /></span> <span>GOD'S EYE <span class="title-accent">VIEW</span></span></h1>
    <p class="subtitle">NO PLACE LEFT BEHIND</p>
  </div>

  <!-- Style indicator -->
  <div id="style-indicator">
    <span class="indicator-label">ACTIVE STYLE</span>
    <span class="indicator-value" id="active-style-name">NORMAL</span>
  </div>

  <!-- Top-center camera and share actions -->
  <nav id="top-center-actions" aria-label="Globe actions">
    <button id="clear-selected-layers" type="button" aria-label="Clear selected data layers" title="Turn off all selected data layers">
      <span class="material-symbols-outlined" aria-hidden="true">layers_clear</span>
    </button>
    <button id="share-btn" type="button" aria-label="Copy share link" title="Copy share link">
      <span class="share-icon" aria-hidden="true">&#x1F517;</span>
    </button>
    <button id="tilt-map-view" type="button" aria-label="Tilt map to oblique view" aria-pressed="false" title="Toggle straight-down and tilted map views">
      <span class="material-symbols-outlined" aria-hidden="true">view_in_ar</span>
    </button>
    <button id="north-up-view" type="button" aria-label="Reset map to north up" title="Reset map bearing to north">
      <span class="camera-compass-n" aria-hidden="true">N</span>
      <span class="camera-compass-needle material-symbols-outlined" aria-hidden="true">navigation</span>
    </button>
    <button id="reset-globe-view" type="button" aria-label="Reset to full globe view" title="Reset camera and return to full globe view">
      <span class="material-symbols-outlined" aria-hidden="true">public</span>
    </button>
  </nav>
  <div id="global-loading-status" role="status" aria-live="polite" aria-atomic="true" hidden>
    <span id="global-loading-label">LOADING LIVE DATA</span>
    <span id="global-loading-detail"></span>
  </div>
  <div id="traffic-sync-chip" aria-live="polite">
    <span id="traffic-sync-label">syncing road network</span>
    <span id="traffic-sync-progress">0%</span>
  </div>
  <div id="cctv-sync-chip" aria-live="polite">
    <span id="cctv-sync-label">loading frames</span>
    <span id="cctv-sync-progress">0/0</span>
  </div>

  <!-- Toast notification -->
  <div id="toast" role="status" aria-live="polite" aria-atomic="true"></div>

  <!-- Safe frame guides for recording composition -->
  <div id="safe-frame-overlay">
    <div id="safe-frame-box"></div>
  </div>

  <!-- Aircraft first-person view. It can be entered from the visible view switcher. -->
  <section id="cockpit-hud" aria-label="Aircraft cockpit view" hidden>
    <div class="cockpit-visor-shell" aria-hidden="true">
      <div class="cockpit-roll-arc">
        <span style="--slot:-3;--depth:3">−30</span>
        <span style="--slot:-2;--depth:2">−20</span>
        <span style="--slot:-1;--depth:1">−10</span>
        <span class="active" style="--slot:0;--depth:0">0</span>
        <span style="--slot:1;--depth:1">+10</span>
        <span style="--slot:2;--depth:2">+20</span>
        <span style="--slot:3;--depth:3">+30</span>
      </div>
      <div class="cockpit-pitch-rail cockpit-pitch-rail-left">
        <span>+20</span><span>+10</span><span class="active">00</span><span>−10</span><span>−20</span>
      </div>
      <div class="cockpit-pitch-rail cockpit-pitch-rail-right">
        <span>+20</span><span>+10</span><span class="active">00</span><span>−10</span><span>−20</span>
      </div>
      <div class="cockpit-horizon-guide">
        <span></span><small>LEVEL</small><span></span>
      </div>
      <div id="cockpit-route-direction" class="cockpit-route-direction" hidden aria-label="Estimated destination direction">
        <svg class="cockpit-route-chevron" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
          <path d="M12 2 4.58 19.93c-.34.83.51 1.63 1.31 1.27L12 18.47l6.11 2.73c.8.36 1.65-.44 1.31-1.27L12 2Z" />
        </svg>
        <small id="cockpit-route-direction-label">DEST ---°</small>
      </div>
      <div class="cockpit-visor-status cockpit-visor-status-left">OPTICAL PLANE · 01</div>
      <div class="cockpit-visor-status cockpit-visor-status-right">VISOR LOCK · ACTIVE</div>
    </div>
    <div id="cockpit-speed-rim" class="cockpit-altitude-rim cockpit-speed-rim">
      <span class="cockpit-altitude-rim-label">GROUND SPEED · KTS</span>
      <div class="cockpit-altitude-rim-rail"></div>
      <div class="cockpit-altitude-rim-scale">
        <span data-speed-rim-tick><b></b><i></i></span>
        <span data-speed-rim-tick><b></b><i></i></span>
        <span data-speed-rim-tick><b></b><i></i></span>
        <span data-speed-rim-tick><b></b><i></i></span>
        <span data-speed-rim-tick><b></b><i></i></span>
        <span data-speed-rim-tick><b></b><i></i></span>
        <span data-speed-rim-tick><b></b><i></i></span>
        <span data-speed-rim-tick><b></b><i></i></span>
        <span data-speed-rim-tick><b></b><i></i></span>
      </div>
      <div class="cockpit-altitude-rim-pointer">
        <span class="material-symbols-outlined">arrow_right</span>
        <strong id="cockpit-speed-rim-value">---</strong>
      </div>
    </div>
    <div id="cockpit-altitude-rim" class="cockpit-altitude-rim">
      <span class="cockpit-altitude-rim-label">ALTITUDE · FT</span>
      <div class="cockpit-altitude-rim-rail"></div>
      <div class="cockpit-altitude-rim-scale">
        <span data-altitude-rim-tick><b></b><i></i></span>
        <span data-altitude-rim-tick><b></b><i></i></span>
        <span data-altitude-rim-tick><b></b><i></i></span>
        <span data-altitude-rim-tick><b></b><i></i></span>
        <span data-altitude-rim-tick><b></b><i></i></span>
        <span data-altitude-rim-tick><b></b><i></i></span>
        <span data-altitude-rim-tick><b></b><i></i></span>
        <span data-altitude-rim-tick><b></b><i></i></span>
        <span data-altitude-rim-tick><b></b><i></i></span>
      </div>
      <div class="cockpit-altitude-rim-pointer">
        <strong id="cockpit-altitude-rim-value">-----</strong>
        <span class="material-symbols-outlined">arrow_left</span>
      </div>
    </div>
    <div class="cockpit-topline">
      <div>
        <span class="cockpit-kicker">FIRST PERSON</span>
        <strong id="cockpit-callsign">AIRCRAFT</strong>
        <span id="cockpit-aircraft-meta" class="cockpit-aircraft-meta">LIVE TRACK · COURSE ALIGNED</span>
      </div>
      <div class="cockpit-vision-controls" role="group" aria-label="Cockpit vision style">
        <button id="cockpit-vision-previous" class="cockpit-vision-nav" type="button" aria-label="Previous cockpit vision style" title="Previous vision style">
          <span class="material-symbols-outlined" aria-hidden="true">chevron_left</span>
          <small>PREV</small>
        </button>
        <button id="cockpit-vision-current" class="cockpit-vision-current" type="button" data-cockpit-vision="optical" aria-label="Current cockpit vision style: NORMAL. Activate for next style." title="Current style: NORMAL — click for next">
          <small>CURRENT</small>
          <strong id="cockpit-vision-current-label" aria-live="polite">NORMAL</strong>
        </button>
        <button id="cockpit-vision-next" class="cockpit-vision-nav" type="button" aria-label="Next cockpit vision style" title="Next vision style">
          <small>NEXT</small>
          <span class="material-symbols-outlined" aria-hidden="true">chevron_right</span>
        </button>
      </div>
    </div>
    <div class="cockpit-reticle material-symbols-outlined" aria-hidden="true">my_location</div>
    <div class="cockpit-compass" aria-label="Current aircraft heading">
      <div class="cockpit-instrument-row">
        <div class="cockpit-readout cockpit-speed">
          <span class="cockpit-readout-label">GROUND SPEED</span>
          <strong id="cockpit-speed-value">---</strong>
          <span class="cockpit-readout-unit">KTS</span>
        </div>
        <div class="cockpit-heading-value"><span id="cockpit-heading-value">---</span><small>°</small></div>
        <div class="cockpit-readout cockpit-altitude">
          <span class="cockpit-readout-label">ALTITUDE</span>
          <strong id="cockpit-altitude-value">-----</strong>
          <span class="cockpit-readout-unit">FT</span>
        </div>
      </div>
      <span class="cockpit-heading-caret material-symbols-outlined" aria-hidden="true">arrow_drop_down</span>
      <div class="cockpit-compass-tape" id="cockpit-compass-tape" aria-hidden="true"></div>
    </div>
    <div class="cockpit-position-readout">
      <span id="cockpit-clock">--:--:--Z</span>
      <span id="cockpit-position">--° · --°</span>
    </div>
    <aside id="cockpit-context" class="cockpit-context-window" aria-label="Contact cockpit summary" hidden>
      <header class="cockpit-context-header">
        <div>
          <span class="cockpit-context-kicker">CONTACT</span>
          <strong id="cockpit-context-subject">CONTACTS · 250 KM</strong>
        </div>
        <nav class="cockpit-context-actions" aria-label="Contact navigation">
          <button id="cockpit-context-previous" type="button" aria-label="Previous — prior visited contact in the 250 km window" title="Previous — prior visited contact in the 250 km window">
            <span class="material-symbols-outlined" aria-hidden="true">skip_previous</span>
          </button>
          <button id="cockpit-context-next" type="button" aria-label="Next — nearest unvisited contact in the 250 km window" title="Next — nearest unvisited contact in the 250 km window">
            <span class="material-symbols-outlined" aria-hidden="true">skip_next</span>
          </button>
          <button id="cockpit-context-toggle" type="button" aria-label="Collapse Contact panel" aria-expanded="true" title="Collapse contact panel">
            <span class="material-symbols-outlined" aria-hidden="true">chevron_left</span>
          </button>
        </nav>
        <span class="cockpit-context-qualifier">CONTEXT ONLY</span>
      </header>
      <div class="cockpit-context-cohorts" role="list" aria-label="Nearby cohort counts">
        <div role="listitem" data-context-cohort="flights"><span>FLT</span><strong>—</strong><small>OpenSky</small></div>
        <div role="listitem" data-context-cohort="military"><span>MIL</span><strong>—</strong><small>adsb.lol</small></div>
        <div role="listitem" data-context-cohort="ais-live-vessels"><span>AIS</span><strong>—</strong><small>AISStream</small></div>
        <div role="listitem" data-context-cohort="military-installations"><span>SITE</span><strong>—</strong><small>OpenStreetMap</small></div>
      </div>
      <div class="cockpit-context-nearest">
        <span id="cockpit-context-direction" class="material-symbols-outlined" aria-hidden="true">navigation</span>
        <div>
          <small>NEAREST OBSERVED / MAPPED</small>
          <strong id="cockpit-context-nearest-label">NO AVAILABLE EXAMPLE</strong>
        </div>
        <span id="cockpit-context-bearing">—</span>
        <span id="cockpit-context-distance">—</span>
      </div>
      <footer class="cockpit-context-footer">
        <span id="cockpit-context-uncertainty">AVAILABLE INPUTS ONLY · NOT AN ALL-CLEAR</span>
        <button
          id="cockpit-weather-toggle"
          class="cockpit-context-weather"
          type="button"
          aria-label="Enable cockpit weather effects"
          aria-pressed="false"
          title="Enable cockpit weather effects"
        >
          <span>WX</span>
          <strong id="cockpit-weather-state">OFF</strong>
        </button>
        <time id="cockpit-context-updated">--:--:--Z</time>
      </footer>
    </aside>
    <aside id="cockpit-signal-stream" class="cockpit-signal-window" aria-label="Cockpit briefing carousel" hidden>
      <section id="cockpit-route" class="cockpit-route-card" aria-label="Estimated flight plan" hidden>
        <div class="cockpit-route-heading">
          <span class="cockpit-route-kicker">ESTIMATED FLIGHT PLAN</span>
          <small id="cockpit-route-status">ROUTE DATA UNAVAILABLE</small>
        </div>
        <div class="cockpit-route-endpoints">
          <div class="cockpit-route-airport">
            <span>FROM</span>
            <strong id="cockpit-route-from">UNKNOWN</strong>
          </div>
          <span class="cockpit-route-arrow material-symbols-outlined" aria-hidden="true">east</span>
          <div class="cockpit-route-airport">
            <span>TO</span>
            <strong id="cockpit-route-to">UNKNOWN</strong>
          </div>
        </div>
      </section>
      <header class="cockpit-signal-header">
        <div class="cockpit-brief-heading">
          <span id="cockpit-brief-kicker" class="cockpit-signal-kicker"><i aria-hidden="true"></i> LIVE SIGNALS</span>
          <strong id="cockpit-brief-subtitle">OBSERVED / MAPPED PINGS</strong>
        </div>
        <nav class="cockpit-brief-actions" aria-label="Cockpit briefing controls">
          <button id="cockpit-brief-previous" type="button" aria-label="Previous briefing page" title="Previous briefing page">
            <span class="material-symbols-outlined" aria-hidden="true">chevron_left</span>
          </button>
          <span id="cockpit-brief-position" aria-live="polite">1 / 3</span>
          <button id="cockpit-brief-next" type="button" aria-label="Next briefing page" title="Next briefing page">
            <span class="material-symbols-outlined" aria-hidden="true">chevron_right</span>
          </button>
          <button
            id="cockpit-brief-auto"
            type="button"
            aria-label="CYCLE OFF"
            aria-pressed="false"
            title="Cycle briefing pages automatically every 9 seconds (Signals → News → Local). Pauses while you hover or focus the panel. Live signal data refreshes continuously either way."
          >CYCLE OFF</button>
          <button id="cockpit-signal-toggle" type="button" aria-label="Collapse cockpit briefing panel" aria-expanded="true" title="Collapse briefing panel">
            <span class="material-symbols-outlined" aria-hidden="true">right_panel_close</span>
          </button>
        </nav>
      </header>
      <div class="cockpit-brief-stage">
        <section data-cockpit-brief-page="signals" aria-label="Live signals">
          <ol id="cockpit-signal-list" class="cockpit-signal-list" aria-live="polite"></ol>
        </section>
        <section data-cockpit-brief-page="news" aria-label="Latest regional news" hidden>
          <div id="cockpit-news-status" class="cockpit-brief-status">ACQUIRING REGIONAL NEWS</div>
          <ol id="cockpit-news-list" class="cockpit-news-list" aria-live="polite"></ol>
        </section>
        <section data-cockpit-brief-page="local" aria-label="Location-based information" hidden>
          <div class="cockpit-local-place">
            <strong id="cockpit-local-place">RESOLVING REGION</strong>
            <small id="cockpit-local-coordinates">--</small>
          </div>
          <div class="cockpit-local-grid">
            <div><span>TEMP</span><strong id="cockpit-local-temperature">—</strong><small>OPEN-METEO</small></div>
            <div><span>WIND</span><strong id="cockpit-local-wind">—</strong><small id="cockpit-local-wind-direction">—</small></div>
            <div><span>SKY</span><strong id="cockpit-local-condition">UNKNOWN</strong><small id="cockpit-local-cloud">—</small></div>
            <div><span>PRECIP</span><strong id="cockpit-local-precipitation">—</strong><small>MM</small></div>
          </div>
          <a class="cockpit-weather-credit" href="https://open-meteo.com/" target="_blank" rel="noopener">Weather data by Open-Meteo.com</a>
        </section>
      </div>
      <footer class="cockpit-signal-footer">
        <span id="cockpit-brief-source">SOURCE-BACKED EVENTS · NO SYNTHETIC NEWS</span>
        <nav class="cockpit-brief-tabs" aria-label="Cockpit briefing pages">
          <button type="button" data-cockpit-brief-index="0" aria-label="Show Live Signals" aria-current="true">SIG</button>
          <button type="button" data-cockpit-brief-index="1" aria-label="Show Regional News">NEWS</button>
          <button type="button" data-cockpit-brief-index="2" aria-label="Show Local Info">LOCAL</button>
        </nav>
      </footer>
    </aside>
    <aside id="cockpit-utility-controls" class="cockpit-utility-controls" aria-label="Cockpit display and Radio controls">
      <div class="cockpit-utility-control">
        <div class="cockpit-utility-launcher" data-cockpit-launcher="display">
          <span>DISPLAY</span>
          <span class="cockpit-utility-divider" aria-hidden="true"></span>
          <button id="cockpit-display-toggle-btn" class="cockpit-utility-glyph" type="button" aria-expanded="false" aria-controls="cockpit-display-panel" aria-label="Expand Cockpit display options" title="Expand Cockpit display options">◀</button>
        </div>
        <div id="cockpit-display-panel" class="cockpit-utility-popover" role="group" aria-label="Cockpit display options" hidden>
          <div class="cockpit-display-slot" data-cockpit-display-slot="hud"></div>
          <div class="cockpit-display-slot" data-cockpit-display-slot="detection"></div>
          <div class="cockpit-display-slot" data-cockpit-display-slot="parameters"></div>
          <div class="cockpit-display-slot" data-cockpit-display-slot="models3d"></div>
        </div>
      </div>
      <div class="cockpit-utility-control">
        <div class="cockpit-utility-launcher" data-cockpit-launcher="radio">
          <span>RADIO</span>
          <span class="cockpit-utility-divider" aria-hidden="true"></span>
          <button id="cockpit-radio-toggle-btn" class="cockpit-utility-glyph" type="button" aria-expanded="false" aria-controls="cockpit-radio-panel" aria-label="Expand Cockpit Radio controls" title="Expand Cockpit Radio controls">◀</button>
        </div>
        <div id="cockpit-radio-panel" class="cockpit-utility-popover cockpit-radio-compact" role="group" aria-label="Cockpit compact Radio controls" hidden>
          <strong id="cockpit-radio-station" class="cockpit-radio-station">READY</strong>
          <button id="cockpit-radio-enable-btn" class="panel-layer-toggle" type="button" aria-pressed="false">ENABLE</button>
          <div class="cockpit-radio-transport">
            <button id="cockpit-radio-prev-btn" type="button" aria-label="Previous filtered radio station" disabled>◀◀</button>
            <button id="cockpit-radio-play-btn" type="button" aria-label="Play selected radio station" disabled>▶</button>
            <button id="cockpit-radio-next-btn" type="button" aria-label="Next filtered radio station" disabled>▶▶</button>
          </div>
          <label class="cockpit-radio-volume" for="cockpit-radio-volume">
            <span>VOLUME</span>
            <input id="cockpit-radio-volume" class="gev-quantitative-slider" type="range" min="0" max="100" value="80" aria-label="Cockpit Radio volume" disabled />
            <output id="cockpit-radio-volume-value" class="gev-slider-value" for="cockpit-radio-volume">80%</output>
          </label>
        </div>
      </div>
    </aside>
    <div class="cockpit-help">ESC EXIT <span>·</span> C TOGGLE</div>
  </section>

  <nav id="view-switcher" aria-label="View switcher">
    <button id="cockpit-reset-globe" type="button" aria-label="Reset cockpit to full globe view" title="Exit cockpit and return to full globe view" hidden>
      <span class="material-symbols-outlined" aria-hidden="true">public</span>
      <span>RESET</span>
    </button>
    <button id="map-view-switch" type="button" aria-label="Exit cockpit view" aria-keyshortcuts="Escape C" title="Exit cockpit view" hidden>
      <span class="material-symbols-outlined" aria-hidden="true">close_fullscreen</span>
      <span>EXIT COCKPIT</span>
    </button>
  </nav>

  <!-- Post-processing toggles (top-right) -->
  <div id="pp-toggles" class="panel-collapsible collapsed" data-panel-id="pp-toggles">
    <div class="compact pp-header-row">
      <span class="pp-header-label">DISPLAY</span>
      <span class="panel-divider" aria-hidden="true"></span>
      <button class="panel-collapse-btn pp-collapse-btn" data-collapse-target="pp-toggles" title="Collapse panel">&#x25C0;</button>
    </div>
    <div class="pp-toggle-group">
      <button class="pp-toggle-btn" id="hud-toggle" title="Intelligence HUD (H)">
        <span class="pp-icon">&#x25CE;</span>
        <span class="pp-label">HUD</span>
      </button>
      <div class="pp-slider-row" id="hud-layout-row">
        <span class="pp-slider-mini-label">Layout</span>
        <select id="hud-layout-select" class="pp-select" aria-label="HUD layout">
          <option value="tactical">Tactical</option>
          <option value="operator">Operator</option>
          <option value="minimal">Minimal</option>
        </select>
      </div>
    </div>
    <div class="pp-toggle-group">
      <button class="pp-toggle-btn" id="detection-toggle" title="Detection Overlay (D)" aria-label="Detection overlay" aria-pressed="false">
        <span class="pp-icon">&#x25A3;</span>
        <span class="pp-label">DETECT</span>
      </button>
      <div class="pp-slider-row detection-slider-row" id="detection-slider-row">
        <label class="pp-slider-mini-label" for="detection-density-slider">Density</label>
        <input type="range" class="pp-slider" id="detection-density-slider" min="0" max="100" step="25" value="50" aria-label="Detection label density" />
        <span class="pp-slider-value" id="detection-density-value">50%</span>
      </div>
      <div class="pp-slider-row detection-allocation-row" id="detection-allocation-row">
        <span class="pp-slider-mini-label">Allocation</span>
        <div class="pp-mode-seg detection-allocation-seg" role="radiogroup" aria-label="Detection label allocation">
          <button class="pp-mode-btn active" id="detection-allocation-elastic" data-allocation="ELASTIC" role="radio" aria-checked="true">Elastic</button>
          <button class="pp-mode-btn" id="detection-allocation-weighted" data-allocation="WEIGHTED" role="radio" aria-checked="false">Weighted</button>
        </div>
      </div>
      <div class="pp-slider-row detection-fade-row" id="detection-fade-row">
        <label class="pp-slider-mini-label" for="detection-fade-slider">Fade</label>
        <input type="range" class="pp-slider" id="detection-fade-slider" min="0" max="40" step="1" value="7" aria-label="Detection fade distance" title="World-overlay fade distance outside the keyhole as a percentage of its radius" />
        <span class="pp-slider-value" id="detection-fade-value">7%</span>
      </div>
      <div class="pp-slider-row detection-opacity-row" id="detection-opacity-row">
        <label class="pp-slider-mini-label" for="detection-opacity-slider">Outside</label>
        <input type="range" class="pp-slider" id="detection-opacity-slider" min="0" max="100" step="1" value="1" aria-label="Detection opacity outside the keyhole" title="World-overlay label and card opacity beyond the fade distance" />
        <span class="pp-slider-value" id="detection-opacity-value">1%</span>
      </div>
    </div>
    <!-- The one shared preset-parameter surface is inserted here at runtime. -->
    <div id="param-slider-panel">
      <div class="param-panel-header">
        <span class="param-panel-title">PARAMETERS</span>
        <span class="param-panel-divider"></span>
        <button class="panel-collapse-btn" id="param-panel-collapse-btn" data-collapse-target="param-slider-panel" title="Collapse panel">−</button>
      </div>
      <div id="param-sliders"></div>
    </div>
    <div class="pp-toggle-group">
      <!-- 3D aircraft is DEFAULT-ON in Proximity (owner directive 2026-08-22), so the
           button ships lit and the mode row ships open — the same markup-carries-the-default
           convention as #scope-toggle. ui.js re-syncs both from durable layer state, which
           is what flips them back for a share link or a stored session carrying 3D off. -->
      <button class="pp-toggle-btn active" id="models3d-toggle" aria-pressed="true" title="3D aircraft — flat icons zoomed out, 3D models up close">
        <span class="pp-icon">&#x2708;</span>
        <span class="pp-label">3D</span>
      </button>
      <div class="pp-slider-row visible" id="models3d-mode-row">
        <span class="pp-slider-mini-label">Models</span>
        <div class="pp-mode-seg" role="radiogroup" aria-label="3D model coverage">
          <button class="pp-mode-btn active" id="models3d-mode-proximity" data-mode="proximity" role="radio" aria-checked="true">Proximity</button>
          <button class="pp-mode-btn" id="models3d-mode-all" data-mode="all" role="radio" aria-checked="false">All</button>
        </div>
      </div>
    </div>
    <div class="pp-toggle-group">
      <button class="pp-toggle-btn active" id="scope-toggle" title="Scope — the circular viewport mask" aria-pressed="true">
        <span class="pp-icon material-symbols-outlined" aria-hidden="true">adjust</span>
        <span class="pp-label">Scope</span>
      </button>
      <div class="pp-slider-row visible" id="scope-slider-row">
        <span class="pp-slider-mini-label">Feather</span>
        <!-- Feather starts at an 11% soft scope-mask edge (owner final lock
             2026-08-24, superseding the 08-22 hard-crop and 08-23 8% rulings);
             mirrors SCOPE_FEATHER_RATIO_DEFAULT in src/scopeMask.js. Feather
             softens the black mask edge; label fading is the separate Fade
             slider. -->
        <input type="range" class="pp-slider" id="scope-feather-slider" min="0" max="100" value="11" aria-label="Scope edge feather" title="Scope edge feather as a percentage of the keyhole radius" />
        <span class="pp-slider-value" id="scope-feather-value">11%</span>
      </div>
    </div>
    <div class="pp-toggle-group">
      <button class="pp-toggle-btn" id="draw-toggle" title="Draw on the world — click vertices, double-click or Enter to finish, Esc to cancel" aria-pressed="false">
        <span class="pp-icon material-symbols-outlined" aria-hidden="true">draw</span>
        <span class="pp-label">Draw</span>
      </button>
      <div class="pp-slider-row" id="draw-mode-row">
        <span class="pp-slider-mini-label">Shape</span>
        <div class="pp-mode-seg" role="radiogroup" aria-label="Shape to draw">
          <button class="pp-mode-btn active" data-shape="area" role="radio" aria-checked="true">Area</button>
          <button class="pp-mode-btn" data-shape="line" role="radio" aria-checked="false">Line</button>
          <button class="pp-mode-btn" data-shape="pin" role="radio" aria-checked="false">Pin</button>
        </div>
      </div>
      <div class="pp-slider-row" id="draw-label-row">
        <input type="text" class="pp-text-input" id="draw-label-input" maxlength="120" placeholder="Label (optional)" aria-label="Label for the drawn shape" autocomplete="off" spellcheck="false">
        <select class="pp-select draw-color-select" id="draw-color-select" aria-label="Colour of the drawn shape">
          <option value="primary">Primary</option>
          <option value="amber">Amber</option>
          <option value="cyan">Cyan</option>
          <option value="green">Green</option>
          <option value="red">Red</option>
        </select>
        <button class="pp-mode-btn draw-clear-btn" id="draw-clear" type="button" title="Remove every mark from the board">Clear</button>
        <span class="draw-hint" id="draw-hint" aria-live="polite"></span>
      </div>
    </div>
    <div class="pp-toggle-group">
      <button class="pp-toggle-btn" id="celestial-toggle" title="Celestial ring — reveal the full globe" aria-pressed="false">
        <span class="pp-icon material-symbols-outlined" aria-hidden="true">flare</span>
        <span class="pp-label">Celestial</span>
      </button>
    </div>
    <button class="pp-toggle-btn" id="clean-view-toggle" title="Hide UI chrome">
      <span class="pp-icon">&#x25A1;</span>
      <span class="pp-label">Clean UI</span>
    </button>
    <div class="pp-toggle-group">
      <button class="pp-toggle-btn" id="bloom-toggle" title="Bloom / Glow">
        <span class="pp-icon">&#x2728;</span>
        <span class="pp-label">Bloom</span>
      </button>
      <div class="pp-slider-row" id="bloom-slider-row">
        <input type="range" class="pp-slider" id="bloom-intensity-slider" min="0" max="200" value="0" aria-label="Bloom intensity" />
        <span class="pp-slider-value" id="bloom-intensity-value">0%</span>
      </div>
    </div>
    <div class="pp-toggle-group">
      <button class="pp-toggle-btn" id="sharpen-toggle" title="Sharpening">
        <span class="pp-icon">&#x1F50D;</span>
        <span class="pp-label">Sharpen</span>
      </button>
      <div class="pp-slider-row" id="sharpen-slider-row">
        <input type="range" class="pp-slider" id="sharpen-intensity-slider" min="0" max="100" value="49" aria-label="Sharpen intensity" />
        <span class="pp-slider-value" id="sharpen-intensity-value">49%</span>
      </div>
    </div>
  </div>
  <button id="clean-view-exit" title="Return UI controls">EXIT CLEAN VIEW</button>

  <!-- Unified bottom command dock: locations, voice (injected at runtime), visual presets -->
  <div id="command-dock" aria-label="Navigation, voice, and visual preset controls">
  <!-- Control panel -->
  <div id="control-panel" class="panel-collapsible collapsed">
    <div class="panel-glow"></div>
    <div class="panel-inner">
      <button id="control-panel-toggle" class="panel-header dock-tray-toggle" type="button"
        data-dock-toggle-target="control-panel" aria-expanded="false"
        aria-controls="control-panel-popover" aria-label="Expand Visual Presets">
        <span class="panel-title"><span class="dock-label-icon dock-label-icon-presets" aria-hidden="true"></span>VISUAL PRESETS</span>
        <span class="panel-divider"></span>
      </button>
      <div id="control-panel-popover" class="dock-popover-content">
      <button class="dock-pin-btn" data-pin-target="control-panel" type="button" aria-label="Pin visual presets" aria-pressed="false" title="Keep visual presets open"><img src="/pin.svg" alt="" /></button>
      <div id="style-buttons" class="button-grid">
        <button class="style-btn active" data-style="normal" title="Show the globe without a visual filter.">
          <span class="btn-icon">◯</span>
          <span class="btn-label">Normal</span>
          <span class="btn-key">1</span>
        </button>
        <button class="style-btn" data-style="retro" title="Emulate a green phosphor CRT with scanlines and screen curvature.">
          <span class="btn-icon">▦</span>
          <span class="btn-label">CRT</span>
          <span class="btn-key">2</span>
        </button>
        <button class="style-btn" data-style="surveillance" title="Simulate night-vision goggles with green intensification and a tube vignette.">
          <span class="btn-icon">🌙</span>
          <span class="btn-label">NVG</span>
          <span class="btn-key">3</span>
        </button>
        <button class="style-btn" data-style="thermal" title="Simulate FLIR-style thermal contrast. Turn up Ironbow for color.">
          <span class="btn-icon">🌡️</span>
          <span class="btn-label">FLIR</span>
          <span class="btn-key">4</span>
        </button>
        <button class="style-btn" data-style="anime" title="Apply bright cel-shaded color and illustrated outlines.">
          <span class="btn-icon">✦</span>
          <span class="btn-label">Anime</span>
          <span class="btn-key">5</span>
        </button>
        <button class="style-btn" data-style="noir" title="Apply high-contrast monochrome film-noir grading.">
          <span class="btn-icon">◐</span>
          <span class="btn-label">Noir</span>
          <span class="btn-key">6</span>
        </button>
        <button class="style-btn" data-style="snow" title="Add a cold, snowy whiteout treatment to the scene.">
          <span class="btn-icon">❄</span>
          <span class="btn-label">Snow</span>
          <span class="btn-key">7</span>
        </button>
      </div>
      <section class="map-source-section" aria-labelledby="map-source-label">
        <div class="map-source-heading">
          <span id="map-source-label">MAP SOURCE</span>
          <span id="map-stack-status" class="pp-stack-status" aria-live="polite">3D</span>
        </div>
        <div id="map-stack-chips" class="map-stack-chip-row" role="group" aria-label="Map source"></div>
      </section>
      </div>
      <div id="style-mini-status" class="panel-mini-status" aria-live="polite">
        <span class="panel-mini-label">Style</span>
        <span id="style-mini-value" class="panel-mini-value">NORMAL</span>
      </div>
    </div>
  </div>

  <!-- Location bar -->
  <div id="location-bar" class="panel-collapsible collapsed">
    <div class="panel-glow"></div>
    <div class="location-inner">
      <div class="location-toolbar">
        <button id="location-bar-toggle" class="dock-tray-toggle" type="button" data-dock-toggle-target="location-bar" aria-controls="location-bar-popover" aria-expanded="false" aria-label="Expand LOCATION" title="Expand LOCATION">
          <span class="location-toolbar-label"><span class="dock-label-icon dock-label-icon-location" aria-hidden="true"></span>LOCATION</span>
        </button>
        <button class="panel-collapse-btn" data-collapse-target="location-bar" title="Collapse panel">+</button>
      </div>
      <div id="location-mini-status" class="location-mini-status" aria-live="polite">
        <div id="location-mini-city" class="location-mini-city">📍 Location: --</div>
        <div id="location-mini-poi" class="location-mini-poi">Landmark: --</div>
      </div>
      <div id="location-bar-popover" class="dock-popover-content">
        <button class="dock-pin-btn" data-pin-target="location-bar" type="button" aria-label="Pin location tray" aria-pressed="false" title="Keep location tray open"><img src="/pin.svg" alt="" /></button>
        <div id="poi-row" class="poi-row-container"></div>
        <div class="location-bar-divider" id="location-bar-divider"></div>
        <div class="location-city-row">
          <div id="location-pills" class="location-pills"></div>
          <div class="location-search-wrap">
            <button id="search-toggle" class="search-toggle-btn" title="Search any location">
              <span>&#x1F50E;</span>
            </button>
            <input type="text" id="location-search" placeholder="Search any location..." autocomplete="off" spellcheck="false" aria-label="Search location by name or coordinates" />
          </div>
        </div>
      </div>
    </div>
  </div>
  </div>

  <div id="left-panel-stack">
  <!-- Data Layer Toggle Panel -->
  <div id="data-panel" class="panel-collapsible collapsed active" data-panel-id="data-panel">
    <div class="panel-glow"></div>
    <div class="data-panel-inner">
      <div class="panel-header">
        <span class="panel-title">DATA LAYERS</span>
        <span class="panel-divider"></span>
        <button class="panel-collapse-btn" data-collapse-target="data-panel" title="Collapse panel">+</button>
      </div>
      <div id="data-toggles" class="data-toggle-list"></div>
    </div>
  </div>

  <!-- CCTV Coverage Panel -->
  <div id="cctv-panel" class="panel-collapsible collapsed" data-panel-id="cctv-panel">
    <div class="panel-glow"></div>
    <div class="cctv-panel-inner">
      <div class="panel-header">
        <span class="panel-title">CCTV</span>
        <span class="panel-divider"></span>
        <button class="panel-collapse-btn" data-collapse-target="cctv-panel" title="Collapse panel">+</button>
      </div>
      <div id="cctv-frame-wrap" class="cctv-frame-wrap">
        <img id="cctv-frame" alt="CCTV feed frame" />
      </div>
      <div id="cctv-source-badge" role="status" aria-live="polite">SOURCE · UNKNOWN</div>
      <div id="cctv-meta">Enable CCTV to load camera intersections</div>
      <div class="cctv-controls">
        <button id="cctv-enable-btn" class="scene-btn">CCTV OFF</button>
        <button id="cctv-nearest-btn" class="scene-btn">NEAREST</button>
      </div>
      <div class="cctv-controls">
        <button id="cctv-prev-btn" class="scene-btn">PREV</button>
        <select id="cctv-camera-select" aria-label="CCTV camera"></select>
        <button id="cctv-next-btn" class="scene-btn">NEXT</button>
      </div>
      <div class="cctv-controls">
        <button id="cctv-focus-btn" class="scene-btn">FOCUS</button>
        <button id="cctv-coverage-btn" class="scene-btn">COVERAGE OFF</button>
        <button id="cctv-auto-hop-btn" class="scene-btn">AUTO HOP OFF</button>
      </div>
      <div class="cctv-controls">
        <button id="cctv-projection-btn" class="scene-btn">PROJECTION ON</button>
        <span id="cctv-quality-chip">CAL · --</span>
      </div>
      <div class="cctv-calibration-block">
        <div class="cctv-calibration-header">
          <div class="cctv-summary-label">CALIBRATION</div>
          <button id="cctv-adjust-btn" class="scene-btn" title="Drag the camera in the world: rings rotate, arrows move, handles set range/FOV">ADJUST</button>
        </div>
        <div id="cctv-cal-readout" class="cctv-cal-readout" aria-label="Camera pose — click a value to type">
          <button class="cctv-cal-value" data-cal-field="heading" title="Heading (compass °) — click to type">HDG --</button>
          <button class="cctv-cal-value" data-cal-field="pitch" title="Pitch (° up/down) — click to type">PITCH --</button>
          <button class="cctv-cal-value" data-cal-field="fov" title="Horizontal FOV (°) — click to type">FOV --</button>
          <button class="cctv-cal-value" data-cal-field="range" title="Range / monitor-plane distance (m) — click to type">RANGE --</button>
          <button class="cctv-cal-value" data-cal-field="height" title="Mount height above ground (m) — click to type">HGT --</button>
          <button class="cctv-cal-value" data-cal-field="north" title="North offset from catalog position (m) — click to type">ΔN --</button>
          <button class="cctv-cal-value" data-cal-field="east" title="East offset from catalog position (m) — click to type">ΔE --</button>
        </div>
        <div class="cctv-controls cctv-calibration-actions">
          <button id="cctv-calib-save-btn" class="scene-btn">SAVE CAL</button>
          <button id="cctv-calib-reset-btn" class="scene-btn">RESET CAL</button>
        </div>
      </div>
      <div class="cctv-summary-label">SCENE SUMMARY</div>
      <div id="cctv-summary">Enable CCTV to start camera-linked intelligence summaries.</div>
    </div>
  </div>

  <!-- Scene Director Panel -->
  <div id="scene-panel" class="panel-collapsible collapsed" data-panel-id="scene-panel">
    <div class="panel-glow"></div>
    <div class="scene-panel-inner">
      <div class="panel-header">
        <span class="panel-title">SCENES</span>
        <span class="panel-divider"></span>
        <button class="panel-collapse-btn" data-collapse-target="scene-panel" title="Collapse panel">+</button>
      </div>
      <div class="scene-controls">
        <select id="scene-select" aria-label="Scene recipe"></select>
        <button id="scene-new-btn" class="scene-btn">NEW</button>
        <button id="scene-delete-btn" class="scene-btn scene-btn-danger">DEL</button>
      </div>
      <div class="scene-controls">
        <button id="scene-capture-btn" class="scene-btn">CAPTURE SHOT</button>
        <button id="scene-update-shot-btn" class="scene-btn">UPDATE SHOT</button>
      </div>
      <div id="scene-shot-list" class="scene-shot-list"></div>
      <div class="scene-controls">
        <button id="scene-start-btn" class="scene-btn">START</button>
        <button id="scene-stop-btn" class="scene-btn scene-btn-danger">STOP</button>
        <button id="scene-next-btn" class="scene-btn">NEXT</button>
      </div>
      <div class="scene-controls">
        <button id="scene-export-btn" class="scene-btn">EXPORT PRESETS</button>
        <button id="scene-import-btn" class="scene-btn">IMPORT</button>
        <button id="scene-download-btn" class="scene-btn">RUN LOG</button>
        <input type="file" id="scene-import-file" accept="application/json,.json" hidden />
      </div>
      <div class="scene-progress">
        <div id="scene-progress-fill">0%</div>
      </div>
      <div id="scene-status">Ready</div>
    </div>
  </div>

  </div>

  <!-- Global Context is deliberately independent from the left layer accordion. -->
  <aside id="right-context-rail">
    <div id="global-context-panel" class="panel-collapsible collapsed" data-panel-id="global-context-panel">
      <div class="panel-glow"></div>
      <div class="global-context-panel-inner">
        <div class="panel-header">
          <span class="panel-title">CONTEXT</span>
          <span class="panel-divider"></span>
          <div id="context-radio-dock" class="context-radio-dock">
            <button id="context-radio-toggle-btn" class="context-radio-toggle" type="button" aria-expanded="false" aria-controls="context-radio-mini" aria-label="Open compact Radio controls" title="Open compact Radio controls">
              <span class="material-symbols-outlined" aria-hidden="true">radio</span>
            </button>
            <div id="context-radio-mini" class="context-radio-mini" role="group" aria-label="Compact Radio controls" hidden>
              <div class="context-radio-mini-heading">
                <span>RADIO</span>
                <strong id="context-radio-mini-station">RADIO READY</strong>
                <span class="context-radio-mini-actions">
                  <button id="context-radio-details-btn" type="button" aria-label="Open detailed Radio controls" aria-expanded="false" aria-controls="radio-panel" title="Open detailed Radio controls">
                    <span class="material-symbols-outlined" aria-hidden="true">open_in_full</span>
                  </button>
                  <button id="context-radio-mini-close-btn" type="button" aria-label="Close compact Radio controls" title="Close compact Radio controls">
                    <span class="material-symbols-outlined" aria-hidden="true">close</span>
                  </button>
                </span>
              </div>
              <button id="context-radio-mini-enable-btn" class="panel-layer-toggle" type="button" aria-pressed="false">ENABLE</button>
              <div class="context-radio-mini-transport">
                <button id="context-radio-mini-prev-btn" type="button" aria-label="Previous filtered radio station" title="Previous station" disabled>◀◀</button>
                <button id="context-radio-mini-play-btn" type="button" aria-label="Play selected radio station" title="Play" disabled>▶</button>
                <button id="context-radio-mini-next-btn" type="button" aria-label="Next filtered radio station" title="Next station" disabled>▶▶</button>
              </div>
              <label class="context-radio-mini-volume" for="context-radio-mini-volume">
                <span>VOLUME</span>
                <input id="context-radio-mini-volume" class="gev-quantitative-slider" type="range" min="0" max="100" value="80" aria-label="Compact Radio volume" disabled />
                <output id="context-radio-mini-volume-value" class="gev-slider-value" for="context-radio-mini-volume">80%</output>
              </label>
            </div>
          </div>
          <button class="panel-collapse-btn" data-collapse-target="global-context-panel" title="Expand panel">▶</button>
        </div>
        <div class="global-context-modes" role="tablist" aria-label="Context mode">
          <button id="global-context-flights-btn" class="context-mode-button" type="button" role="tab" tabindex="0" aria-selected="false" aria-controls="context-flights-view" aria-label="CONTACTS" title="Cycles the nearest contacts of whatever type you select — planes, vessels, installations. Satellites track independently.">
            <span class="material-symbols-outlined" aria-hidden="true">radar</span>
            <span>CONTACTS</span>
          </button>
          <button id="global-context-missions-btn" class="context-mode-button" type="button" role="tab" tabindex="0" aria-selected="false" aria-controls="context-missions-view">
            <span class="material-symbols-outlined" aria-hidden="true">rocket_launch</span>
            <span>SPACE MISSIONS</span>
          </button>
        </div>
        <div id="context-mode-standby" class="context-mode-standby">
          <strong>SELECT CONTEXT</strong>
          <span>CONTACTS — nearest planes · vessels · sites<br>SPACE MISSIONS — launches &amp; orbital assets</span>
        </div>
        <section id="context-flights-view" class="context-mode-view" role="tabpanel" aria-labelledby="global-context-flights-btn" hidden>
          <div class="global-context-actions" aria-label="Contact Context actions">
            <button id="cockpit-entry" type="button" hidden>
              <span class="material-symbols-outlined" aria-hidden="true">flight</span>
              <span>COCKPIT</span>
            </button>
            <button id="installations-search-btn" class="panel-layer-toggle" type="button">SEARCH NEARBY SITES</button>
            <button id="tr3b-toggle" class="tr3b-toggle" type="button" aria-pressed="false" hidden aria-label="Reclassify tracked contact as TR-3B" title="Reclassify as TR-3B">🛸</button>
          </div>
          <aside id="military-awareness-panel">
            <div class="military-awareness-standby">
              <strong>CONTACTS CONTEXT OFF</strong>
              <span>SELECT CONTACTS TO LOAD OBSERVED / MAPPED PROXIMITY</span>
            </div>
          </aside>
        </section>
        <section id="context-missions-view" class="context-mode-view" role="tabpanel" aria-labelledby="global-context-missions-btn" hidden>
          <div id="space-mission-panel-host">
            <div id="space-mission-roster" class="space-mission-roster" aria-label="Available Space Missions">
              <div class="space-mission-roster-header">
                <div>
                  <strong>AVAILABLE MISSIONS</strong>
                  <span>SELECT A MISSION TO INSPECT</span>
                </div>
                <output data-mission-roster-count>—</output>
              </div>
              <div class="space-mission-roster-list" data-mission-roster-list>
                <div class="space-mission-roster-empty">LOADING 30-DAY MISSION INDEX</div>
              </div>
              <p class="space-mission-roster-focus-continuation" tabindex="-1" data-mission-roster-focus-continuation>TAB PREVIEWS · ENTER / SPACE SELECTS</p>
            </div>
          </div>
        </section>
        <section id="radio-panel" class="panel-collapsible collapsed" data-panel-id="radio-panel" aria-label="Internet radio companion">
          <div class="radio-panel-inner">
            <div class="panel-header">
              <span class="panel-title">RADIO</span>
              <span id="radio-layer-state" class="radio-layer-state">OFF</span>
              <span class="panel-divider"></span>
              <button class="panel-collapse-btn" data-collapse-target="radio-panel" title="Expand Radio" aria-label="Expand Radio section">+</button>
            </div>
            <div class="radio-directory-row">
              <button id="radio-enable-btn" class="panel-layer-toggle" type="button" aria-pressed="false">ENABLE</button>
              <label class="radio-filter-label" for="radio-filter">STATION TAG</label>
              <select id="radio-filter" aria-label="Filter stations by station tag" disabled>
                <option value="all">All</option>
              </select>
            </div>
            <div id="radio-station-card" class="radio-station-card" aria-live="polite">
              <strong id="radio-station-name">NO STATION SELECTED</strong>
              <span id="radio-station-meta">Enable Radio, then choose a globe marker or use next.</span>
              <span id="radio-station-tags"></span>
            </div>
            <div id="radio-tuner" class="radio-tuner" hidden>
              <div class="radio-tuner-header">
                <span id="radio-tuner-band-label">DIRECTORY BAND</span>
                <output id="radio-tuner-value" for="radio-tuner-slider">DRAG TO TUNE</output>
              </div>
              <div class="radio-tuner-dial">
                <div class="radio-tuner-scale" aria-hidden="true"></div>
                <div id="radio-tuner-needle" class="radio-tuner-needle" aria-hidden="true"></div>
                <input id="radio-tuner-slider" type="range" min="0" max="0" step="1" value="0"
                  aria-label="Tune available internet radio stations" aria-valuetext="No station available" disabled />
              </div>
              <div class="radio-tuner-readout">
                <span id="radio-tuner-station">ALL · DRAG THE NEEDLE</span>
                <span>SNAPS TO AVAILABLE STATIONS</span>
              </div>
            </div>
            <div class="radio-transport" role="group" aria-label="Radio playback">
              <button id="radio-prev-btn" type="button" aria-label="Previous filtered station" disabled>PREV</button>
              <button id="radio-play-btn" type="button" aria-label="Play selected station" disabled>PLAY</button>
              <button id="radio-next-btn" type="button" aria-label="Next filtered station" disabled>NEXT</button>
              <button id="radio-stop-btn" type="button" aria-label="Stop radio playback" disabled>STOP</button>
            </div>
            <label class="radio-volume-row" for="radio-volume">
              <span>VOLUME</span>
              <input id="radio-volume" class="gev-quantitative-slider" type="range" min="0" max="100" value="80" aria-label="Radio volume" />
              <output id="radio-volume-value" class="gev-slider-value" for="radio-volume">80%</output>
            </label>
            <div id="radio-playback-state" class="radio-playback-state" role="status" aria-live="polite">Radio off</div>
            <div class="radio-links">
              <a id="radio-station-homepage" href="#" target="_blank" rel="noopener noreferrer" hidden>STATION SITE</a>
              <a href="https://www.radio-browser.info/" target="_blank" rel="noopener noreferrer">DIRECTORY: RADIO BROWSER</a>
            </div>
            <p class="radio-privacy">Audio connects directly to the broadcaster after you press play. Your IP is visible to that broadcaster.</p>
          </div>
        </section>
      </div>
    </div>
  </aside>

  <div id="scene-runtime"></div>

  <!-- Explicit mission choice on a fresh session. Live feeds are not auto-enabled
       until the visitor asks; shared links skip this surface entirely. It returns
       every session until "Don't show this again" is ticked — see
       src/firstRunExperience.js for the full show policy. -->
  <aside id="first-run-launcher" role="dialog" aria-labelledby="first-run-title" aria-describedby="first-run-description" hidden>
    <div class="first-run-scanline" aria-hidden="true"></div>
    <header class="first-run-header">
      <span class="first-run-kicker">MISSION CONTROL · FIRST LAUNCH</span>
    </header>
    <h2 id="first-run-title">Choose your first view</h2>
    <!-- The card's one persuasive line, owner-authored and VERBATIM (2026-08-23)
         — including the unspaced em dash. The arc it has to carry: this looks
         like something you should not have access to → the sources are all
         public → the data is real. Tile subcopy stays purely functional. -->
    <p id="first-run-description">It feels like a forbidden cockpit—then you realize the sources are public and the data is real.</p>
    <div class="first-run-choices">
      <button type="button" data-first-run-choice="contacts">
        <span class="material-symbols-outlined" aria-hidden="true">radar</span>
        <span><strong>LIVE CONTACTS</strong><small>Aircraft, vessels and nearby intelligence</small></span>
        <span class="material-symbols-outlined first-run-arrow" aria-hidden="true">arrow_forward</span>
      </button>
      <button type="button" data-first-run-choice="space-missions">
        <span class="material-symbols-outlined" aria-hidden="true">rocket_launch</span>
        <span><strong>SPACE MISSIONS</strong><small>Launches, spacecraft and orbital context</small></span>
        <span class="material-symbols-outlined first-run-arrow" aria-hidden="true">arrow_forward</span>
      </button>
      <button type="button" data-first-run-choice="environmental">
        <span class="material-symbols-outlined" aria-hidden="true">local_fire_department</span>
        <!-- Title text is painted from ENVIRONMENTAL_LABEL_CHOICE at init. -->
        <!-- Subcopy names BOTH feeds this tile turns on, because the launcher
             optimizes for the fully configured experience (owner ruling,
             2026-08-23) — see the mission table in src/firstRunExperience.js. -->
        <span><strong data-first-run-environmental-title>ENVIRONMENTAL</strong><small>Live earthquakes and active fires, from USGS and NASA</small></span>
        <span class="material-symbols-outlined first-run-arrow" aria-hidden="true">arrow_forward</span>
      </button>
      <button type="button" class="first-run-explore" data-first-run-choice="explore">
        <span class="material-symbols-outlined" aria-hidden="true">public</span>
        <span><strong>EXPLORE MANUALLY</strong><small>Begin with a clean globe</small></span>
        <span class="material-symbols-outlined first-run-arrow" aria-hidden="true">arrow_forward</span>
      </button>
    </div>
    <div class="first-run-footer">
      <label class="first-run-suppress">
        <input type="checkbox" data-first-run-suppress />
        <span>Don't show this again</span>
      </label>
      <span>ESC to dismiss</span>
    </div>
    <!-- Kept out of the footer row: it swaps to mission progress and errors, and
         a live region that also holds layout makes the row jump as it speaks. -->
    <p class="first-run-note" data-first-run-status role="status" aria-live="polite">Tip: the GEV MIC button in the dock lets you talk to the map.</p>
  </aside>

  <!-- POWER UP — in-app key setup. Dev-server only: src/keySetup.js removes
       both the chip and this dialog outright when /api/setup/status is not
       there to answer (prod builds, LAN visitors). Rows are rendered from
       that payload, so the key registry lives in src/keySetupCore.mjs alone. -->
  <button id="key-setup-chip" type="button" hidden aria-haspopup="dialog" aria-controls="key-setup">
    <span class="material-symbols-outlined" aria-hidden="true">bolt</span>
    <span data-key-setup-chip-label>POWER UP</span>
  </button>
  <aside id="key-setup" role="dialog" aria-labelledby="key-setup-title" aria-describedby="key-setup-description" hidden>
    <div class="key-setup-scanline" aria-hidden="true"></div>
    <header class="key-setup-header">
      <span class="key-setup-kicker">GROUND STATION · PROVIDER SETTINGS</span>
      <button type="button" class="key-setup-close" data-key-setup-close aria-label="Close key setup">
        <span class="material-symbols-outlined" aria-hidden="true">close</span>
      </button>
    </header>
    <h2 id="key-setup-title">Power up the globe</h2>
    <p id="key-setup-description">The globe already flies keyless. Every key below switches on another real feed — paste one and it's saved into this app's local configuration, then the server restarts itself. Server-side keys stay on this machine; Google Maps and Cesium ion run in the browser and must be provider-restricted. Keys you configured elsewhere are shown but never touched.</p>
    <div class="key-setup-rows" data-key-setup-rows></div>
    <div class="key-setup-footer">
      <button type="button" class="key-setup-apply" data-key-setup-apply>SAVE KEYS</button>
      <span class="key-setup-hint">ESC to close</span>
    </div>
    <p class="key-setup-note" data-key-setup-status role="status" aria-live="polite">The Google Maps key buys the photorealistic planet — everything else stacks on top.</p>
  </aside>

  <!-- Intelligence HUD Overlay -->
  <div id="intel-hud"></div>

  <!-- Loading screen -->
  <div id="loading-screen">
    <div class="loader-content">
      <span class="loader-logo brand-logo" data-logo-gaze data-logo-src="/logo.svg" aria-hidden="true"><img src="/logo.svg" alt="" /></span>
      <h2>GOD'S EYE <span class="title-accent">VIEW</span></h2>
      <p class="loader-status">Initializing photorealistic world...</p>
    </div>
  </div>

</body>
</html>