gopeak 2.3.6 → 2.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2595 +1,2595 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Godot Project Map</title>
7
- <style>
8
- /* ============================================================================
9
- GODOT PROJECT MAP VISUALIZER — "VOID" BIG TYPOGRAPHY DARK DASHBOARD
10
- ============================================================================ */
11
-
12
- * { margin: 0; padding: 0; box-sizing: border-box; }
13
-
14
- :root {
15
- /* Void palette */
16
- --bg-primary: #101319;
17
- --bg-secondary: #171c24;
18
- --bg-tertiary: #202734;
19
- --bg-hover: #293243;
20
- --bg-surface: #1b212c;
21
- --border: rgba(255,255,255,0.06);
22
- --border-light: rgba(255,255,255,0.1);
23
- --text-primary: #f0f0f5;
24
- --text-secondary: #7d8590;
25
- --text-muted: #484f58;
26
- --accent: #4ec9b0;
27
- --accent-light: #6edcc8;
28
- --accent-dim: rgba(78, 201, 176, 0.12);
29
-
30
- /* GDScript syntax colors — UNCHANGED */
31
- --gd-keyword: #cc7832;
32
- --gd-func-name: #ffc66d;
33
- --gd-type: #6897bb;
34
- --gd-string: #6a8759;
35
- --gd-number: #6897bb;
36
- --gd-comment: #808080;
37
- --gd-var: #cc7832;
38
- --gd-signal: #a6e3a1;
39
- --gd-export: #bbb529;
40
- --gd-builtin: #8888c6;
41
-
42
- /* Edge colors — UNCHANGED */
43
- --edge-extends: #7aa2f7;
44
- --edge-preload: #d4a27f;
45
- --edge-signal: #a6e3a1;
46
-
47
- /* Typography scale — Big Typography editorial dashboard */
48
- --font-display: 48px;
49
- --font-h1: 32px;
50
- --font-h2: 20px;
51
- --font-body: 12px;
52
- --font-small: 10px;
53
- --font-micro: 9px;
54
- --font-mono: 'SF Mono', 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
55
- --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
56
-
57
- /* Spacing scale */
58
- --space-xs: 6px;
59
- --space-sm: 10px;
60
- --space-md: 16px;
61
- --space-lg: 22px;
62
- --space-xl: 32px;
63
- --space-2xl: 44px;
64
-
65
- /* Shadows */
66
- --shadow-panel: 0 2px 20px rgba(0,0,0,0.5);
67
- --shadow-elevated: 0 4px 30px rgba(0,0,0,0.4);
68
- --shadow-menu: 0 8px 40px rgba(0,0,0,0.6);
69
- --shadow-modal: 0 16px 64px rgba(0,0,0,0.6);
70
-
71
- /* Radii */
72
- --radius-sm: 8px;
73
- --radius-md: 12px;
74
- --radius-lg: 16px;
75
- --radius-full: 50%;
76
- }
77
-
78
- body {
79
- background: var(--bg-primary);
80
- color: var(--text-primary);
81
- font-family: var(--font-sans);
82
- font-size: var(--font-body);
83
- overflow: hidden;
84
- height: 100vh;
85
- -webkit-font-smoothing: antialiased;
86
- -moz-osx-font-smoothing: grayscale;
87
- }
88
-
89
- canvas { display: block; cursor: grab; }
90
- canvas.dragging { cursor: grabbing; }
91
-
92
-
93
- /* ============================================================================
94
- SEARCH BAR
95
- ============================================================================ */
96
-
97
- #search-bar {
98
- position: fixed;
99
- top: 20px;
100
- left: 50%;
101
- transform: translateX(-50%);
102
- z-index: 100;
103
- display: flex;
104
- align-items: center;
105
- gap: 10px;
106
- background: var(--bg-secondary);
107
- border: none;
108
- border-radius: var(--radius-md);
109
- padding: 10px 18px;
110
- height: 42px;
111
- max-width: 480px;
112
- width: 400px;
113
- box-shadow: var(--shadow-elevated);
114
- }
115
-
116
- #search-bar input {
117
- background: transparent;
118
- border: none;
119
- outline: none;
120
- color: var(--text-primary);
121
- font-size: 12px;
122
- font-weight: 500;
123
- flex: 1;
124
- font-family: var(--font-sans);
125
- min-width: 0;
126
- }
127
-
128
- #search-bar input::placeholder {
129
- color: var(--text-muted);
130
- }
131
-
132
- #search-bar .stats {
133
- color: var(--text-secondary);
134
- font-size: var(--font-small);
135
- font-family: var(--font-mono);
136
- font-weight: 600;
137
- white-space: nowrap;
138
- flex-shrink: 0;
139
- }
140
-
141
- #search-bar svg {
142
- flex-shrink: 0;
143
- opacity: 0.5;
144
- }
145
-
146
- #refresh-btn {
147
- background: transparent;
148
- border: none;
149
- border-radius: var(--radius-full);
150
- width: 36px;
151
- height: 36px;
152
- padding: 0;
153
- cursor: pointer;
154
- color: var(--text-muted);
155
- display: flex;
156
- align-items: center;
157
- justify-content: center;
158
- transition: all 0.2s;
159
- flex-shrink: 0;
160
- }
161
-
162
- #refresh-btn:hover {
163
- color: var(--accent);
164
- background: var(--accent-dim);
165
- }
166
-
167
- #refresh-btn.spinning svg {
168
- animation: spin 0.8s linear infinite;
169
- }
170
-
171
- #refresh-btn.spinning {
172
- pointer-events: none;
173
- opacity: 0.7;
174
- }
175
-
176
- #refresh-btn.refresh-done {
177
- color: #a6e3a1;
178
- background: rgba(166,227,161,0.1);
179
- }
180
-
181
- #refresh-btn.refresh-error {
182
- color: #f38ba8;
183
- background: rgba(243,139,168,0.1);
184
- }
185
-
186
- @keyframes spin {
187
- from { transform: rotate(0deg); }
188
- to { transform: rotate(360deg); }
189
- }
190
-
191
-
192
- /* ============================================================================
193
- VIEW TABS — floating transparent row, top-left
194
- ============================================================================ */
195
-
196
- #view-tabs {
197
- position: fixed;
198
- top: 20px;
199
- left: 20px;
200
- z-index: 100;
201
- display: flex;
202
- gap: 4px;
203
- background: transparent;
204
- border: none;
205
- border-radius: 0;
206
- padding: 0;
207
- }
208
-
209
- #view-tabs button {
210
- background: transparent;
211
- border: none;
212
- border-bottom: 2px solid transparent;
213
- color: var(--text-muted);
214
- font-size: var(--font-micro);
215
- font-weight: 700;
216
- padding: 8px 14px;
217
- text-transform: uppercase;
218
- letter-spacing: 0.1em;
219
- border-radius: 0;
220
- cursor: pointer;
221
- transition: all 0.2s;
222
- font-family: var(--font-sans);
223
- }
224
-
225
- #view-tabs button:hover {
226
- color: var(--text-secondary);
227
- }
228
-
229
- #view-tabs button.active {
230
- color: var(--text-primary);
231
- border-bottom-color: var(--accent);
232
- font-weight: 700;
233
- }
234
-
235
-
236
- /* ============================================================================
237
- CATEGORY PANEL
238
- ============================================================================ */
239
-
240
- #category-panel {
241
- position: fixed;
242
- top: 80px;
243
- left: 20px;
244
- z-index: 50;
245
- background: rgba(16, 19, 25, 0.72);
246
- border: 1px solid var(--border);
247
- backdrop-filter: blur(8px);
248
- -webkit-backdrop-filter: blur(8px);
249
- border-radius: var(--radius-lg);
250
- padding: var(--space-md);
251
- min-width: 110px;
252
- max-width: 170px;
253
- width: 170px;
254
- max-height: calc(100vh - 130px);
255
- overflow-y: auto;
256
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
257
- font-size: var(--font-small);
258
- }
259
-
260
- #category-panel::-webkit-scrollbar { width: 3px; }
261
- #category-panel::-webkit-scrollbar-track { background: transparent; }
262
- #category-panel::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 2px; }
263
-
264
- .cat-header {
265
- display: flex;
266
- align-items: center;
267
- justify-content: space-between;
268
- padding-bottom: var(--space-sm);
269
- margin-bottom: var(--space-sm);
270
- }
271
-
272
- .cat-title {
273
- font-weight: 800;
274
- color: var(--text-primary);
275
- font-size: 24px;
276
- letter-spacing: -0.03em;
277
- }
278
-
279
- .cat-controls {
280
- display: flex;
281
- gap: 4px;
282
- }
283
-
284
- .cat-mode-btn,
285
- .cat-all-btn {
286
- background: transparent;
287
- border: none;
288
- color: var(--text-muted);
289
- border-radius: var(--radius-sm);
290
- cursor: pointer;
291
- display: flex;
292
- align-items: center;
293
- justify-content: center;
294
- transition: all 0.15s;
295
- }
296
-
297
- .cat-mode-btn {
298
- width: 18px;
299
- height: 18px;
300
- padding: 0;
301
- }
302
-
303
- .cat-all-btn {
304
- padding: 4px 8px;
305
- font-size: var(--font-micro);
306
- font-weight: 600;
307
- text-transform: uppercase;
308
- letter-spacing: 0.06em;
309
- }
310
-
311
- .cat-mode-btn:hover,
312
- .cat-all-btn:hover {
313
- background: var(--bg-hover);
314
- color: var(--text-primary);
315
- }
316
-
317
- .cat-mode-btn.active {
318
- background: rgba(122, 162, 247, 0.15);
319
- color: #7aa2f7;
320
- }
321
-
322
- .cat-item {
323
- display: flex;
324
- align-items: center;
325
- gap: 6px;
326
- padding: 7px var(--space-xs);
327
- border-radius: var(--radius-sm);
328
- cursor: pointer;
329
- transition: background 0.12s;
330
- user-select: none;
331
- }
332
-
333
- .cat-item:hover {
334
- background: var(--bg-hover);
335
- }
336
-
337
- .cat-item.inactive {
338
- opacity: 0.3;
339
- }
340
-
341
- .cat-dot {
342
- width: 6px;
343
- height: 6px;
344
- border-radius: var(--radius-full);
345
- flex-shrink: 0;
346
- }
347
-
348
- .cat-label {
349
- flex: 1;
350
- color: var(--text-primary);
351
- font-size: var(--font-micro);
352
- font-weight: 400;
353
- text-transform: uppercase;
354
- letter-spacing: 0.05em;
355
- white-space: nowrap;
356
- overflow: hidden;
357
- text-overflow: ellipsis;
358
- }
359
-
360
- .cat-count {
361
- color: var(--text-secondary);
362
- font-size: 10px;
363
- font-family: var(--font-mono);
364
- font-weight: 600;
365
- flex-shrink: 0;
366
- }
367
-
368
-
369
- /* ============================================================================
370
- CHANGES PANEL
371
- ============================================================================ */
372
-
373
- #changes-panel {
374
- position: fixed;
375
- top: 80px;
376
- left: 218px;
377
- z-index: 50;
378
- background: rgba(16, 19, 25, 0.72);
379
- border: 1px solid var(--border);
380
- backdrop-filter: blur(8px);
381
- -webkit-backdrop-filter: blur(8px);
382
- border-radius: var(--radius-md);
383
- padding: var(--space-sm);
384
- min-width: 90px;
385
- max-width: 130px;
386
- width: 130px;
387
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
388
- font-size: var(--font-micro);
389
- }
390
-
391
- .changes-header {
392
- display: flex;
393
- align-items: center;
394
- justify-content: space-between;
395
- padding-bottom: var(--space-xs);
396
- margin-bottom: var(--space-xs);
397
- }
398
-
399
- .changes-title {
400
- font-weight: 800;
401
- color: var(--text-primary);
402
- font-size: 18px;
403
- letter-spacing: -0.03em;
404
- }
405
-
406
- /* Toggle switch for changes */
407
- .changes-toggle {
408
- position: relative;
409
- display: inline-block;
410
- width: 22px;
411
- height: 12px;
412
- cursor: pointer;
413
- }
414
-
415
- .changes-toggle input {
416
- opacity: 0;
417
- width: 0;
418
- height: 0;
419
- }
420
-
421
- .changes-toggle-slider {
422
- position: absolute;
423
- cursor: pointer;
424
- top: 0;
425
- left: 0;
426
- right: 0;
427
- bottom: 0;
428
- background-color: var(--bg-tertiary);
429
- border-radius: 12px;
430
- transition: 0.15s;
431
- }
432
-
433
- .changes-toggle-slider::before {
434
- position: absolute;
435
- content: "";
436
- height: 8px;
437
- width: 8px;
438
- left: 2px;
439
- bottom: 2px;
440
- background-color: var(--text-muted);
441
- border-radius: var(--radius-full);
442
- transition: 0.15s;
443
- }
444
-
445
- .changes-toggle input:checked + .changes-toggle-slider {
446
- background-color: rgba(249, 226, 175, 0.3);
447
- }
448
-
449
- .changes-toggle input:checked + .changes-toggle-slider::before {
450
- background-color: #f9e2af;
451
- transform: translateX(10px);
452
- }
453
-
454
- .changes-stats {
455
- margin-bottom: 2px;
456
- }
457
-
458
- .changes-stat-row {
459
- display: flex;
460
- align-items: center;
461
- gap: 5px;
462
- padding: 5px var(--space-xs);
463
- border-radius: var(--radius-sm);
464
- cursor: pointer;
465
- transition: background 0.12s;
466
- user-select: none;
467
- }
468
-
469
- .changes-stat-row:hover {
470
- background: var(--bg-hover);
471
- }
472
-
473
- .changes-stat-row.active {
474
- background: var(--bg-tertiary);
475
- }
476
-
477
- .changes-dot {
478
- width: 5px;
479
- height: 5px;
480
- border-radius: var(--radius-full);
481
- flex-shrink: 0;
482
- }
483
-
484
- .changes-label {
485
- flex: 1;
486
- color: var(--text-secondary);
487
- font-size: var(--font-micro);
488
- font-weight: 400;
489
- text-transform: uppercase;
490
- letter-spacing: 0.05em;
491
- }
492
-
493
- .changes-count {
494
- color: var(--text-secondary);
495
- font-size: 9px;
496
- font-family: var(--font-mono);
497
- font-weight: 600;
498
- flex-shrink: 0;
499
- }
500
-
501
- .changes-total {
502
- font-size: 8px;
503
- font-weight: 500;
504
- color: var(--text-muted);
505
- text-align: center;
506
- padding-top: 3px;
507
- text-transform: uppercase;
508
- letter-spacing: 0.08em;
509
- }
510
-
511
-
512
- /* ============================================================================
513
- LEGEND — minimal horizontal row, bottom-left
514
- ============================================================================ */
515
-
516
- #legend {
517
- position: fixed;
518
- bottom: 20px;
519
- left: 20px;
520
- z-index: 100;
521
- background: rgba(8,9,10,0.7);
522
- backdrop-filter: blur(8px);
523
- -webkit-backdrop-filter: blur(8px);
524
- border: none;
525
- border-radius: var(--radius-sm);
526
- padding: 10px 16px;
527
- font-size: var(--font-micro);
528
- display: flex;
529
- gap: 24px;
530
- align-items: center;
531
- }
532
-
533
- #legend .item {
534
- display: flex;
535
- align-items: center;
536
- gap: 10px;
537
- color: var(--text-secondary);
538
- margin-bottom: 0;
539
- }
540
-
541
- #legend .item:last-child { margin-bottom: 0; }
542
-
543
- #legend .line {
544
- width: 28px;
545
- height: 2px;
546
- border-radius: 1px;
547
- }
548
-
549
- #legend.hidden { display: none; }
550
-
551
-
552
- /* ============================================================================
553
- ZOOM INDICATOR — minimal, after legend
554
- ============================================================================ */
555
-
556
- #zoom-indicator {
557
- position: fixed;
558
- bottom: 20px;
559
- left: 280px;
560
- z-index: 100;
561
- background: transparent;
562
- border: none;
563
- border-radius: var(--radius-sm);
564
- padding: 8px 12px;
565
- font-size: 14px;
566
- display: flex;
567
- align-items: center;
568
- gap: 8px;
569
- cursor: pointer;
570
- transition: all 0.2s;
571
- }
572
-
573
- #zoom-indicator:hover {
574
- background: var(--bg-hover);
575
- }
576
-
577
- #zoom-indicator.faded { opacity: 0.4; }
578
- #zoom-indicator.faded:hover { opacity: 1; }
579
-
580
- #zoom-indicator svg {
581
- flex-shrink: 0;
582
- cursor: pointer;
583
- opacity: 0.5;
584
- }
585
-
586
- #zoom-indicator svg:hover {
587
- stroke: var(--text-primary);
588
- opacity: 1;
589
- }
590
-
591
- #zoom-indicator .zoom-input {
592
- background: transparent;
593
- border: none;
594
- color: var(--text-secondary);
595
- font-weight: 600;
596
- font-size: 16px;
597
- font-family: var(--font-mono);
598
- width: 54px;
599
- text-align: center;
600
- padding: 2px 0;
601
- cursor: text;
602
- }
603
-
604
- #zoom-indicator .zoom-input:focus {
605
- outline: none;
606
- background: var(--bg-tertiary);
607
- border-radius: 4px;
608
- color: var(--text-primary);
609
- }
610
-
611
-
612
- /* ============================================================================
613
- DETAIL PANEL
614
- ============================================================================ */
615
-
616
- #detail-panel {
617
- position: fixed;
618
- top: 0;
619
- right: -440px;
620
- width: 420px;
621
- min-width: 300px;
622
- max-width: 80vw;
623
- height: 100vh;
624
- background: var(--bg-primary);
625
- border-left: 1px solid var(--border);
626
- z-index: 200;
627
- overflow-y: auto;
628
- transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);
629
- box-shadow: -8px 0 40px rgba(0,0,0,0.5);
630
- }
631
-
632
- #detail-panel.open { right: 0; }
633
- #detail-panel.resizing { transition: none; }
634
-
635
- /* Horizontal resize handle */
636
- #panel-resize-handle {
637
- position: absolute;
638
- left: -4px;
639
- top: 0;
640
- width: 8px;
641
- height: 100%;
642
- cursor: col-resize;
643
- z-index: 201;
644
- }
645
-
646
- #panel-resize-handle::after {
647
- content: '';
648
- position: absolute;
649
- left: 3px;
650
- top: 50%;
651
- transform: translateY(-50%);
652
- width: 3px;
653
- height: 50px;
654
- background: var(--border-light);
655
- border-radius: 2px;
656
- opacity: 0;
657
- transition: opacity 0.2s;
658
- }
659
-
660
- #panel-resize-handle:hover::after,
661
- #detail-panel.resizing #panel-resize-handle::after {
662
- opacity: 1;
663
- background: var(--accent);
664
- }
665
-
666
- #detail-panel::-webkit-scrollbar { width: 4px; }
667
- #detail-panel::-webkit-scrollbar-track { background: transparent; }
668
- #detail-panel::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.06); border-radius: 2px; }
669
-
670
- .panel-header {
671
- position: sticky;
672
- top: 0;
673
- background: var(--bg-primary);
674
- padding: var(--space-md) 22px;
675
- z-index: 10;
676
- border-bottom: 1px solid var(--border);
677
- }
678
-
679
- .panel-header h2 {
680
- font-size: 30px;
681
- font-weight: 800;
682
- color: var(--accent-light);
683
- margin-bottom: 6px;
684
- padding-right: 48px;
685
- line-height: 1.3;
686
- letter-spacing: -0.03em;
687
- }
688
-
689
- .panel-header .path {
690
- font-size: var(--font-micro);
691
- color: var(--text-muted);
692
- font-family: var(--font-mono);
693
- word-break: break-all;
694
- }
695
-
696
- .close-btn {
697
- position: absolute;
698
- top: 14px;
699
- right: 14px;
700
- background: transparent;
701
- border: none;
702
- color: var(--text-muted);
703
- width: 30px;
704
- height: 30px;
705
- border-radius: var(--radius-sm);
706
- cursor: pointer;
707
- font-size: 18px;
708
- display: flex;
709
- align-items: center;
710
- justify-content: center;
711
- transition: all 0.15s;
712
- }
713
-
714
- .close-btn:hover {
715
- background: var(--bg-hover);
716
- color: var(--text-primary);
717
- }
718
-
719
- .panel-body {
720
- padding: var(--space-md) 22px var(--space-lg);
721
- }
722
-
723
- /* Description block */
724
- .desc-block {
725
- font-size: var(--font-body);
726
- color: var(--text-secondary);
727
- margin-bottom: var(--space-lg);
728
- padding: var(--space-md) var(--space-lg);
729
- background: var(--bg-secondary);
730
- border-radius: var(--radius-md);
731
- border-left: 3px solid var(--accent);
732
- line-height: 1.6;
733
- }
734
-
735
- /* Meta row */
736
- .meta-row {
737
- display: flex;
738
- gap: 10px;
739
- margin-bottom: var(--space-lg);
740
- flex-wrap: wrap;
741
- }
742
-
743
- .meta-badge {
744
- background: var(--bg-secondary);
745
- border: none;
746
- padding: 6px 10px;
747
- border-radius: var(--radius-sm);
748
- font-size: var(--font-micro);
749
- color: var(--text-secondary);
750
- }
751
-
752
- .meta-badge span {
753
- color: var(--accent-light);
754
- font-weight: 600;
755
- font-family: var(--font-mono);
756
- }
757
-
758
- .meta-badge.script-badge {
759
- cursor: pointer;
760
- transition: background 0.12s;
761
- }
762
-
763
- .meta-badge.script-badge:hover {
764
- background: var(--bg-tertiary);
765
- }
766
-
767
-
768
- /* ============================================================================
769
- SECTIONS (detail panel content)
770
- ============================================================================ */
771
-
772
- .section {
773
- margin-bottom: var(--space-lg);
774
- }
775
-
776
- .section .item-list {
777
- /* No max-height — show all items */
778
- }
779
-
780
- .section-resize-handle {
781
- position: relative;
782
- height: 12px;
783
- cursor: row-resize;
784
- z-index: 5;
785
- margin: 4px 0;
786
- display: flex;
787
- align-items: center;
788
- justify-content: center;
789
- }
790
-
791
- .section-resize-handle::after {
792
- content: '';
793
- width: 40px;
794
- height: 3px;
795
- background: var(--border-light);
796
- border-radius: 2px;
797
- opacity: 0.3;
798
- transition: opacity 0.2s;
799
- }
800
-
801
- .section-resize-handle:hover::after,
802
- .section.resizing .section-resize-handle::after {
803
- opacity: 1;
804
- background: var(--accent);
805
- }
806
-
807
- .section-header {
808
- display: flex;
809
- align-items: center;
810
- justify-content: space-between;
811
- font-size: 16px;
812
- font-weight: 700;
813
- color: var(--text-primary);
814
- padding-bottom: var(--space-sm);
815
- margin-bottom: var(--space-sm);
816
- border-bottom: none;
817
- text-transform: none;
818
- letter-spacing: -0.01em;
819
- }
820
-
821
- .section-count {
822
- background: transparent;
823
- color: var(--accent);
824
- padding: 0;
825
- border-radius: 0;
826
- font-size: 16px;
827
- font-family: var(--font-mono);
828
- font-weight: 700;
829
- }
830
-
831
- .item-list { list-style: none; }
832
-
833
- .item-list li {
834
- padding: 6px 8px;
835
- border-radius: var(--radius-sm);
836
- margin-bottom: 2px;
837
- font-size: 11px;
838
- font-family: var(--font-mono);
839
- cursor: default;
840
- display: flex;
841
- align-items: center;
842
- gap: 6px;
843
- line-height: 1.35;
844
- min-width: 0;
845
- }
846
-
847
- #exports-list li,
848
- #vars-list li,
849
- #signals-list li,
850
- .section .item-list li.clickable {
851
- overflow-x: auto;
852
- overflow-y: hidden;
853
- white-space: nowrap;
854
- }
855
-
856
- #exports-list li::-webkit-scrollbar,
857
- #vars-list li::-webkit-scrollbar,
858
- #signals-list li::-webkit-scrollbar,
859
- .section .item-list li.clickable::-webkit-scrollbar {
860
- height: 4px;
861
- }
862
-
863
- #exports-list li::-webkit-scrollbar-thumb,
864
- #vars-list li::-webkit-scrollbar-thumb,
865
- #signals-list li::-webkit-scrollbar-thumb,
866
- .section .item-list li.clickable::-webkit-scrollbar-thumb {
867
- background: rgba(255,255,255,0.12);
868
- border-radius: 2px;
869
- }
870
-
871
- .item-list li:hover { background: var(--bg-secondary); }
872
- .item-list li.clickable { cursor: pointer; }
873
- .item-list li.clickable:hover { background: var(--bg-tertiary); }
874
-
875
- /* Scene usage list */
876
- .scene-usage-section { margin-bottom: var(--space-lg); }
877
-
878
- .scene-list li.scene-link {
879
- cursor: pointer;
880
- font-family: var(--font-sans);
881
- }
882
-
883
- .scene-list li.scene-link:hover {
884
- background: rgba(166, 227, 161, 0.08);
885
- }
886
-
887
- .scene-list .scene-icon {
888
- font-size: 16px;
889
- }
890
-
891
- .scene-list .scene-name {
892
- color: #a6e3a1;
893
- font-weight: 500;
894
- }
895
-
896
- /* Inline editable items */
897
- .item-list li .item-actions {
898
- margin-left: auto;
899
- display: flex;
900
- gap: 4px;
901
- opacity: 0;
902
- transition: opacity 0.15s;
903
- flex-shrink: 0;
904
- }
905
-
906
- .item-list li:hover .item-actions { opacity: 1; }
907
- .item-list li:hover .delete { opacity: 1 !important; }
908
-
909
- .item-actions button {
910
- background: var(--bg-tertiary);
911
- border: none;
912
- color: var(--text-muted);
913
- width: 26px;
914
- height: 26px;
915
- border-radius: 6px;
916
- cursor: pointer;
917
- font-size: var(--font-small);
918
- display: flex;
919
- align-items: center;
920
- justify-content: center;
921
- }
922
-
923
- .item-actions button:hover {
924
- background: var(--bg-hover);
925
- color: var(--text-primary);
926
- }
927
-
928
- .item-actions button.delete:hover {
929
- background: rgba(243,139,168,0.15);
930
- color: #f38ba8;
931
- }
932
-
933
- /* Inline editable spans */
934
- .editable {
935
- cursor: text;
936
- padding: 2px 6px;
937
- margin: -2px -6px;
938
- border-radius: 4px;
939
- transition: background 0.15s;
940
- min-width: 20px;
941
- display: inline-block;
942
- }
943
-
944
- .editable:hover { background: rgba(255,255,255,0.06); }
945
-
946
- .editable:focus {
947
- outline: none;
948
- background: rgba(255,255,255,0.1);
949
- box-shadow: 0 0 0 1px var(--accent);
950
- }
951
-
952
- .editable[data-placeholder]:empty::before {
953
- content: attr(data-placeholder);
954
- color: var(--text-muted);
955
- opacity: 0.5;
956
- }
957
-
958
- /* @onready badge */
959
- .onready-badge {
960
- display: inline-block;
961
- font-size: var(--font-micro);
962
- padding: 3px 7px;
963
- background: rgba(137, 180, 250, 0.15);
964
- color: #89b4fa;
965
- border-radius: 4px;
966
- margin-right: 8px;
967
- font-weight: 500;
968
- cursor: pointer;
969
- user-select: none;
970
- text-transform: uppercase;
971
- letter-spacing: 1px;
972
- }
973
-
974
- .onready-badge:hover { background: rgba(137, 180, 250, 0.25); }
975
-
976
- .onready-badge.inactive {
977
- background: rgba(255,255,255,0.04);
978
- color: var(--text-muted);
979
- opacity: 0.5;
980
- }
981
-
982
-
983
- /* ============================================================================
984
- CONTEXT MENUS
985
- ============================================================================ */
986
-
987
- #context-menu {
988
- position: fixed;
989
- z-index: 500;
990
- background: var(--bg-secondary);
991
- border: none;
992
- border-radius: var(--radius-md);
993
- padding: 8px 0;
994
- min-width: 200px;
995
- box-shadow: var(--shadow-menu);
996
- display: none;
997
- }
998
-
999
- #context-menu.visible { display: block; }
1000
-
1001
- #context-menu .menu-item {
1002
- display: flex;
1003
- align-items: center;
1004
- gap: 12px;
1005
- padding: 12px 18px;
1006
- font-size: var(--font-body);
1007
- color: var(--text-secondary);
1008
- cursor: pointer;
1009
- transition: background 0.1s;
1010
- }
1011
-
1012
- #context-menu .menu-item:hover {
1013
- background: var(--bg-hover);
1014
- color: var(--text-primary);
1015
- }
1016
-
1017
- #context-menu .menu-item svg { flex-shrink: 0; opacity: 0.6; }
1018
-
1019
- #context-menu .menu-divider {
1020
- height: 1px;
1021
- background: var(--border);
1022
- margin: 6px 12px;
1023
- }
1024
-
1025
- /* Scene Context Menu */
1026
- #scene-context-menu {
1027
- position: fixed;
1028
- z-index: 500;
1029
- background: var(--bg-secondary);
1030
- border: none;
1031
- border-radius: var(--radius-md);
1032
- padding: 8px 0;
1033
- min-width: 200px;
1034
- box-shadow: var(--shadow-menu);
1035
- display: none;
1036
- }
1037
-
1038
- #scene-context-menu.visible { display: block; }
1039
-
1040
- #scene-context-menu .menu-item {
1041
- display: flex;
1042
- align-items: center;
1043
- gap: 12px;
1044
- padding: 12px 18px;
1045
- font-size: var(--font-body);
1046
- color: var(--text-secondary);
1047
- cursor: pointer;
1048
- transition: background 0.1s;
1049
- }
1050
-
1051
- #scene-context-menu .menu-item:hover {
1052
- background: var(--bg-hover);
1053
- color: var(--text-primary);
1054
- }
1055
-
1056
- #scene-context-menu .menu-item.danger { color: #f38ba8; }
1057
- #scene-context-menu .menu-item.danger:hover { background: rgba(243, 139, 168, 0.1); }
1058
-
1059
- #scene-context-menu .menu-item svg { flex-shrink: 0; opacity: 0.6; }
1060
-
1061
- #scene-context-menu .menu-divider {
1062
- height: 1px;
1063
- background: var(--border);
1064
- margin: 6px 12px;
1065
- }
1066
-
1067
-
1068
- /* ============================================================================
1069
- MODALS
1070
- ============================================================================ */
1071
-
1072
- .modal {
1073
- position: fixed;
1074
- top: 0;
1075
- left: 0;
1076
- right: 0;
1077
- bottom: 0;
1078
- background: rgba(0,0,0,0.7);
1079
- z-index: 600;
1080
- display: flex;
1081
- align-items: center;
1082
- justify-content: center;
1083
- backdrop-filter: blur(4px);
1084
- -webkit-backdrop-filter: blur(4px);
1085
- }
1086
-
1087
- .modal-content {
1088
- background: var(--bg-secondary);
1089
- border: none;
1090
- border-radius: var(--radius-lg);
1091
- width: 420px;
1092
- box-shadow: var(--shadow-modal);
1093
- overflow: hidden;
1094
- }
1095
-
1096
- .modal-header {
1097
- display: flex;
1098
- align-items: center;
1099
- justify-content: space-between;
1100
- padding: var(--space-lg);
1101
- }
1102
-
1103
- .modal-header h3 {
1104
- font-size: 22px;
1105
- font-weight: 700;
1106
- color: var(--text-primary);
1107
- letter-spacing: -0.02em;
1108
- }
1109
-
1110
- .modal-body {
1111
- padding: 0 var(--space-lg) var(--space-lg);
1112
- }
1113
-
1114
- .modal-body .form-group {
1115
- margin-bottom: var(--space-lg);
1116
- }
1117
-
1118
- .modal-body .form-group:last-child { margin-bottom: 0; }
1119
-
1120
- .modal-body label {
1121
- display: block;
1122
- font-size: var(--font-small);
1123
- color: var(--text-secondary);
1124
- margin-bottom: var(--space-xs);
1125
- font-weight: 500;
1126
- }
1127
-
1128
- .modal-body input,
1129
- .modal-body select {
1130
- width: 100%;
1131
- background: var(--bg-tertiary);
1132
- border: 1px solid var(--border);
1133
- border-radius: var(--radius-sm);
1134
- padding: 12px var(--space-md);
1135
- font-size: var(--font-body);
1136
- color: var(--text-primary);
1137
- font-family: var(--font-mono);
1138
- transition: border-color 0.15s;
1139
- }
1140
-
1141
- .modal-body input:focus,
1142
- .modal-body select:focus {
1143
- outline: none;
1144
- border-color: var(--accent);
1145
- }
1146
-
1147
- .modal-footer {
1148
- display: flex;
1149
- justify-content: flex-end;
1150
- gap: 12px;
1151
- padding: var(--space-lg);
1152
- background: var(--bg-tertiary);
1153
- }
1154
-
1155
- .modal-footer button {
1156
- padding: 10px 20px;
1157
- border-radius: var(--radius-sm);
1158
- font-size: var(--font-body);
1159
- cursor: pointer;
1160
- border: none;
1161
- font-weight: 500;
1162
- transition: all 0.15s;
1163
- }
1164
-
1165
- .modal-footer .cancel {
1166
- background: var(--bg-secondary);
1167
- color: var(--text-secondary);
1168
- }
1169
-
1170
- .modal-footer .cancel:hover {
1171
- background: var(--bg-hover);
1172
- }
1173
-
1174
- .modal-footer .confirm {
1175
- background: var(--accent);
1176
- color: var(--bg-primary);
1177
- }
1178
-
1179
- .modal-footer .confirm:hover {
1180
- background: var(--accent-light);
1181
- }
1182
-
1183
-
1184
- /* ============================================================================
1185
- TIMELINE / ACTIVITY PANEL
1186
- ============================================================================ */
1187
-
1188
- #timeline-panel {
1189
- position: fixed;
1190
- bottom: 20px;
1191
- right: 20px;
1192
- z-index: 50;
1193
- background: rgba(16, 19, 25, 0.72);
1194
- border: 1px solid var(--border);
1195
- backdrop-filter: blur(8px);
1196
- -webkit-backdrop-filter: blur(8px);
1197
- border-radius: var(--radius-lg);
1198
- width: 250px;
1199
- max-width: 250px;
1200
- max-height: calc(100vh - 40px);
1201
- box-shadow: 0 10px 28px rgba(0, 0, 0, 0.3);
1202
- font-size: var(--font-body);
1203
- display: flex;
1204
- flex-direction: column;
1205
- overflow: hidden;
1206
- padding: var(--space-lg);
1207
- }
1208
-
1209
- #timeline-panel.collapsed .tl-body {
1210
- display: none;
1211
- }
1212
-
1213
- #timeline-panel.collapsed .tl-chevron {
1214
- transform: rotate(-90deg);
1215
- }
1216
-
1217
- .tl-header {
1218
- display: flex;
1219
- align-items: center;
1220
- gap: 8px;
1221
- padding: var(--space-sm) var(--space-md);
1222
- padding-bottom: var(--space-md);
1223
- margin-bottom: var(--space-md);
1224
- cursor: pointer;
1225
- user-select: none;
1226
- transition: background 0.12s;
1227
- }
1228
-
1229
- .tl-header:hover {
1230
- background: var(--bg-hover);
1231
- }
1232
-
1233
- .tl-title {
1234
- font-weight: 800;
1235
- color: var(--text-primary);
1236
- font-size: var(--font-h1);
1237
- flex: 1;
1238
- text-transform: none;
1239
- letter-spacing: -0.03em;
1240
- }
1241
-
1242
- .tl-count {
1243
- background: transparent;
1244
- color: var(--text-secondary);
1245
- padding: 0;
1246
- border-radius: 0;
1247
- font-size: 13px;
1248
- font-family: var(--font-mono);
1249
- font-weight: 600;
1250
- }
1251
-
1252
- .tl-chevron {
1253
- color: var(--text-muted);
1254
- transition: transform 0.2s;
1255
- flex-shrink: 0;
1256
- }
1257
-
1258
- .tl-body {
1259
- overflow-y: auto;
1260
- max-height: calc(100vh - 170px);
1261
- }
1262
-
1263
- .tl-body::-webkit-scrollbar { width: 3px; }
1264
- .tl-body::-webkit-scrollbar-track { background: transparent; }
1265
- .tl-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.06); border-radius: 2px; }
1266
-
1267
- .tl-empty {
1268
- padding: var(--space-xl) var(--space-lg);
1269
- text-align: center;
1270
- color: var(--text-muted);
1271
- font-size: var(--font-body);
1272
- font-style: italic;
1273
- }
1274
-
1275
- .tl-list {
1276
- padding: var(--space-xs) 0;
1277
- }
1278
-
1279
- /* File-grouped card */
1280
- .tl-card {
1281
- margin: 6px var(--space-sm);
1282
- background: var(--bg-surface);
1283
- border: none;
1284
- border-radius: var(--radius-sm);
1285
- overflow: hidden;
1286
- box-shadow: 0 1px 4px rgba(0,0,0,0.2);
1287
- }
1288
-
1289
- .tl-card-header {
1290
- display: flex;
1291
- align-items: center;
1292
- gap: 8px;
1293
- padding: 10px var(--space-sm);
1294
- background: var(--bg-tertiary);
1295
- font-size: var(--font-small);
1296
- cursor: pointer;
1297
- transition: background 0.1s;
1298
- }
1299
-
1300
- .tl-card-header:hover {
1301
- background: var(--bg-hover);
1302
- }
1303
-
1304
- .tl-card-file {
1305
- color: var(--accent-light);
1306
- font-weight: 600;
1307
- font-size: var(--font-body);
1308
- flex: 1;
1309
- overflow: hidden;
1310
- text-overflow: ellipsis;
1311
- white-space: nowrap;
1312
- }
1313
-
1314
- .tl-card-time {
1315
- color: var(--text-muted);
1316
- font-size: var(--font-micro);
1317
- font-family: var(--font-mono);
1318
- flex-shrink: 0;
1319
- }
1320
-
1321
- /* Action items within a card */
1322
- .tl-action {
1323
- display: flex;
1324
- align-items: flex-start;
1325
- gap: 10px;
1326
- padding: 10px var(--space-sm);
1327
- font-size: var(--font-body);
1328
- border-bottom: 1px solid var(--border);
1329
- transition: background 0.1s;
1330
- cursor: pointer;
1331
- }
1332
-
1333
- .tl-action:last-child {
1334
- border-bottom: none;
1335
- }
1336
-
1337
- .tl-action:hover {
1338
- background: rgba(255, 255, 255, 0.02);
1339
- }
1340
-
1341
- .tl-action-icon {
1342
- font-size: var(--font-body);
1343
- flex-shrink: 0;
1344
- line-height: 1.4;
1345
- }
1346
-
1347
- .tl-action-text {
1348
- color: var(--text-secondary);
1349
- flex: 1;
1350
- line-height: 1.5;
1351
- font-size: var(--font-small);
1352
- }
1353
-
1354
- .tl-action-text .tl-name {
1355
- color: var(--accent-light);
1356
- font-weight: 500;
1357
- }
1358
-
1359
- .tl-action-reason {
1360
- font-size: var(--font-small);
1361
- color: var(--text-muted);
1362
- font-style: italic;
1363
- margin-top: 4px;
1364
- line-height: 1.4;
1365
- }
1366
-
1367
- .tl-action-time {
1368
- color: var(--text-muted);
1369
- font-size: var(--font-micro);
1370
- font-family: var(--font-mono);
1371
- flex-shrink: 0;
1372
- margin-top: 2px;
1373
- }
1374
-
1375
-
1376
- /* ============================================================================
1377
- FLOATING USAGE PANEL
1378
- ============================================================================ */
1379
-
1380
- #usage-float-panel {
1381
- position: fixed;
1382
- top: 80px;
1383
- right: 500px;
1384
- width: 400px;
1385
- min-width: 320px;
1386
- min-height: 260px;
1387
- max-height: calc(100vh - 100px);
1388
- background: var(--bg-secondary);
1389
- border: none;
1390
- border-radius: var(--radius-lg);
1391
- box-shadow: var(--shadow-menu);
1392
- z-index: 150;
1393
- display: none;
1394
- flex-direction: column;
1395
- overflow: hidden;
1396
- }
1397
-
1398
- #usage-float-panel.visible { display: flex; }
1399
- #usage-float-panel.dragging { user-select: none; }
1400
-
1401
- /* Resize handle */
1402
- #usage-float-panel .ufp-resize {
1403
- position: absolute;
1404
- bottom: 0;
1405
- right: 0;
1406
- width: 18px;
1407
- height: 18px;
1408
- cursor: nwse-resize;
1409
- z-index: 10;
1410
- }
1411
-
1412
- #usage-float-panel .ufp-resize::after {
1413
- content: '';
1414
- position: absolute;
1415
- right: 5px;
1416
- bottom: 5px;
1417
- width: 8px;
1418
- height: 8px;
1419
- border-right: 2px solid var(--border-light);
1420
- border-bottom: 2px solid var(--border-light);
1421
- opacity: 0.4;
1422
- }
1423
-
1424
- #usage-float-panel .ufp-resize:hover::after { opacity: 0.8; }
1425
-
1426
- #usage-float-panel .ufp-header {
1427
- display: flex;
1428
- align-items: flex-start;
1429
- justify-content: space-between;
1430
- gap: var(--space-md);
1431
- padding: var(--space-md) var(--space-lg);
1432
- background: rgba(243, 139, 168, 0.08);
1433
- cursor: grab;
1434
- }
1435
-
1436
- #usage-float-panel .ufp-header:active { cursor: grabbing; }
1437
-
1438
- #usage-float-panel .ufp-header .ufp-info {
1439
- flex: 1;
1440
- min-width: 0;
1441
- }
1442
-
1443
- #usage-float-panel .ufp-header .ufp-title {
1444
- font-size: var(--font-h2);
1445
- font-weight: 600;
1446
- color: #f38ba8;
1447
- line-height: 1.3;
1448
- }
1449
-
1450
- #usage-float-panel .ufp-header .ufp-count {
1451
- font-size: var(--font-small);
1452
- color: var(--text-secondary);
1453
- margin-top: 6px;
1454
- line-height: 1.3;
1455
- }
1456
-
1457
- #usage-float-panel .ufp-header .ufp-count .count-num {
1458
- font-weight: 700;
1459
- font-size: var(--font-body);
1460
- font-family: var(--font-mono);
1461
- color: #fab387;
1462
- }
1463
-
1464
- #usage-float-panel .ufp-header .ufp-buttons {
1465
- display: flex;
1466
- gap: 6px;
1467
- align-items: center;
1468
- flex-shrink: 0;
1469
- }
1470
-
1471
- #usage-float-panel .ufp-header .refresh-btn,
1472
- #usage-float-panel .ufp-header .close-btn {
1473
- background: transparent;
1474
- border: none;
1475
- color: var(--text-muted);
1476
- width: 30px;
1477
- height: 30px;
1478
- border-radius: var(--radius-sm);
1479
- cursor: pointer;
1480
- font-size: var(--font-body);
1481
- display: flex;
1482
- align-items: center;
1483
- justify-content: center;
1484
- flex-shrink: 0;
1485
- transition: all 0.15s;
1486
- }
1487
-
1488
- #usage-float-panel .ufp-header .close-btn {
1489
- font-size: 18px;
1490
- }
1491
-
1492
- #usage-float-panel .ufp-header .refresh-btn:hover,
1493
- #usage-float-panel .ufp-header .close-btn:hover {
1494
- background: var(--bg-hover);
1495
- color: var(--text-primary);
1496
- }
1497
-
1498
- #usage-float-panel .ufp-list {
1499
- flex: 1;
1500
- overflow-y: auto;
1501
- max-height: 320px;
1502
- }
1503
-
1504
- #usage-float-panel .ufp-item {
1505
- display: flex;
1506
- flex-direction: column;
1507
- gap: 6px;
1508
- padding: var(--space-sm) var(--space-lg);
1509
- font-size: var(--font-small);
1510
- cursor: pointer;
1511
- border-bottom: 1px solid var(--border);
1512
- transition: background 0.1s;
1513
- }
1514
-
1515
- #usage-float-panel .ufp-item:last-child { border-bottom: none; }
1516
- #usage-float-panel .ufp-item:hover { background: var(--bg-hover); }
1517
-
1518
- #usage-float-panel .ufp-item.active {
1519
- background: var(--accent-dim);
1520
- border-left: 3px solid var(--accent);
1521
- margin-left: -3px;
1522
- padding-left: calc(var(--space-lg) - 3px);
1523
- }
1524
-
1525
- #usage-float-panel .ufp-item .ufp-loc {
1526
- display: flex;
1527
- align-items: center;
1528
- gap: 10px;
1529
- }
1530
-
1531
- #usage-float-panel .ufp-item .ufp-file {
1532
- color: var(--text-muted);
1533
- font-size: var(--font-small);
1534
- }
1535
-
1536
- #usage-float-panel .ufp-item .ufp-func {
1537
- color: #89dceb;
1538
- font-weight: 600;
1539
- font-size: var(--font-small);
1540
- }
1541
-
1542
- #usage-float-panel .ufp-item .ufp-func::before {
1543
- content: 'func ';
1544
- color: var(--gd-keyword);
1545
- font-weight: normal;
1546
- }
1547
-
1548
- #usage-float-panel .ufp-item .ufp-line {
1549
- color: var(--text-muted);
1550
- font-size: var(--font-micro);
1551
- font-family: var(--font-mono);
1552
- margin-left: auto;
1553
- }
1554
-
1555
- #usage-float-panel .ufp-item .ufp-code {
1556
- color: var(--text-secondary);
1557
- font-family: var(--font-mono);
1558
- font-size: var(--font-small);
1559
- background: var(--bg-tertiary);
1560
- padding: 8px var(--space-sm);
1561
- border-radius: 6px;
1562
- overflow: hidden;
1563
- text-overflow: ellipsis;
1564
- white-space: nowrap;
1565
- }
1566
-
1567
- #usage-float-panel .ufp-item .ufp-code .highlight {
1568
- color: #f38ba8;
1569
- font-weight: 600;
1570
- background: rgba(243, 139, 168, 0.12);
1571
- padding: 1px 4px;
1572
- border-radius: 3px;
1573
- }
1574
-
1575
- #usage-float-panel .ufp-actions {
1576
- display: flex;
1577
- gap: 12px;
1578
- padding: var(--space-md) var(--space-lg);
1579
- background: var(--bg-tertiary);
1580
- }
1581
-
1582
- #usage-float-panel .ufp-actions button {
1583
- flex: 1;
1584
- padding: 10px var(--space-md);
1585
- border-radius: var(--radius-sm);
1586
- font-size: var(--font-small);
1587
- cursor: pointer;
1588
- border: none;
1589
- font-weight: 500;
1590
- transition: all 0.15s;
1591
- }
1592
-
1593
- #usage-float-panel .ufp-actions .cancel {
1594
- background: var(--bg-secondary);
1595
- color: var(--text-secondary);
1596
- }
1597
-
1598
- #usage-float-panel .ufp-actions .cancel:hover {
1599
- background: var(--bg-hover);
1600
- }
1601
-
1602
- #usage-float-panel .ufp-actions .delete {
1603
- background: rgba(243, 139, 168, 0.15);
1604
- color: #f38ba8;
1605
- }
1606
-
1607
- #usage-float-panel .ufp-actions .delete:hover {
1608
- background: rgba(243, 139, 168, 0.25);
1609
- }
1610
-
1611
-
1612
- /* ============================================================================
1613
- CODE LINE HIGHLIGHT
1614
- ============================================================================ */
1615
-
1616
- .code-line-highlight {
1617
- background: rgba(243, 139, 168, 0.2) !important;
1618
- border-left: 3px solid #f38ba8 !important;
1619
- margin-left: -14px !important;
1620
- padding-left: 11px !important;
1621
- }
1622
-
1623
-
1624
- /* ============================================================================
1625
- ADD ITEM FORM
1626
- ============================================================================ */
1627
-
1628
- .add-item-btn {
1629
- display: flex;
1630
- align-items: center;
1631
- gap: 8px;
1632
- padding: 10px var(--space-sm);
1633
- color: var(--text-muted);
1634
- font-size: var(--font-small);
1635
- cursor: pointer;
1636
- border-radius: var(--radius-sm);
1637
- margin-top: 6px;
1638
- transition: all 0.12s;
1639
- }
1640
-
1641
- .add-item-btn:hover {
1642
- background: var(--bg-secondary);
1643
- color: var(--text-secondary);
1644
- }
1645
-
1646
- .add-item-btn svg { opacity: 0.5; }
1647
-
1648
- .add-item-form {
1649
- background: var(--bg-secondary);
1650
- border: none;
1651
- border-radius: var(--radius-md);
1652
- padding: var(--space-md);
1653
- margin-top: var(--space-sm);
1654
- box-shadow: var(--shadow-panel);
1655
- }
1656
-
1657
- .add-item-form .form-row {
1658
- display: flex;
1659
- gap: 10px;
1660
- margin-bottom: var(--space-sm);
1661
- }
1662
-
1663
- .add-item-form .form-row:last-child { margin-bottom: 0; }
1664
-
1665
- .add-item-form input,
1666
- .add-item-form select {
1667
- flex: 1;
1668
- background: var(--bg-tertiary);
1669
- border: 1px solid var(--border);
1670
- color: var(--text-primary);
1671
- padding: 8px var(--space-sm);
1672
- border-radius: 6px;
1673
- font-size: var(--font-small);
1674
- font-family: inherit;
1675
- transition: border-color 0.15s;
1676
- }
1677
-
1678
- .add-item-form input:focus,
1679
- .add-item-form select:focus {
1680
- outline: none;
1681
- border-color: var(--accent);
1682
- }
1683
-
1684
- .add-item-form .form-actions {
1685
- display: flex;
1686
- gap: 10px;
1687
- justify-content: flex-end;
1688
- }
1689
-
1690
- .add-item-form button {
1691
- padding: 8px var(--space-md);
1692
- border-radius: 6px;
1693
- font-size: var(--font-small);
1694
- cursor: pointer;
1695
- border: none;
1696
- font-weight: 500;
1697
- transition: all 0.15s;
1698
- }
1699
-
1700
- .add-item-form button.cancel {
1701
- background: var(--bg-tertiary);
1702
- color: var(--text-secondary);
1703
- }
1704
-
1705
- .add-item-form button.confirm {
1706
- background: var(--accent);
1707
- color: var(--bg-primary);
1708
- font-weight: 600;
1709
- }
1710
-
1711
- .add-item-form button.confirm:hover {
1712
- background: var(--accent-light);
1713
- }
1714
-
1715
-
1716
- /* ============================================================================
1717
- SYNTAX TOKENS — UNCHANGED colors
1718
- ============================================================================ */
1719
-
1720
- .kw { color: var(--gd-keyword); font-weight: 600; }
1721
- .fn { color: var(--gd-func-name); }
1722
- .tp { color: var(--gd-type); }
1723
- .str { color: var(--gd-string); }
1724
- .num { color: var(--gd-number); }
1725
- .cmt { color: var(--gd-comment); font-style: italic; }
1726
- .sig { color: var(--gd-signal); }
1727
- .exp { color: var(--gd-export); }
1728
- .param { color: var(--text-secondary); }
1729
- .ret { color: var(--text-muted); }
1730
-
1731
-
1732
- /* ============================================================================
1733
- TAGS
1734
- ============================================================================ */
1735
-
1736
- .tag {
1737
- font-size: var(--font-micro);
1738
- padding: 3px 8px;
1739
- border-radius: 4px;
1740
- font-family: var(--font-sans);
1741
- font-weight: 600;
1742
- text-transform: uppercase;
1743
- letter-spacing: 0.5px;
1744
- }
1745
-
1746
- .tag-export { background: rgba(187, 181, 41, 0.12); color: var(--gd-export); }
1747
- .tag-signal { background: rgba(166, 227, 161, 0.12); color: var(--gd-signal); }
1748
- .tag-lines { background: var(--bg-tertiary); color: var(--text-muted); font-weight: normal; }
1749
- .tag-return { background: rgba(104, 151, 187, 0.12); color: var(--gd-type); }
1750
-
1751
-
1752
- /* ============================================================================
1753
- FUNCTION VIEWER
1754
- ============================================================================ */
1755
-
1756
- .func-viewer {
1757
- margin-top: var(--space-lg);
1758
- background: var(--bg-secondary);
1759
- border: none;
1760
- border-radius: var(--radius-md);
1761
- overflow: hidden;
1762
- box-shadow: var(--shadow-panel);
1763
- }
1764
-
1765
- .func-viewer-header {
1766
- display: flex;
1767
- align-items: center;
1768
- justify-content: space-between;
1769
- padding: var(--space-sm) var(--space-lg);
1770
- background: var(--bg-tertiary);
1771
- font-size: var(--font-body);
1772
- color: var(--text-secondary);
1773
- }
1774
-
1775
- .func-viewer-header .func-title {
1776
- color: var(--gd-func-name);
1777
- font-weight: 600;
1778
- }
1779
-
1780
- .func-viewer-close {
1781
- background: none;
1782
- border: none;
1783
- color: var(--text-muted);
1784
- cursor: pointer;
1785
- font-size: 16px;
1786
- padding: 4px 8px;
1787
- border-radius: 6px;
1788
- transition: all 0.15s;
1789
- }
1790
-
1791
- .func-viewer-close:hover {
1792
- color: var(--text-primary);
1793
- background: var(--bg-hover);
1794
- }
1795
-
1796
- .func-viewer-code {
1797
- position: relative;
1798
- padding: var(--space-md) 0;
1799
- font-family: var(--font-mono);
1800
- font-size: 13px;
1801
- line-height: 1.7;
1802
- overflow: auto;
1803
- tab-size: 4;
1804
- }
1805
-
1806
- /* Editable code area */
1807
- .code-editor-container {
1808
- position: relative;
1809
- margin: 0 var(--space-lg);
1810
- }
1811
-
1812
- .code-editor-textarea {
1813
- position: absolute;
1814
- top: 0;
1815
- left: 0;
1816
- width: 100%;
1817
- height: 100%;
1818
- font-family: inherit;
1819
- font-size: inherit;
1820
- line-height: inherit;
1821
- tab-size: inherit;
1822
- padding: 0;
1823
- margin: 0;
1824
- border: none;
1825
- background: transparent;
1826
- color: transparent;
1827
- caret-color: var(--text-primary);
1828
- resize: none;
1829
- outline: none;
1830
- overflow: hidden;
1831
- white-space: pre;
1832
- }
1833
-
1834
- .code-editor-textarea::selection {
1835
- background: rgba(255, 255, 255, 0.15);
1836
- }
1837
-
1838
- .code-editor-highlight {
1839
- white-space: pre;
1840
- pointer-events: none;
1841
- }
1842
-
1843
- .code-editor-container:focus-within {
1844
- outline: 1px solid var(--accent);
1845
- outline-offset: 6px;
1846
- border-radius: 4px;
1847
- }
1848
-
1849
- .func-viewer-footer {
1850
- display: flex;
1851
- align-items: center;
1852
- justify-content: space-between;
1853
- padding: 10px var(--space-lg);
1854
- background: var(--bg-tertiary);
1855
- font-size: var(--font-small);
1856
- color: var(--text-muted);
1857
- }
1858
-
1859
- .func-viewer-footer .status { opacity: 0; transition: opacity 0.2s; }
1860
- .func-viewer-footer .status.visible { opacity: 1; }
1861
-
1862
- .func-viewer-footer .save-btn {
1863
- background: var(--accent);
1864
- color: var(--bg-primary);
1865
- border: none;
1866
- padding: 6px var(--space-md);
1867
- border-radius: 6px;
1868
- font-size: var(--font-small);
1869
- font-weight: 600;
1870
- cursor: pointer;
1871
- opacity: 0.5;
1872
- transition: all 0.2s;
1873
- }
1874
-
1875
- .func-viewer-footer .save-btn.active { opacity: 1; }
1876
- .func-viewer-footer .save-btn.active:hover { background: var(--accent-light); }
1877
-
1878
- .code-line {
1879
- display: block;
1880
- padding: 0 var(--space-lg);
1881
- min-height: 1.5em;
1882
- white-space: pre;
1883
- }
1884
-
1885
- .code-line:hover { background: rgba(255,255,255,0.02); }
1886
-
1887
- .line-num {
1888
- color: var(--text-muted);
1889
- min-width: 40px;
1890
- text-align: right;
1891
- padding-right: var(--space-md);
1892
- user-select: none;
1893
- flex-shrink: 0;
1894
- font-size: var(--font-small);
1895
- }
1896
-
1897
- .line-content {
1898
- white-space: pre;
1899
- flex: 1;
1900
- }
1901
-
1902
-
1903
- /* ============================================================================
1904
- SCENE VIEW STYLES
1905
- ============================================================================ */
1906
-
1907
- #scene-back-btn {
1908
- position: fixed;
1909
- top: 24px;
1910
- left: 200px;
1911
- z-index: 100;
1912
- display: flex;
1913
- align-items: center;
1914
- gap: 8px;
1915
- background: var(--bg-secondary);
1916
- border: none;
1917
- border-radius: var(--radius-sm);
1918
- padding: 10px var(--space-md);
1919
- font-size: var(--font-small);
1920
- color: var(--text-secondary);
1921
- cursor: pointer;
1922
- box-shadow: var(--shadow-panel);
1923
- transition: all 0.15s;
1924
- }
1925
-
1926
- #scene-back-btn:hover {
1927
- background: var(--bg-hover);
1928
- color: var(--text-primary);
1929
- }
1930
-
1931
- #scene-back-btn svg {
1932
- flex-shrink: 0;
1933
- opacity: 0.6;
1934
- width: 14px;
1935
- height: 14px;
1936
- }
1937
-
1938
- #scene-back-btn .scene-name {
1939
- color: var(--accent);
1940
- font-weight: 600;
1941
- max-width: 120px;
1942
- overflow: hidden;
1943
- text-overflow: ellipsis;
1944
- white-space: nowrap;
1945
- }
1946
-
1947
-
1948
- /* ============================================================================
1949
- SCENE NODE PROPERTIES PANEL STYLES
1950
- ============================================================================ */
1951
-
1952
- .loading-state,
1953
- .error-state {
1954
- padding: var(--space-2xl) var(--space-lg);
1955
- text-align: center;
1956
- color: var(--text-muted);
1957
- font-size: var(--font-body);
1958
- }
1959
-
1960
- .error-state {
1961
- color: #f38ba8;
1962
- }
1963
-
1964
- /* Property sections — Godot inspector style */
1965
- .property-section {
1966
- margin-bottom: 6px;
1967
- border-radius: var(--radius-sm);
1968
- overflow: hidden;
1969
- }
1970
-
1971
- .property-section .section-header {
1972
- cursor: pointer;
1973
- user-select: none;
1974
- background: var(--bg-secondary);
1975
- padding: var(--space-sm) var(--space-md);
1976
- font-size: var(--font-h2);
1977
- font-weight: 600;
1978
- color: var(--text-primary);
1979
- display: flex;
1980
- justify-content: space-between;
1981
- align-items: center;
1982
- border-bottom: none;
1983
- text-transform: none;
1984
- letter-spacing: 0;
1985
- transition: background 0.1s;
1986
- }
1987
-
1988
- .property-section .section-header:hover {
1989
- background: var(--bg-hover);
1990
- }
1991
-
1992
- .property-section .section-count {
1993
- background: transparent;
1994
- color: var(--text-muted);
1995
- font-size: var(--font-small);
1996
- font-family: var(--font-mono);
1997
- padding: 0;
1998
- border-radius: 0;
1999
- font-weight: 500;
2000
- }
2001
-
2002
- .property-section.collapsed .property-list {
2003
- display: none;
2004
- }
2005
-
2006
- .property-section.collapsed .section-header span:first-child::before {
2007
- content: '▶ ';
2008
- }
2009
-
2010
- .property-section:not(.collapsed) .section-header span:first-child::before {
2011
- content: '▼ ';
2012
- }
2013
-
2014
- .property-section .section-header span:first-child {
2015
- display: flex;
2016
- align-items: center;
2017
- }
2018
-
2019
- .property-section .section-header span:first-child::before {
2020
- margin-right: 6px;
2021
- font-size: var(--font-small);
2022
- opacity: 0.5;
2023
- }
2024
-
2025
- .property-list {
2026
- padding: 6px 0;
2027
- background: var(--bg-primary);
2028
- }
2029
-
2030
- /* Property rows */
2031
- .property-row {
2032
- display: flex;
2033
- align-items: center;
2034
- gap: var(--space-sm);
2035
- padding: 8px var(--space-md);
2036
- margin-bottom: 1px;
2037
- transition: background 0.1s;
2038
- }
2039
-
2040
- .property-row:hover {
2041
- background: rgba(255, 255, 255, 0.02);
2042
- }
2043
-
2044
- .property-name {
2045
- flex: 0 0 40%;
2046
- font-size: var(--font-body);
2047
- color: var(--text-secondary);
2048
- text-overflow: ellipsis;
2049
- overflow: hidden;
2050
- white-space: nowrap;
2051
- padding-right: 10px;
2052
- }
2053
-
2054
- .property-value {
2055
- flex: 1;
2056
- display: flex;
2057
- align-items: center;
2058
- gap: 6px;
2059
- min-width: 0;
2060
- }
2061
-
2062
- /* Property inputs */
2063
- .property-input {
2064
- width: 100%;
2065
- background: var(--bg-tertiary);
2066
- border: 1px solid var(--border);
2067
- border-radius: 6px;
2068
- padding: 8px var(--space-sm);
2069
- font-size: var(--font-body);
2070
- color: var(--text-primary);
2071
- font-family: var(--font-mono);
2072
- transition: border-color 0.15s;
2073
- }
2074
-
2075
- .property-input:focus {
2076
- outline: none;
2077
- border-color: var(--accent);
2078
- }
2079
-
2080
- .property-input::-webkit-inner-spin-button,
2081
- .property-input::-webkit-outer-spin-button {
2082
- opacity: 1;
2083
- }
2084
-
2085
- /* Property select */
2086
- .property-select {
2087
- width: 100%;
2088
- background: var(--bg-tertiary);
2089
- border: 1px solid var(--border);
2090
- border-radius: 6px;
2091
- padding: 8px var(--space-sm);
2092
- font-size: var(--font-body);
2093
- color: var(--text-primary);
2094
- cursor: pointer;
2095
- transition: border-color 0.15s;
2096
- }
2097
-
2098
- .property-select:focus {
2099
- outline: none;
2100
- border-color: var(--accent);
2101
- }
2102
-
2103
- /* Toggle switch */
2104
- .toggle-switch {
2105
- position: relative;
2106
- display: inline-block;
2107
- width: 38px;
2108
- height: 22px;
2109
- }
2110
-
2111
- .toggle-switch input {
2112
- opacity: 0;
2113
- width: 0;
2114
- height: 0;
2115
- }
2116
-
2117
- .toggle-slider {
2118
- position: absolute;
2119
- cursor: pointer;
2120
- top: 0;
2121
- left: 0;
2122
- right: 0;
2123
- bottom: 0;
2124
- background-color: var(--bg-tertiary);
2125
- border-radius: 22px;
2126
- transition: 0.15s;
2127
- }
2128
-
2129
- .toggle-slider::before {
2130
- position: absolute;
2131
- content: "";
2132
- height: 16px;
2133
- width: 16px;
2134
- left: 3px;
2135
- bottom: 3px;
2136
- background-color: var(--text-muted);
2137
- border-radius: var(--radius-full);
2138
- transition: 0.15s;
2139
- }
2140
-
2141
- .toggle-switch input:checked + .toggle-slider {
2142
- background-color: rgba(166, 227, 161, 0.25);
2143
- }
2144
-
2145
- .toggle-switch input:checked + .toggle-slider::before {
2146
- background-color: var(--gd-signal);
2147
- transform: translateX(16px);
2148
- }
2149
-
2150
- /* Range input group */
2151
- .range-input-group {
2152
- display: flex;
2153
- align-items: center;
2154
- gap: 10px;
2155
- width: 100%;
2156
- }
2157
-
2158
- .property-range {
2159
- flex: 1;
2160
- height: 4px;
2161
- -webkit-appearance: none;
2162
- background: var(--bg-tertiary);
2163
- border-radius: 2px;
2164
- outline: none;
2165
- }
2166
-
2167
- .property-range::-webkit-slider-thumb {
2168
- -webkit-appearance: none;
2169
- width: 16px;
2170
- height: 16px;
2171
- background: var(--accent);
2172
- border-radius: var(--radius-full);
2173
- cursor: pointer;
2174
- transition: background 0.15s;
2175
- }
2176
-
2177
- .property-range::-webkit-slider-thumb:hover {
2178
- background: var(--accent-light);
2179
- }
2180
-
2181
- .range-number {
2182
- width: 60px !important;
2183
- flex: 0 0 auto;
2184
- }
2185
-
2186
- /* Vector input group */
2187
- .vector-input-group {
2188
- display: flex;
2189
- align-items: center;
2190
- gap: 6px;
2191
- width: 100%;
2192
- }
2193
-
2194
- .vector-input-group label {
2195
- font-size: var(--font-micro);
2196
- color: var(--text-muted);
2197
- font-weight: 600;
2198
- text-transform: uppercase;
2199
- }
2200
-
2201
- .vector-input-group .property-input {
2202
- width: auto;
2203
- flex: 1;
2204
- min-width: 50px;
2205
- }
2206
-
2207
- .vector-input-group.vec3 .property-input {
2208
- min-width: 40px;
2209
- }
2210
-
2211
- /* Color input group */
2212
- .color-input-group {
2213
- display: flex;
2214
- align-items: center;
2215
- gap: 8px;
2216
- width: 100%;
2217
- }
2218
-
2219
- .property-color {
2220
- width: 42px;
2221
- height: 28px;
2222
- padding: 0;
2223
- border: 1px solid var(--border);
2224
- border-radius: 6px;
2225
- cursor: pointer;
2226
- background: transparent;
2227
- }
2228
-
2229
- .property-color::-webkit-color-swatch-wrapper {
2230
- padding: 2px;
2231
- }
2232
-
2233
- .property-color::-webkit-color-swatch {
2234
- border-radius: 3px;
2235
- border: none;
2236
- }
2237
-
2238
- .color-alpha {
2239
- width: 50px !important;
2240
- flex: 0 0 auto;
2241
- }
2242
-
2243
- /* Readonly property */
2244
- .property-readonly {
2245
- font-size: var(--font-small);
2246
- color: var(--text-muted);
2247
- font-family: var(--font-mono);
2248
- background: var(--bg-tertiary);
2249
- padding: 6px 10px;
2250
- border-radius: 6px;
2251
- max-width: 100%;
2252
- overflow: hidden;
2253
- text-overflow: ellipsis;
2254
- white-space: nowrap;
2255
- }
2256
-
2257
- /* Resource path */
2258
- .resource-path {
2259
- font-size: var(--font-small);
2260
- color: var(--gd-string);
2261
- font-family: var(--font-mono);
2262
- background: var(--bg-tertiary);
2263
- padding: 6px 10px;
2264
- border-radius: 6px;
2265
- }
2266
-
2267
-
2268
- /* ============================================================================
2269
- DIFF STYLES
2270
- ============================================================================ */
2271
-
2272
- .diff-container { padding: 0; }
2273
-
2274
- .diff-loading {
2275
- padding: var(--space-md);
2276
- color: var(--text-muted);
2277
- font-size: var(--font-body);
2278
- }
2279
-
2280
- .diff-error {
2281
- padding: var(--space-md);
2282
- color: #f38ba8;
2283
- font-size: var(--font-body);
2284
- }
2285
-
2286
- .diff-info {
2287
- padding: var(--space-md);
2288
- color: var(--text-muted);
2289
- font-size: var(--font-body);
2290
- font-style: italic;
2291
- }
2292
-
2293
- .diff-group { margin-bottom: var(--space-sm); }
2294
-
2295
- .diff-group-header {
2296
- display: flex;
2297
- justify-content: space-between;
2298
- align-items: center;
2299
- padding: 8px var(--space-sm);
2300
- background: rgba(255,255,255,0.02);
2301
- font-size: var(--font-small);
2302
- font-weight: 600;
2303
- color: var(--text-primary);
2304
- }
2305
-
2306
- .diff-func-name {
2307
- font-family: var(--font-mono);
2308
- }
2309
-
2310
- .diff-stats {
2311
- display: flex;
2312
- gap: 8px;
2313
- font-family: var(--font-mono);
2314
- }
2315
-
2316
- .diff-stat-add { color: #a6e3a1; }
2317
- .diff-stat-del { color: #f38ba8; }
2318
-
2319
- .diff-hunk {
2320
- font-family: var(--font-mono);
2321
- font-size: var(--font-small);
2322
- line-height: 1.6;
2323
- }
2324
-
2325
- .diff-line {
2326
- padding: 0 var(--space-sm);
2327
- white-space: pre-wrap;
2328
- word-break: break-all;
2329
- }
2330
-
2331
- .diff-add { background: rgba(166, 227, 161, 0.08); color: #a6e3a1; }
2332
- .diff-del { background: rgba(243, 139, 168, 0.08); color: #f38ba8; }
2333
- .diff-ctx { color: var(--text-muted); }
2334
-
2335
- </style>
2336
- </head>
2337
- <body>
2338
- <div id="search-bar">
2339
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--text-muted)" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
2340
- <input type="text" id="search" placeholder="Search scripts..." />
2341
- <span class="stats" id="stats"></span>
2342
- <button id="refresh-btn" onclick="refreshProject()" title="Refresh project (re-scan files & git status)">
2343
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2344
- <path d="M23 4v6h-6M1 20v-6h6"/>
2345
- <path d="M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15"/>
2346
- </svg>
2347
- </button>
2348
- </div>
2349
-
2350
- <div id="legend">
2351
- <div class="item"><div class="line" style="background:var(--edge-extends)"></div> extends</div>
2352
- <div class="item"><div class="line" style="background:var(--edge-preload)"></div> preload</div>
2353
- <div class="item"><div class="line" style="background:var(--edge-signal);height:0;border-top:2px dotted var(--edge-signal)"></div> signal</div>
2354
- </div>
2355
-
2356
- <div id="zoom-indicator" title="Click to reset, or type custom zoom">
2357
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--text-muted)" stroke-width="2" onclick="resetZoom()" style="cursor:pointer"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/><path d="M8 11h6"/><path d="M11 8v6"/></svg>
2358
- <input type="text" class="zoom-input" id="zoom-text" value="100%" onchange="setCustomZoom(this.value)" onkeydown="if(event.key==='Enter'){this.blur()}" onclick="this.select()">
2359
- </div>
2360
-
2361
- <div id="detail-panel">
2362
- <div id="panel-resize-handle"></div>
2363
- <div class="panel-header">
2364
- <button class="close-btn" onclick="closePanel()">&times;</button>
2365
- <h2 id="panel-title"></h2>
2366
- <div class="path" id="panel-path"></div>
2367
- </div>
2368
- <div class="panel-body" id="panel-body"></div>
2369
- </div>
2370
-
2371
- <!-- Category Filter Panel -->
2372
- <div id="category-panel">
2373
- <div class="cat-header">
2374
- <span class="cat-title">Categories</span>
2375
- <div class="cat-controls">
2376
- <button class="cat-mode-btn" id="cat-mode-btn" onclick="toggleGroupMode()" title="Toggle grouped layout">
2377
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2378
- <rect x="3" y="3" width="7" height="7" rx="1"/>
2379
- <rect x="14" y="3" width="7" height="7" rx="1"/>
2380
- <rect x="14" y="14" width="7" height="7" rx="1"/>
2381
- <rect x="3" y="14" width="7" height="7" rx="1"/>
2382
- </svg>
2383
- </button>
2384
- <button class="cat-all-btn" onclick="toggleAllCategories()" title="Show/Hide all">All</button>
2385
- </div>
2386
- </div>
2387
- <div class="cat-list" id="cat-list"></div>
2388
- </div>
2389
-
2390
- <!-- Changes Panel -->
2391
- <div id="changes-panel">
2392
- <div class="changes-header">
2393
- <span class="changes-title">Changes</span>
2394
- <label class="changes-toggle">
2395
- <input type="checkbox" id="changes-toggle-input" checked onchange="toggleChangesVisible()">
2396
- <span class="changes-toggle-slider"></span>
2397
- </label>
2398
- </div>
2399
- <div class="changes-stats" id="changes-stats">
2400
- <div class="changes-stat-row" data-type="modified" onclick="filterByChangeType('modified')">
2401
- <span class="changes-dot" style="background:#f9e2af"></span>
2402
- <span class="changes-label">Modified</span>
2403
- <span class="changes-count" id="changes-modified-count">0</span>
2404
- </div>
2405
- <div class="changes-stat-row" data-type="added" onclick="filterByChangeType('added')">
2406
- <span class="changes-dot" style="background:#a6e3a1"></span>
2407
- <span class="changes-label">Added</span>
2408
- <span class="changes-count" id="changes-added-count">0</span>
2409
- </div>
2410
- <div class="changes-stat-row" data-type="untracked" onclick="filterByChangeType('untracked')">
2411
- <span class="changes-dot" style="background:#89b4fa"></span>
2412
- <span class="changes-label">Untracked</span>
2413
- <span class="changes-count" id="changes-untracked-count">0</span>
2414
- </div>
2415
- <div class="changes-stat-row" data-type="new" onclick="filterByChangeType('new')">
2416
- <span class="changes-dot" style="background:#cdd6f4"></span>
2417
- <span class="changes-label">New</span>
2418
- <span class="changes-count" id="changes-new-count">0</span>
2419
- </div>
2420
- </div>
2421
- <div class="changes-total" id="changes-total">0 changed files</div>
2422
- </div>
2423
-
2424
- <!-- Timeline Panel -->
2425
- <div id="timeline-panel">
2426
- <div class="tl-header" onclick="toggleTimelinePanel()">
2427
- <span class="tl-title">Activity</span>
2428
- <span class="tl-count" id="tl-count">0</span>
2429
- <svg class="tl-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2430
- <polyline points="6 9 12 15 18 9"/>
2431
- </svg>
2432
- </div>
2433
- <div class="tl-body" id="tl-body">
2434
- <div class="tl-empty" id="tl-empty">No actions recorded yet</div>
2435
- <div class="tl-list" id="tl-list"></div>
2436
- </div>
2437
- </div>
2438
-
2439
- <!-- View Tabs -->
2440
- <div id="view-tabs">
2441
- <button class="active" onclick="switchView('scripts')">Scripts</button>
2442
- <button onclick="switchView('scenes')">Scenes</button>
2443
- </div>
2444
-
2445
- <!-- Scene Back Button (shown when scene is expanded) -->
2446
- <div id="scene-back-btn" style="display:none" onclick="goBackToSceneOverview()">
2447
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2448
- <path d="M19 12H5M12 19l-7-7 7-7"/>
2449
- </svg>
2450
- <span>← Back to Scenes</span>
2451
- <span class="scene-name"></span>
2452
- </div>
2453
-
2454
- <!-- Context Menu (Scripts) -->
2455
- <div id="context-menu">
2456
- <div class="menu-item" onclick="createNewScript()">
2457
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2458
- <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
2459
- <polyline points="14,2 14,8 20,8"/>
2460
- <line x1="12" y1="18" x2="12" y2="12"/>
2461
- <line x1="9" y1="15" x2="15" y2="15"/>
2462
- </svg>
2463
- New Script
2464
- </div>
2465
- <div class="menu-divider"></div>
2466
- <div class="menu-item" onclick="refreshProject()">
2467
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2468
- <path d="M23 4v6h-6M1 20v-6h6"/>
2469
- <path d="M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15"/>
2470
- </svg>
2471
- Refresh
2472
- </div>
2473
- <div class="menu-item" onclick="resetLayout()">
2474
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2475
- <rect x="3" y="3" width="7" height="7"/>
2476
- <rect x="14" y="3" width="7" height="7"/>
2477
- <rect x="14" y="14" width="7" height="7"/>
2478
- <rect x="3" y="14" width="7" height="7"/>
2479
- </svg>
2480
- Reset Layout
2481
- </div>
2482
- </div>
2483
-
2484
- <!-- Context Menu (Scene Nodes) -->
2485
- <div id="scene-context-menu">
2486
- <div class="menu-item" onclick="sceneNodeAction('add_child')">
2487
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2488
- <circle cx="12" cy="12" r="10"/>
2489
- <line x1="12" y1="8" x2="12" y2="16"/>
2490
- <line x1="8" y1="12" x2="16" y2="12"/>
2491
- </svg>
2492
- Add Child Node
2493
- </div>
2494
- <div class="menu-item" onclick="sceneNodeAction('rename')">
2495
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2496
- <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
2497
- <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
2498
- </svg>
2499
- Rename
2500
- </div>
2501
- <div class="menu-item" onclick="sceneNodeAction('duplicate')">
2502
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2503
- <rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
2504
- <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
2505
- </svg>
2506
- Duplicate
2507
- </div>
2508
- <div class="menu-divider"></div>
2509
- <div class="menu-item" onclick="sceneNodeAction('move_up')">
2510
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2511
- <polyline points="18 15 12 9 6 15"/>
2512
- </svg>
2513
- Move Up
2514
- </div>
2515
- <div class="menu-item" onclick="sceneNodeAction('move_down')">
2516
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2517
- <polyline points="6 9 12 15 18 9"/>
2518
- </svg>
2519
- Move Down
2520
- </div>
2521
- <div class="menu-divider"></div>
2522
- <div class="menu-item danger" onclick="sceneNodeAction('delete')">
2523
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2524
- <polyline points="3 6 5 6 21 6"/>
2525
- <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
2526
- </svg>
2527
- Delete
2528
- </div>
2529
- </div>
2530
-
2531
- <!-- Floating Usage Panel -->
2532
- <div id="usage-float-panel">
2533
- <div class="ufp-header" id="ufp-header">
2534
- <div class="ufp-info">
2535
- <div class="ufp-title" id="ufp-title">⚠ Delete Variable</div>
2536
- <div class="ufp-count" id="ufp-count"></div>
2537
- </div>
2538
- <div class="ufp-buttons">
2539
- <button class="refresh-btn" onclick="refreshUsages()" title="Re-scan for usages">↻</button>
2540
- <button class="close-btn" onclick="closeUsagePanel()" title="Cancel">×</button>
2541
- </div>
2542
- </div>
2543
- <div class="ufp-list" id="ufp-list"></div>
2544
- <div class="ufp-actions">
2545
- <button class="cancel" onclick="closeUsagePanel()">Cancel</button>
2546
- <button class="delete" id="ufp-delete-btn">Delete Anyway</button>
2547
- </div>
2548
- <div class="ufp-resize" id="ufp-resize"></div>
2549
- </div>
2550
-
2551
- <!-- New Script Modal -->
2552
- <div id="new-script-modal" class="modal" style="display:none">
2553
- <div class="modal-content">
2554
- <div class="modal-header">
2555
- <h3>Create New Script</h3>
2556
- <button class="close-btn" onclick="closeNewScriptModal()">&times;</button>
2557
- </div>
2558
- <div class="modal-body">
2559
- <div class="form-group">
2560
- <label>Script Path</label>
2561
- <input type="text" id="new-script-path" placeholder="res://scripts/my_script.gd">
2562
- </div>
2563
- <div class="form-group">
2564
- <label>Extends</label>
2565
- <select id="new-script-extends">
2566
- <option value="Node">Node</option>
2567
- <option value="Node2D">Node2D</option>
2568
- <option value="Node3D">Node3D</option>
2569
- <option value="CharacterBody2D">CharacterBody2D</option>
2570
- <option value="CharacterBody3D">CharacterBody3D</option>
2571
- <option value="RigidBody2D">RigidBody2D</option>
2572
- <option value="Area2D">Area2D</option>
2573
- <option value="Control">Control</option>
2574
- <option value="Resource">Resource</option>
2575
- <option value="RefCounted">RefCounted</option>
2576
- </select>
2577
- </div>
2578
- <div class="form-group">
2579
- <label>Class Name (optional)</label>
2580
- <input type="text" id="new-script-classname" placeholder="MyClass">
2581
- </div>
2582
- </div>
2583
- <div class="modal-footer">
2584
- <button class="cancel" onclick="closeNewScriptModal()">Cancel</button>
2585
- <button class="confirm" onclick="submitNewScript()">Create</button>
2586
- </div>
2587
- </div>
2588
- </div>
2589
-
2590
- <canvas id="canvas"></canvas>
2591
-
2592
- <script>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Godot Project Map</title>
7
+ <style>
8
+ /* ============================================================================
9
+ GODOT PROJECT MAP VISUALIZER — "VOID" BIG TYPOGRAPHY DARK DASHBOARD
10
+ ============================================================================ */
11
+
12
+ * { margin: 0; padding: 0; box-sizing: border-box; }
13
+
14
+ :root {
15
+ /* Void palette */
16
+ --bg-primary: #101319;
17
+ --bg-secondary: #171c24;
18
+ --bg-tertiary: #202734;
19
+ --bg-hover: #293243;
20
+ --bg-surface: #1b212c;
21
+ --border: rgba(255,255,255,0.06);
22
+ --border-light: rgba(255,255,255,0.1);
23
+ --text-primary: #f0f0f5;
24
+ --text-secondary: #7d8590;
25
+ --text-muted: #484f58;
26
+ --accent: #4ec9b0;
27
+ --accent-light: #6edcc8;
28
+ --accent-dim: rgba(78, 201, 176, 0.12);
29
+
30
+ /* GDScript syntax colors — UNCHANGED */
31
+ --gd-keyword: #cc7832;
32
+ --gd-func-name: #ffc66d;
33
+ --gd-type: #6897bb;
34
+ --gd-string: #6a8759;
35
+ --gd-number: #6897bb;
36
+ --gd-comment: #808080;
37
+ --gd-var: #cc7832;
38
+ --gd-signal: #a6e3a1;
39
+ --gd-export: #bbb529;
40
+ --gd-builtin: #8888c6;
41
+
42
+ /* Edge colors — UNCHANGED */
43
+ --edge-extends: #7aa2f7;
44
+ --edge-preload: #d4a27f;
45
+ --edge-signal: #a6e3a1;
46
+
47
+ /* Typography scale — Big Typography editorial dashboard */
48
+ --font-display: 48px;
49
+ --font-h1: 32px;
50
+ --font-h2: 20px;
51
+ --font-body: 12px;
52
+ --font-small: 10px;
53
+ --font-micro: 9px;
54
+ --font-mono: 'SF Mono', 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
55
+ --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
56
+
57
+ /* Spacing scale */
58
+ --space-xs: 6px;
59
+ --space-sm: 10px;
60
+ --space-md: 16px;
61
+ --space-lg: 22px;
62
+ --space-xl: 32px;
63
+ --space-2xl: 44px;
64
+
65
+ /* Shadows */
66
+ --shadow-panel: 0 2px 20px rgba(0,0,0,0.5);
67
+ --shadow-elevated: 0 4px 30px rgba(0,0,0,0.4);
68
+ --shadow-menu: 0 8px 40px rgba(0,0,0,0.6);
69
+ --shadow-modal: 0 16px 64px rgba(0,0,0,0.6);
70
+
71
+ /* Radii */
72
+ --radius-sm: 8px;
73
+ --radius-md: 12px;
74
+ --radius-lg: 16px;
75
+ --radius-full: 50%;
76
+ }
77
+
78
+ body {
79
+ background: var(--bg-primary);
80
+ color: var(--text-primary);
81
+ font-family: var(--font-sans);
82
+ font-size: var(--font-body);
83
+ overflow: hidden;
84
+ height: 100vh;
85
+ -webkit-font-smoothing: antialiased;
86
+ -moz-osx-font-smoothing: grayscale;
87
+ }
88
+
89
+ canvas { display: block; cursor: grab; }
90
+ canvas.dragging { cursor: grabbing; }
91
+
92
+
93
+ /* ============================================================================
94
+ SEARCH BAR
95
+ ============================================================================ */
96
+
97
+ #search-bar {
98
+ position: fixed;
99
+ top: 20px;
100
+ left: 50%;
101
+ transform: translateX(-50%);
102
+ z-index: 100;
103
+ display: flex;
104
+ align-items: center;
105
+ gap: 10px;
106
+ background: var(--bg-secondary);
107
+ border: none;
108
+ border-radius: var(--radius-md);
109
+ padding: 10px 18px;
110
+ height: 42px;
111
+ max-width: 480px;
112
+ width: 400px;
113
+ box-shadow: var(--shadow-elevated);
114
+ }
115
+
116
+ #search-bar input {
117
+ background: transparent;
118
+ border: none;
119
+ outline: none;
120
+ color: var(--text-primary);
121
+ font-size: 12px;
122
+ font-weight: 500;
123
+ flex: 1;
124
+ font-family: var(--font-sans);
125
+ min-width: 0;
126
+ }
127
+
128
+ #search-bar input::placeholder {
129
+ color: var(--text-muted);
130
+ }
131
+
132
+ #search-bar .stats {
133
+ color: var(--text-secondary);
134
+ font-size: var(--font-small);
135
+ font-family: var(--font-mono);
136
+ font-weight: 600;
137
+ white-space: nowrap;
138
+ flex-shrink: 0;
139
+ }
140
+
141
+ #search-bar svg {
142
+ flex-shrink: 0;
143
+ opacity: 0.5;
144
+ }
145
+
146
+ #refresh-btn {
147
+ background: transparent;
148
+ border: none;
149
+ border-radius: var(--radius-full);
150
+ width: 36px;
151
+ height: 36px;
152
+ padding: 0;
153
+ cursor: pointer;
154
+ color: var(--text-muted);
155
+ display: flex;
156
+ align-items: center;
157
+ justify-content: center;
158
+ transition: all 0.2s;
159
+ flex-shrink: 0;
160
+ }
161
+
162
+ #refresh-btn:hover {
163
+ color: var(--accent);
164
+ background: var(--accent-dim);
165
+ }
166
+
167
+ #refresh-btn.spinning svg {
168
+ animation: spin 0.8s linear infinite;
169
+ }
170
+
171
+ #refresh-btn.spinning {
172
+ pointer-events: none;
173
+ opacity: 0.7;
174
+ }
175
+
176
+ #refresh-btn.refresh-done {
177
+ color: #a6e3a1;
178
+ background: rgba(166,227,161,0.1);
179
+ }
180
+
181
+ #refresh-btn.refresh-error {
182
+ color: #f38ba8;
183
+ background: rgba(243,139,168,0.1);
184
+ }
185
+
186
+ @keyframes spin {
187
+ from { transform: rotate(0deg); }
188
+ to { transform: rotate(360deg); }
189
+ }
190
+
191
+
192
+ /* ============================================================================
193
+ VIEW TABS — floating transparent row, top-left
194
+ ============================================================================ */
195
+
196
+ #view-tabs {
197
+ position: fixed;
198
+ top: 20px;
199
+ left: 20px;
200
+ z-index: 100;
201
+ display: flex;
202
+ gap: 4px;
203
+ background: transparent;
204
+ border: none;
205
+ border-radius: 0;
206
+ padding: 0;
207
+ }
208
+
209
+ #view-tabs button {
210
+ background: transparent;
211
+ border: none;
212
+ border-bottom: 2px solid transparent;
213
+ color: var(--text-muted);
214
+ font-size: var(--font-micro);
215
+ font-weight: 700;
216
+ padding: 8px 14px;
217
+ text-transform: uppercase;
218
+ letter-spacing: 0.1em;
219
+ border-radius: 0;
220
+ cursor: pointer;
221
+ transition: all 0.2s;
222
+ font-family: var(--font-sans);
223
+ }
224
+
225
+ #view-tabs button:hover {
226
+ color: var(--text-secondary);
227
+ }
228
+
229
+ #view-tabs button.active {
230
+ color: var(--text-primary);
231
+ border-bottom-color: var(--accent);
232
+ font-weight: 700;
233
+ }
234
+
235
+
236
+ /* ============================================================================
237
+ CATEGORY PANEL
238
+ ============================================================================ */
239
+
240
+ #category-panel {
241
+ position: fixed;
242
+ top: 80px;
243
+ left: 20px;
244
+ z-index: 50;
245
+ background: rgba(16, 19, 25, 0.72);
246
+ border: 1px solid var(--border);
247
+ backdrop-filter: blur(8px);
248
+ -webkit-backdrop-filter: blur(8px);
249
+ border-radius: var(--radius-lg);
250
+ padding: var(--space-md);
251
+ min-width: 110px;
252
+ max-width: 170px;
253
+ width: 170px;
254
+ max-height: calc(100vh - 130px);
255
+ overflow-y: auto;
256
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
257
+ font-size: var(--font-small);
258
+ }
259
+
260
+ #category-panel::-webkit-scrollbar { width: 3px; }
261
+ #category-panel::-webkit-scrollbar-track { background: transparent; }
262
+ #category-panel::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 2px; }
263
+
264
+ .cat-header {
265
+ display: flex;
266
+ align-items: center;
267
+ justify-content: space-between;
268
+ padding-bottom: var(--space-sm);
269
+ margin-bottom: var(--space-sm);
270
+ }
271
+
272
+ .cat-title {
273
+ font-weight: 800;
274
+ color: var(--text-primary);
275
+ font-size: 24px;
276
+ letter-spacing: -0.03em;
277
+ }
278
+
279
+ .cat-controls {
280
+ display: flex;
281
+ gap: 4px;
282
+ }
283
+
284
+ .cat-mode-btn,
285
+ .cat-all-btn {
286
+ background: transparent;
287
+ border: none;
288
+ color: var(--text-muted);
289
+ border-radius: var(--radius-sm);
290
+ cursor: pointer;
291
+ display: flex;
292
+ align-items: center;
293
+ justify-content: center;
294
+ transition: all 0.15s;
295
+ }
296
+
297
+ .cat-mode-btn {
298
+ width: 18px;
299
+ height: 18px;
300
+ padding: 0;
301
+ }
302
+
303
+ .cat-all-btn {
304
+ padding: 4px 8px;
305
+ font-size: var(--font-micro);
306
+ font-weight: 600;
307
+ text-transform: uppercase;
308
+ letter-spacing: 0.06em;
309
+ }
310
+
311
+ .cat-mode-btn:hover,
312
+ .cat-all-btn:hover {
313
+ background: var(--bg-hover);
314
+ color: var(--text-primary);
315
+ }
316
+
317
+ .cat-mode-btn.active {
318
+ background: rgba(122, 162, 247, 0.15);
319
+ color: #7aa2f7;
320
+ }
321
+
322
+ .cat-item {
323
+ display: flex;
324
+ align-items: center;
325
+ gap: 6px;
326
+ padding: 7px var(--space-xs);
327
+ border-radius: var(--radius-sm);
328
+ cursor: pointer;
329
+ transition: background 0.12s;
330
+ user-select: none;
331
+ }
332
+
333
+ .cat-item:hover {
334
+ background: var(--bg-hover);
335
+ }
336
+
337
+ .cat-item.inactive {
338
+ opacity: 0.3;
339
+ }
340
+
341
+ .cat-dot {
342
+ width: 6px;
343
+ height: 6px;
344
+ border-radius: var(--radius-full);
345
+ flex-shrink: 0;
346
+ }
347
+
348
+ .cat-label {
349
+ flex: 1;
350
+ color: var(--text-primary);
351
+ font-size: var(--font-micro);
352
+ font-weight: 400;
353
+ text-transform: uppercase;
354
+ letter-spacing: 0.05em;
355
+ white-space: nowrap;
356
+ overflow: hidden;
357
+ text-overflow: ellipsis;
358
+ }
359
+
360
+ .cat-count {
361
+ color: var(--text-secondary);
362
+ font-size: 10px;
363
+ font-family: var(--font-mono);
364
+ font-weight: 600;
365
+ flex-shrink: 0;
366
+ }
367
+
368
+
369
+ /* ============================================================================
370
+ CHANGES PANEL
371
+ ============================================================================ */
372
+
373
+ #changes-panel {
374
+ position: fixed;
375
+ top: 80px;
376
+ left: 218px;
377
+ z-index: 50;
378
+ background: rgba(16, 19, 25, 0.72);
379
+ border: 1px solid var(--border);
380
+ backdrop-filter: blur(8px);
381
+ -webkit-backdrop-filter: blur(8px);
382
+ border-radius: var(--radius-md);
383
+ padding: var(--space-sm);
384
+ min-width: 90px;
385
+ max-width: 130px;
386
+ width: 130px;
387
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
388
+ font-size: var(--font-micro);
389
+ }
390
+
391
+ .changes-header {
392
+ display: flex;
393
+ align-items: center;
394
+ justify-content: space-between;
395
+ padding-bottom: var(--space-xs);
396
+ margin-bottom: var(--space-xs);
397
+ }
398
+
399
+ .changes-title {
400
+ font-weight: 800;
401
+ color: var(--text-primary);
402
+ font-size: 18px;
403
+ letter-spacing: -0.03em;
404
+ }
405
+
406
+ /* Toggle switch for changes */
407
+ .changes-toggle {
408
+ position: relative;
409
+ display: inline-block;
410
+ width: 22px;
411
+ height: 12px;
412
+ cursor: pointer;
413
+ }
414
+
415
+ .changes-toggle input {
416
+ opacity: 0;
417
+ width: 0;
418
+ height: 0;
419
+ }
420
+
421
+ .changes-toggle-slider {
422
+ position: absolute;
423
+ cursor: pointer;
424
+ top: 0;
425
+ left: 0;
426
+ right: 0;
427
+ bottom: 0;
428
+ background-color: var(--bg-tertiary);
429
+ border-radius: 12px;
430
+ transition: 0.15s;
431
+ }
432
+
433
+ .changes-toggle-slider::before {
434
+ position: absolute;
435
+ content: "";
436
+ height: 8px;
437
+ width: 8px;
438
+ left: 2px;
439
+ bottom: 2px;
440
+ background-color: var(--text-muted);
441
+ border-radius: var(--radius-full);
442
+ transition: 0.15s;
443
+ }
444
+
445
+ .changes-toggle input:checked + .changes-toggle-slider {
446
+ background-color: rgba(249, 226, 175, 0.3);
447
+ }
448
+
449
+ .changes-toggle input:checked + .changes-toggle-slider::before {
450
+ background-color: #f9e2af;
451
+ transform: translateX(10px);
452
+ }
453
+
454
+ .changes-stats {
455
+ margin-bottom: 2px;
456
+ }
457
+
458
+ .changes-stat-row {
459
+ display: flex;
460
+ align-items: center;
461
+ gap: 5px;
462
+ padding: 5px var(--space-xs);
463
+ border-radius: var(--radius-sm);
464
+ cursor: pointer;
465
+ transition: background 0.12s;
466
+ user-select: none;
467
+ }
468
+
469
+ .changes-stat-row:hover {
470
+ background: var(--bg-hover);
471
+ }
472
+
473
+ .changes-stat-row.active {
474
+ background: var(--bg-tertiary);
475
+ }
476
+
477
+ .changes-dot {
478
+ width: 5px;
479
+ height: 5px;
480
+ border-radius: var(--radius-full);
481
+ flex-shrink: 0;
482
+ }
483
+
484
+ .changes-label {
485
+ flex: 1;
486
+ color: var(--text-secondary);
487
+ font-size: var(--font-micro);
488
+ font-weight: 400;
489
+ text-transform: uppercase;
490
+ letter-spacing: 0.05em;
491
+ }
492
+
493
+ .changes-count {
494
+ color: var(--text-secondary);
495
+ font-size: 9px;
496
+ font-family: var(--font-mono);
497
+ font-weight: 600;
498
+ flex-shrink: 0;
499
+ }
500
+
501
+ .changes-total {
502
+ font-size: 8px;
503
+ font-weight: 500;
504
+ color: var(--text-muted);
505
+ text-align: center;
506
+ padding-top: 3px;
507
+ text-transform: uppercase;
508
+ letter-spacing: 0.08em;
509
+ }
510
+
511
+
512
+ /* ============================================================================
513
+ LEGEND — minimal horizontal row, bottom-left
514
+ ============================================================================ */
515
+
516
+ #legend {
517
+ position: fixed;
518
+ bottom: 20px;
519
+ left: 20px;
520
+ z-index: 100;
521
+ background: rgba(8,9,10,0.7);
522
+ backdrop-filter: blur(8px);
523
+ -webkit-backdrop-filter: blur(8px);
524
+ border: none;
525
+ border-radius: var(--radius-sm);
526
+ padding: 10px 16px;
527
+ font-size: var(--font-micro);
528
+ display: flex;
529
+ gap: 24px;
530
+ align-items: center;
531
+ }
532
+
533
+ #legend .item {
534
+ display: flex;
535
+ align-items: center;
536
+ gap: 10px;
537
+ color: var(--text-secondary);
538
+ margin-bottom: 0;
539
+ }
540
+
541
+ #legend .item:last-child { margin-bottom: 0; }
542
+
543
+ #legend .line {
544
+ width: 28px;
545
+ height: 2px;
546
+ border-radius: 1px;
547
+ }
548
+
549
+ #legend.hidden { display: none; }
550
+
551
+
552
+ /* ============================================================================
553
+ ZOOM INDICATOR — minimal, after legend
554
+ ============================================================================ */
555
+
556
+ #zoom-indicator {
557
+ position: fixed;
558
+ bottom: 20px;
559
+ left: 280px;
560
+ z-index: 100;
561
+ background: transparent;
562
+ border: none;
563
+ border-radius: var(--radius-sm);
564
+ padding: 8px 12px;
565
+ font-size: 14px;
566
+ display: flex;
567
+ align-items: center;
568
+ gap: 8px;
569
+ cursor: pointer;
570
+ transition: all 0.2s;
571
+ }
572
+
573
+ #zoom-indicator:hover {
574
+ background: var(--bg-hover);
575
+ }
576
+
577
+ #zoom-indicator.faded { opacity: 0.4; }
578
+ #zoom-indicator.faded:hover { opacity: 1; }
579
+
580
+ #zoom-indicator svg {
581
+ flex-shrink: 0;
582
+ cursor: pointer;
583
+ opacity: 0.5;
584
+ }
585
+
586
+ #zoom-indicator svg:hover {
587
+ stroke: var(--text-primary);
588
+ opacity: 1;
589
+ }
590
+
591
+ #zoom-indicator .zoom-input {
592
+ background: transparent;
593
+ border: none;
594
+ color: var(--text-secondary);
595
+ font-weight: 600;
596
+ font-size: 16px;
597
+ font-family: var(--font-mono);
598
+ width: 54px;
599
+ text-align: center;
600
+ padding: 2px 0;
601
+ cursor: text;
602
+ }
603
+
604
+ #zoom-indicator .zoom-input:focus {
605
+ outline: none;
606
+ background: var(--bg-tertiary);
607
+ border-radius: 4px;
608
+ color: var(--text-primary);
609
+ }
610
+
611
+
612
+ /* ============================================================================
613
+ DETAIL PANEL
614
+ ============================================================================ */
615
+
616
+ #detail-panel {
617
+ position: fixed;
618
+ top: 0;
619
+ right: -440px;
620
+ width: 420px;
621
+ min-width: 300px;
622
+ max-width: 80vw;
623
+ height: 100vh;
624
+ background: var(--bg-primary);
625
+ border-left: 1px solid var(--border);
626
+ z-index: 200;
627
+ overflow-y: auto;
628
+ transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);
629
+ box-shadow: -8px 0 40px rgba(0,0,0,0.5);
630
+ }
631
+
632
+ #detail-panel.open { right: 0; }
633
+ #detail-panel.resizing { transition: none; }
634
+
635
+ /* Horizontal resize handle */
636
+ #panel-resize-handle {
637
+ position: absolute;
638
+ left: -4px;
639
+ top: 0;
640
+ width: 8px;
641
+ height: 100%;
642
+ cursor: col-resize;
643
+ z-index: 201;
644
+ }
645
+
646
+ #panel-resize-handle::after {
647
+ content: '';
648
+ position: absolute;
649
+ left: 3px;
650
+ top: 50%;
651
+ transform: translateY(-50%);
652
+ width: 3px;
653
+ height: 50px;
654
+ background: var(--border-light);
655
+ border-radius: 2px;
656
+ opacity: 0;
657
+ transition: opacity 0.2s;
658
+ }
659
+
660
+ #panel-resize-handle:hover::after,
661
+ #detail-panel.resizing #panel-resize-handle::after {
662
+ opacity: 1;
663
+ background: var(--accent);
664
+ }
665
+
666
+ #detail-panel::-webkit-scrollbar { width: 4px; }
667
+ #detail-panel::-webkit-scrollbar-track { background: transparent; }
668
+ #detail-panel::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.06); border-radius: 2px; }
669
+
670
+ .panel-header {
671
+ position: sticky;
672
+ top: 0;
673
+ background: var(--bg-primary);
674
+ padding: var(--space-md) 22px;
675
+ z-index: 10;
676
+ border-bottom: 1px solid var(--border);
677
+ }
678
+
679
+ .panel-header h2 {
680
+ font-size: 30px;
681
+ font-weight: 800;
682
+ color: var(--accent-light);
683
+ margin-bottom: 6px;
684
+ padding-right: 48px;
685
+ line-height: 1.3;
686
+ letter-spacing: -0.03em;
687
+ }
688
+
689
+ .panel-header .path {
690
+ font-size: var(--font-micro);
691
+ color: var(--text-muted);
692
+ font-family: var(--font-mono);
693
+ word-break: break-all;
694
+ }
695
+
696
+ .close-btn {
697
+ position: absolute;
698
+ top: 14px;
699
+ right: 14px;
700
+ background: transparent;
701
+ border: none;
702
+ color: var(--text-muted);
703
+ width: 30px;
704
+ height: 30px;
705
+ border-radius: var(--radius-sm);
706
+ cursor: pointer;
707
+ font-size: 18px;
708
+ display: flex;
709
+ align-items: center;
710
+ justify-content: center;
711
+ transition: all 0.15s;
712
+ }
713
+
714
+ .close-btn:hover {
715
+ background: var(--bg-hover);
716
+ color: var(--text-primary);
717
+ }
718
+
719
+ .panel-body {
720
+ padding: var(--space-md) 22px var(--space-lg);
721
+ }
722
+
723
+ /* Description block */
724
+ .desc-block {
725
+ font-size: var(--font-body);
726
+ color: var(--text-secondary);
727
+ margin-bottom: var(--space-lg);
728
+ padding: var(--space-md) var(--space-lg);
729
+ background: var(--bg-secondary);
730
+ border-radius: var(--radius-md);
731
+ border-left: 3px solid var(--accent);
732
+ line-height: 1.6;
733
+ }
734
+
735
+ /* Meta row */
736
+ .meta-row {
737
+ display: flex;
738
+ gap: 10px;
739
+ margin-bottom: var(--space-lg);
740
+ flex-wrap: wrap;
741
+ }
742
+
743
+ .meta-badge {
744
+ background: var(--bg-secondary);
745
+ border: none;
746
+ padding: 6px 10px;
747
+ border-radius: var(--radius-sm);
748
+ font-size: var(--font-micro);
749
+ color: var(--text-secondary);
750
+ }
751
+
752
+ .meta-badge span {
753
+ color: var(--accent-light);
754
+ font-weight: 600;
755
+ font-family: var(--font-mono);
756
+ }
757
+
758
+ .meta-badge.script-badge {
759
+ cursor: pointer;
760
+ transition: background 0.12s;
761
+ }
762
+
763
+ .meta-badge.script-badge:hover {
764
+ background: var(--bg-tertiary);
765
+ }
766
+
767
+
768
+ /* ============================================================================
769
+ SECTIONS (detail panel content)
770
+ ============================================================================ */
771
+
772
+ .section {
773
+ margin-bottom: var(--space-lg);
774
+ }
775
+
776
+ .section .item-list {
777
+ /* No max-height — show all items */
778
+ }
779
+
780
+ .section-resize-handle {
781
+ position: relative;
782
+ height: 12px;
783
+ cursor: row-resize;
784
+ z-index: 5;
785
+ margin: 4px 0;
786
+ display: flex;
787
+ align-items: center;
788
+ justify-content: center;
789
+ }
790
+
791
+ .section-resize-handle::after {
792
+ content: '';
793
+ width: 40px;
794
+ height: 3px;
795
+ background: var(--border-light);
796
+ border-radius: 2px;
797
+ opacity: 0.3;
798
+ transition: opacity 0.2s;
799
+ }
800
+
801
+ .section-resize-handle:hover::after,
802
+ .section.resizing .section-resize-handle::after {
803
+ opacity: 1;
804
+ background: var(--accent);
805
+ }
806
+
807
+ .section-header {
808
+ display: flex;
809
+ align-items: center;
810
+ justify-content: space-between;
811
+ font-size: 16px;
812
+ font-weight: 700;
813
+ color: var(--text-primary);
814
+ padding-bottom: var(--space-sm);
815
+ margin-bottom: var(--space-sm);
816
+ border-bottom: none;
817
+ text-transform: none;
818
+ letter-spacing: -0.01em;
819
+ }
820
+
821
+ .section-count {
822
+ background: transparent;
823
+ color: var(--accent);
824
+ padding: 0;
825
+ border-radius: 0;
826
+ font-size: 16px;
827
+ font-family: var(--font-mono);
828
+ font-weight: 700;
829
+ }
830
+
831
+ .item-list { list-style: none; }
832
+
833
+ .item-list li {
834
+ padding: 6px 8px;
835
+ border-radius: var(--radius-sm);
836
+ margin-bottom: 2px;
837
+ font-size: 11px;
838
+ font-family: var(--font-mono);
839
+ cursor: default;
840
+ display: flex;
841
+ align-items: center;
842
+ gap: 6px;
843
+ line-height: 1.35;
844
+ min-width: 0;
845
+ }
846
+
847
+ #exports-list li,
848
+ #vars-list li,
849
+ #signals-list li,
850
+ .section .item-list li.clickable {
851
+ overflow-x: auto;
852
+ overflow-y: hidden;
853
+ white-space: nowrap;
854
+ }
855
+
856
+ #exports-list li::-webkit-scrollbar,
857
+ #vars-list li::-webkit-scrollbar,
858
+ #signals-list li::-webkit-scrollbar,
859
+ .section .item-list li.clickable::-webkit-scrollbar {
860
+ height: 4px;
861
+ }
862
+
863
+ #exports-list li::-webkit-scrollbar-thumb,
864
+ #vars-list li::-webkit-scrollbar-thumb,
865
+ #signals-list li::-webkit-scrollbar-thumb,
866
+ .section .item-list li.clickable::-webkit-scrollbar-thumb {
867
+ background: rgba(255,255,255,0.12);
868
+ border-radius: 2px;
869
+ }
870
+
871
+ .item-list li:hover { background: var(--bg-secondary); }
872
+ .item-list li.clickable { cursor: pointer; }
873
+ .item-list li.clickable:hover { background: var(--bg-tertiary); }
874
+
875
+ /* Scene usage list */
876
+ .scene-usage-section { margin-bottom: var(--space-lg); }
877
+
878
+ .scene-list li.scene-link {
879
+ cursor: pointer;
880
+ font-family: var(--font-sans);
881
+ }
882
+
883
+ .scene-list li.scene-link:hover {
884
+ background: rgba(166, 227, 161, 0.08);
885
+ }
886
+
887
+ .scene-list .scene-icon {
888
+ font-size: 16px;
889
+ }
890
+
891
+ .scene-list .scene-name {
892
+ color: #a6e3a1;
893
+ font-weight: 500;
894
+ }
895
+
896
+ /* Inline editable items */
897
+ .item-list li .item-actions {
898
+ margin-left: auto;
899
+ display: flex;
900
+ gap: 4px;
901
+ opacity: 0;
902
+ transition: opacity 0.15s;
903
+ flex-shrink: 0;
904
+ }
905
+
906
+ .item-list li:hover .item-actions { opacity: 1; }
907
+ .item-list li:hover .delete { opacity: 1 !important; }
908
+
909
+ .item-actions button {
910
+ background: var(--bg-tertiary);
911
+ border: none;
912
+ color: var(--text-muted);
913
+ width: 26px;
914
+ height: 26px;
915
+ border-radius: 6px;
916
+ cursor: pointer;
917
+ font-size: var(--font-small);
918
+ display: flex;
919
+ align-items: center;
920
+ justify-content: center;
921
+ }
922
+
923
+ .item-actions button:hover {
924
+ background: var(--bg-hover);
925
+ color: var(--text-primary);
926
+ }
927
+
928
+ .item-actions button.delete:hover {
929
+ background: rgba(243,139,168,0.15);
930
+ color: #f38ba8;
931
+ }
932
+
933
+ /* Inline editable spans */
934
+ .editable {
935
+ cursor: text;
936
+ padding: 2px 6px;
937
+ margin: -2px -6px;
938
+ border-radius: 4px;
939
+ transition: background 0.15s;
940
+ min-width: 20px;
941
+ display: inline-block;
942
+ }
943
+
944
+ .editable:hover { background: rgba(255,255,255,0.06); }
945
+
946
+ .editable:focus {
947
+ outline: none;
948
+ background: rgba(255,255,255,0.1);
949
+ box-shadow: 0 0 0 1px var(--accent);
950
+ }
951
+
952
+ .editable[data-placeholder]:empty::before {
953
+ content: attr(data-placeholder);
954
+ color: var(--text-muted);
955
+ opacity: 0.5;
956
+ }
957
+
958
+ /* @onready badge */
959
+ .onready-badge {
960
+ display: inline-block;
961
+ font-size: var(--font-micro);
962
+ padding: 3px 7px;
963
+ background: rgba(137, 180, 250, 0.15);
964
+ color: #89b4fa;
965
+ border-radius: 4px;
966
+ margin-right: 8px;
967
+ font-weight: 500;
968
+ cursor: pointer;
969
+ user-select: none;
970
+ text-transform: uppercase;
971
+ letter-spacing: 1px;
972
+ }
973
+
974
+ .onready-badge:hover { background: rgba(137, 180, 250, 0.25); }
975
+
976
+ .onready-badge.inactive {
977
+ background: rgba(255,255,255,0.04);
978
+ color: var(--text-muted);
979
+ opacity: 0.5;
980
+ }
981
+
982
+
983
+ /* ============================================================================
984
+ CONTEXT MENUS
985
+ ============================================================================ */
986
+
987
+ #context-menu {
988
+ position: fixed;
989
+ z-index: 500;
990
+ background: var(--bg-secondary);
991
+ border: none;
992
+ border-radius: var(--radius-md);
993
+ padding: 8px 0;
994
+ min-width: 200px;
995
+ box-shadow: var(--shadow-menu);
996
+ display: none;
997
+ }
998
+
999
+ #context-menu.visible { display: block; }
1000
+
1001
+ #context-menu .menu-item {
1002
+ display: flex;
1003
+ align-items: center;
1004
+ gap: 12px;
1005
+ padding: 12px 18px;
1006
+ font-size: var(--font-body);
1007
+ color: var(--text-secondary);
1008
+ cursor: pointer;
1009
+ transition: background 0.1s;
1010
+ }
1011
+
1012
+ #context-menu .menu-item:hover {
1013
+ background: var(--bg-hover);
1014
+ color: var(--text-primary);
1015
+ }
1016
+
1017
+ #context-menu .menu-item svg { flex-shrink: 0; opacity: 0.6; }
1018
+
1019
+ #context-menu .menu-divider {
1020
+ height: 1px;
1021
+ background: var(--border);
1022
+ margin: 6px 12px;
1023
+ }
1024
+
1025
+ /* Scene Context Menu */
1026
+ #scene-context-menu {
1027
+ position: fixed;
1028
+ z-index: 500;
1029
+ background: var(--bg-secondary);
1030
+ border: none;
1031
+ border-radius: var(--radius-md);
1032
+ padding: 8px 0;
1033
+ min-width: 200px;
1034
+ box-shadow: var(--shadow-menu);
1035
+ display: none;
1036
+ }
1037
+
1038
+ #scene-context-menu.visible { display: block; }
1039
+
1040
+ #scene-context-menu .menu-item {
1041
+ display: flex;
1042
+ align-items: center;
1043
+ gap: 12px;
1044
+ padding: 12px 18px;
1045
+ font-size: var(--font-body);
1046
+ color: var(--text-secondary);
1047
+ cursor: pointer;
1048
+ transition: background 0.1s;
1049
+ }
1050
+
1051
+ #scene-context-menu .menu-item:hover {
1052
+ background: var(--bg-hover);
1053
+ color: var(--text-primary);
1054
+ }
1055
+
1056
+ #scene-context-menu .menu-item.danger { color: #f38ba8; }
1057
+ #scene-context-menu .menu-item.danger:hover { background: rgba(243, 139, 168, 0.1); }
1058
+
1059
+ #scene-context-menu .menu-item svg { flex-shrink: 0; opacity: 0.6; }
1060
+
1061
+ #scene-context-menu .menu-divider {
1062
+ height: 1px;
1063
+ background: var(--border);
1064
+ margin: 6px 12px;
1065
+ }
1066
+
1067
+
1068
+ /* ============================================================================
1069
+ MODALS
1070
+ ============================================================================ */
1071
+
1072
+ .modal {
1073
+ position: fixed;
1074
+ top: 0;
1075
+ left: 0;
1076
+ right: 0;
1077
+ bottom: 0;
1078
+ background: rgba(0,0,0,0.7);
1079
+ z-index: 600;
1080
+ display: flex;
1081
+ align-items: center;
1082
+ justify-content: center;
1083
+ backdrop-filter: blur(4px);
1084
+ -webkit-backdrop-filter: blur(4px);
1085
+ }
1086
+
1087
+ .modal-content {
1088
+ background: var(--bg-secondary);
1089
+ border: none;
1090
+ border-radius: var(--radius-lg);
1091
+ width: 420px;
1092
+ box-shadow: var(--shadow-modal);
1093
+ overflow: hidden;
1094
+ }
1095
+
1096
+ .modal-header {
1097
+ display: flex;
1098
+ align-items: center;
1099
+ justify-content: space-between;
1100
+ padding: var(--space-lg);
1101
+ }
1102
+
1103
+ .modal-header h3 {
1104
+ font-size: 22px;
1105
+ font-weight: 700;
1106
+ color: var(--text-primary);
1107
+ letter-spacing: -0.02em;
1108
+ }
1109
+
1110
+ .modal-body {
1111
+ padding: 0 var(--space-lg) var(--space-lg);
1112
+ }
1113
+
1114
+ .modal-body .form-group {
1115
+ margin-bottom: var(--space-lg);
1116
+ }
1117
+
1118
+ .modal-body .form-group:last-child { margin-bottom: 0; }
1119
+
1120
+ .modal-body label {
1121
+ display: block;
1122
+ font-size: var(--font-small);
1123
+ color: var(--text-secondary);
1124
+ margin-bottom: var(--space-xs);
1125
+ font-weight: 500;
1126
+ }
1127
+
1128
+ .modal-body input,
1129
+ .modal-body select {
1130
+ width: 100%;
1131
+ background: var(--bg-tertiary);
1132
+ border: 1px solid var(--border);
1133
+ border-radius: var(--radius-sm);
1134
+ padding: 12px var(--space-md);
1135
+ font-size: var(--font-body);
1136
+ color: var(--text-primary);
1137
+ font-family: var(--font-mono);
1138
+ transition: border-color 0.15s;
1139
+ }
1140
+
1141
+ .modal-body input:focus,
1142
+ .modal-body select:focus {
1143
+ outline: none;
1144
+ border-color: var(--accent);
1145
+ }
1146
+
1147
+ .modal-footer {
1148
+ display: flex;
1149
+ justify-content: flex-end;
1150
+ gap: 12px;
1151
+ padding: var(--space-lg);
1152
+ background: var(--bg-tertiary);
1153
+ }
1154
+
1155
+ .modal-footer button {
1156
+ padding: 10px 20px;
1157
+ border-radius: var(--radius-sm);
1158
+ font-size: var(--font-body);
1159
+ cursor: pointer;
1160
+ border: none;
1161
+ font-weight: 500;
1162
+ transition: all 0.15s;
1163
+ }
1164
+
1165
+ .modal-footer .cancel {
1166
+ background: var(--bg-secondary);
1167
+ color: var(--text-secondary);
1168
+ }
1169
+
1170
+ .modal-footer .cancel:hover {
1171
+ background: var(--bg-hover);
1172
+ }
1173
+
1174
+ .modal-footer .confirm {
1175
+ background: var(--accent);
1176
+ color: var(--bg-primary);
1177
+ }
1178
+
1179
+ .modal-footer .confirm:hover {
1180
+ background: var(--accent-light);
1181
+ }
1182
+
1183
+
1184
+ /* ============================================================================
1185
+ TIMELINE / ACTIVITY PANEL
1186
+ ============================================================================ */
1187
+
1188
+ #timeline-panel {
1189
+ position: fixed;
1190
+ bottom: 20px;
1191
+ right: 20px;
1192
+ z-index: 50;
1193
+ background: rgba(16, 19, 25, 0.72);
1194
+ border: 1px solid var(--border);
1195
+ backdrop-filter: blur(8px);
1196
+ -webkit-backdrop-filter: blur(8px);
1197
+ border-radius: var(--radius-lg);
1198
+ width: 250px;
1199
+ max-width: 250px;
1200
+ max-height: calc(100vh - 40px);
1201
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.3);
1202
+ font-size: var(--font-body);
1203
+ display: flex;
1204
+ flex-direction: column;
1205
+ overflow: hidden;
1206
+ padding: var(--space-lg);
1207
+ }
1208
+
1209
+ #timeline-panel.collapsed .tl-body {
1210
+ display: none;
1211
+ }
1212
+
1213
+ #timeline-panel.collapsed .tl-chevron {
1214
+ transform: rotate(-90deg);
1215
+ }
1216
+
1217
+ .tl-header {
1218
+ display: flex;
1219
+ align-items: center;
1220
+ gap: 8px;
1221
+ padding: var(--space-sm) var(--space-md);
1222
+ padding-bottom: var(--space-md);
1223
+ margin-bottom: var(--space-md);
1224
+ cursor: pointer;
1225
+ user-select: none;
1226
+ transition: background 0.12s;
1227
+ }
1228
+
1229
+ .tl-header:hover {
1230
+ background: var(--bg-hover);
1231
+ }
1232
+
1233
+ .tl-title {
1234
+ font-weight: 800;
1235
+ color: var(--text-primary);
1236
+ font-size: var(--font-h1);
1237
+ flex: 1;
1238
+ text-transform: none;
1239
+ letter-spacing: -0.03em;
1240
+ }
1241
+
1242
+ .tl-count {
1243
+ background: transparent;
1244
+ color: var(--text-secondary);
1245
+ padding: 0;
1246
+ border-radius: 0;
1247
+ font-size: 13px;
1248
+ font-family: var(--font-mono);
1249
+ font-weight: 600;
1250
+ }
1251
+
1252
+ .tl-chevron {
1253
+ color: var(--text-muted);
1254
+ transition: transform 0.2s;
1255
+ flex-shrink: 0;
1256
+ }
1257
+
1258
+ .tl-body {
1259
+ overflow-y: auto;
1260
+ max-height: calc(100vh - 170px);
1261
+ }
1262
+
1263
+ .tl-body::-webkit-scrollbar { width: 3px; }
1264
+ .tl-body::-webkit-scrollbar-track { background: transparent; }
1265
+ .tl-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.06); border-radius: 2px; }
1266
+
1267
+ .tl-empty {
1268
+ padding: var(--space-xl) var(--space-lg);
1269
+ text-align: center;
1270
+ color: var(--text-muted);
1271
+ font-size: var(--font-body);
1272
+ font-style: italic;
1273
+ }
1274
+
1275
+ .tl-list {
1276
+ padding: var(--space-xs) 0;
1277
+ }
1278
+
1279
+ /* File-grouped card */
1280
+ .tl-card {
1281
+ margin: 6px var(--space-sm);
1282
+ background: var(--bg-surface);
1283
+ border: none;
1284
+ border-radius: var(--radius-sm);
1285
+ overflow: hidden;
1286
+ box-shadow: 0 1px 4px rgba(0,0,0,0.2);
1287
+ }
1288
+
1289
+ .tl-card-header {
1290
+ display: flex;
1291
+ align-items: center;
1292
+ gap: 8px;
1293
+ padding: 10px var(--space-sm);
1294
+ background: var(--bg-tertiary);
1295
+ font-size: var(--font-small);
1296
+ cursor: pointer;
1297
+ transition: background 0.1s;
1298
+ }
1299
+
1300
+ .tl-card-header:hover {
1301
+ background: var(--bg-hover);
1302
+ }
1303
+
1304
+ .tl-card-file {
1305
+ color: var(--accent-light);
1306
+ font-weight: 600;
1307
+ font-size: var(--font-body);
1308
+ flex: 1;
1309
+ overflow: hidden;
1310
+ text-overflow: ellipsis;
1311
+ white-space: nowrap;
1312
+ }
1313
+
1314
+ .tl-card-time {
1315
+ color: var(--text-muted);
1316
+ font-size: var(--font-micro);
1317
+ font-family: var(--font-mono);
1318
+ flex-shrink: 0;
1319
+ }
1320
+
1321
+ /* Action items within a card */
1322
+ .tl-action {
1323
+ display: flex;
1324
+ align-items: flex-start;
1325
+ gap: 10px;
1326
+ padding: 10px var(--space-sm);
1327
+ font-size: var(--font-body);
1328
+ border-bottom: 1px solid var(--border);
1329
+ transition: background 0.1s;
1330
+ cursor: pointer;
1331
+ }
1332
+
1333
+ .tl-action:last-child {
1334
+ border-bottom: none;
1335
+ }
1336
+
1337
+ .tl-action:hover {
1338
+ background: rgba(255, 255, 255, 0.02);
1339
+ }
1340
+
1341
+ .tl-action-icon {
1342
+ font-size: var(--font-body);
1343
+ flex-shrink: 0;
1344
+ line-height: 1.4;
1345
+ }
1346
+
1347
+ .tl-action-text {
1348
+ color: var(--text-secondary);
1349
+ flex: 1;
1350
+ line-height: 1.5;
1351
+ font-size: var(--font-small);
1352
+ }
1353
+
1354
+ .tl-action-text .tl-name {
1355
+ color: var(--accent-light);
1356
+ font-weight: 500;
1357
+ }
1358
+
1359
+ .tl-action-reason {
1360
+ font-size: var(--font-small);
1361
+ color: var(--text-muted);
1362
+ font-style: italic;
1363
+ margin-top: 4px;
1364
+ line-height: 1.4;
1365
+ }
1366
+
1367
+ .tl-action-time {
1368
+ color: var(--text-muted);
1369
+ font-size: var(--font-micro);
1370
+ font-family: var(--font-mono);
1371
+ flex-shrink: 0;
1372
+ margin-top: 2px;
1373
+ }
1374
+
1375
+
1376
+ /* ============================================================================
1377
+ FLOATING USAGE PANEL
1378
+ ============================================================================ */
1379
+
1380
+ #usage-float-panel {
1381
+ position: fixed;
1382
+ top: 80px;
1383
+ right: 500px;
1384
+ width: 400px;
1385
+ min-width: 320px;
1386
+ min-height: 260px;
1387
+ max-height: calc(100vh - 100px);
1388
+ background: var(--bg-secondary);
1389
+ border: none;
1390
+ border-radius: var(--radius-lg);
1391
+ box-shadow: var(--shadow-menu);
1392
+ z-index: 150;
1393
+ display: none;
1394
+ flex-direction: column;
1395
+ overflow: hidden;
1396
+ }
1397
+
1398
+ #usage-float-panel.visible { display: flex; }
1399
+ #usage-float-panel.dragging { user-select: none; }
1400
+
1401
+ /* Resize handle */
1402
+ #usage-float-panel .ufp-resize {
1403
+ position: absolute;
1404
+ bottom: 0;
1405
+ right: 0;
1406
+ width: 18px;
1407
+ height: 18px;
1408
+ cursor: nwse-resize;
1409
+ z-index: 10;
1410
+ }
1411
+
1412
+ #usage-float-panel .ufp-resize::after {
1413
+ content: '';
1414
+ position: absolute;
1415
+ right: 5px;
1416
+ bottom: 5px;
1417
+ width: 8px;
1418
+ height: 8px;
1419
+ border-right: 2px solid var(--border-light);
1420
+ border-bottom: 2px solid var(--border-light);
1421
+ opacity: 0.4;
1422
+ }
1423
+
1424
+ #usage-float-panel .ufp-resize:hover::after { opacity: 0.8; }
1425
+
1426
+ #usage-float-panel .ufp-header {
1427
+ display: flex;
1428
+ align-items: flex-start;
1429
+ justify-content: space-between;
1430
+ gap: var(--space-md);
1431
+ padding: var(--space-md) var(--space-lg);
1432
+ background: rgba(243, 139, 168, 0.08);
1433
+ cursor: grab;
1434
+ }
1435
+
1436
+ #usage-float-panel .ufp-header:active { cursor: grabbing; }
1437
+
1438
+ #usage-float-panel .ufp-header .ufp-info {
1439
+ flex: 1;
1440
+ min-width: 0;
1441
+ }
1442
+
1443
+ #usage-float-panel .ufp-header .ufp-title {
1444
+ font-size: var(--font-h2);
1445
+ font-weight: 600;
1446
+ color: #f38ba8;
1447
+ line-height: 1.3;
1448
+ }
1449
+
1450
+ #usage-float-panel .ufp-header .ufp-count {
1451
+ font-size: var(--font-small);
1452
+ color: var(--text-secondary);
1453
+ margin-top: 6px;
1454
+ line-height: 1.3;
1455
+ }
1456
+
1457
+ #usage-float-panel .ufp-header .ufp-count .count-num {
1458
+ font-weight: 700;
1459
+ font-size: var(--font-body);
1460
+ font-family: var(--font-mono);
1461
+ color: #fab387;
1462
+ }
1463
+
1464
+ #usage-float-panel .ufp-header .ufp-buttons {
1465
+ display: flex;
1466
+ gap: 6px;
1467
+ align-items: center;
1468
+ flex-shrink: 0;
1469
+ }
1470
+
1471
+ #usage-float-panel .ufp-header .refresh-btn,
1472
+ #usage-float-panel .ufp-header .close-btn {
1473
+ background: transparent;
1474
+ border: none;
1475
+ color: var(--text-muted);
1476
+ width: 30px;
1477
+ height: 30px;
1478
+ border-radius: var(--radius-sm);
1479
+ cursor: pointer;
1480
+ font-size: var(--font-body);
1481
+ display: flex;
1482
+ align-items: center;
1483
+ justify-content: center;
1484
+ flex-shrink: 0;
1485
+ transition: all 0.15s;
1486
+ }
1487
+
1488
+ #usage-float-panel .ufp-header .close-btn {
1489
+ font-size: 18px;
1490
+ }
1491
+
1492
+ #usage-float-panel .ufp-header .refresh-btn:hover,
1493
+ #usage-float-panel .ufp-header .close-btn:hover {
1494
+ background: var(--bg-hover);
1495
+ color: var(--text-primary);
1496
+ }
1497
+
1498
+ #usage-float-panel .ufp-list {
1499
+ flex: 1;
1500
+ overflow-y: auto;
1501
+ max-height: 320px;
1502
+ }
1503
+
1504
+ #usage-float-panel .ufp-item {
1505
+ display: flex;
1506
+ flex-direction: column;
1507
+ gap: 6px;
1508
+ padding: var(--space-sm) var(--space-lg);
1509
+ font-size: var(--font-small);
1510
+ cursor: pointer;
1511
+ border-bottom: 1px solid var(--border);
1512
+ transition: background 0.1s;
1513
+ }
1514
+
1515
+ #usage-float-panel .ufp-item:last-child { border-bottom: none; }
1516
+ #usage-float-panel .ufp-item:hover { background: var(--bg-hover); }
1517
+
1518
+ #usage-float-panel .ufp-item.active {
1519
+ background: var(--accent-dim);
1520
+ border-left: 3px solid var(--accent);
1521
+ margin-left: -3px;
1522
+ padding-left: calc(var(--space-lg) - 3px);
1523
+ }
1524
+
1525
+ #usage-float-panel .ufp-item .ufp-loc {
1526
+ display: flex;
1527
+ align-items: center;
1528
+ gap: 10px;
1529
+ }
1530
+
1531
+ #usage-float-panel .ufp-item .ufp-file {
1532
+ color: var(--text-muted);
1533
+ font-size: var(--font-small);
1534
+ }
1535
+
1536
+ #usage-float-panel .ufp-item .ufp-func {
1537
+ color: #89dceb;
1538
+ font-weight: 600;
1539
+ font-size: var(--font-small);
1540
+ }
1541
+
1542
+ #usage-float-panel .ufp-item .ufp-func::before {
1543
+ content: 'func ';
1544
+ color: var(--gd-keyword);
1545
+ font-weight: normal;
1546
+ }
1547
+
1548
+ #usage-float-panel .ufp-item .ufp-line {
1549
+ color: var(--text-muted);
1550
+ font-size: var(--font-micro);
1551
+ font-family: var(--font-mono);
1552
+ margin-left: auto;
1553
+ }
1554
+
1555
+ #usage-float-panel .ufp-item .ufp-code {
1556
+ color: var(--text-secondary);
1557
+ font-family: var(--font-mono);
1558
+ font-size: var(--font-small);
1559
+ background: var(--bg-tertiary);
1560
+ padding: 8px var(--space-sm);
1561
+ border-radius: 6px;
1562
+ overflow: hidden;
1563
+ text-overflow: ellipsis;
1564
+ white-space: nowrap;
1565
+ }
1566
+
1567
+ #usage-float-panel .ufp-item .ufp-code .highlight {
1568
+ color: #f38ba8;
1569
+ font-weight: 600;
1570
+ background: rgba(243, 139, 168, 0.12);
1571
+ padding: 1px 4px;
1572
+ border-radius: 3px;
1573
+ }
1574
+
1575
+ #usage-float-panel .ufp-actions {
1576
+ display: flex;
1577
+ gap: 12px;
1578
+ padding: var(--space-md) var(--space-lg);
1579
+ background: var(--bg-tertiary);
1580
+ }
1581
+
1582
+ #usage-float-panel .ufp-actions button {
1583
+ flex: 1;
1584
+ padding: 10px var(--space-md);
1585
+ border-radius: var(--radius-sm);
1586
+ font-size: var(--font-small);
1587
+ cursor: pointer;
1588
+ border: none;
1589
+ font-weight: 500;
1590
+ transition: all 0.15s;
1591
+ }
1592
+
1593
+ #usage-float-panel .ufp-actions .cancel {
1594
+ background: var(--bg-secondary);
1595
+ color: var(--text-secondary);
1596
+ }
1597
+
1598
+ #usage-float-panel .ufp-actions .cancel:hover {
1599
+ background: var(--bg-hover);
1600
+ }
1601
+
1602
+ #usage-float-panel .ufp-actions .delete {
1603
+ background: rgba(243, 139, 168, 0.15);
1604
+ color: #f38ba8;
1605
+ }
1606
+
1607
+ #usage-float-panel .ufp-actions .delete:hover {
1608
+ background: rgba(243, 139, 168, 0.25);
1609
+ }
1610
+
1611
+
1612
+ /* ============================================================================
1613
+ CODE LINE HIGHLIGHT
1614
+ ============================================================================ */
1615
+
1616
+ .code-line-highlight {
1617
+ background: rgba(243, 139, 168, 0.2) !important;
1618
+ border-left: 3px solid #f38ba8 !important;
1619
+ margin-left: -14px !important;
1620
+ padding-left: 11px !important;
1621
+ }
1622
+
1623
+
1624
+ /* ============================================================================
1625
+ ADD ITEM FORM
1626
+ ============================================================================ */
1627
+
1628
+ .add-item-btn {
1629
+ display: flex;
1630
+ align-items: center;
1631
+ gap: 8px;
1632
+ padding: 10px var(--space-sm);
1633
+ color: var(--text-muted);
1634
+ font-size: var(--font-small);
1635
+ cursor: pointer;
1636
+ border-radius: var(--radius-sm);
1637
+ margin-top: 6px;
1638
+ transition: all 0.12s;
1639
+ }
1640
+
1641
+ .add-item-btn:hover {
1642
+ background: var(--bg-secondary);
1643
+ color: var(--text-secondary);
1644
+ }
1645
+
1646
+ .add-item-btn svg { opacity: 0.5; }
1647
+
1648
+ .add-item-form {
1649
+ background: var(--bg-secondary);
1650
+ border: none;
1651
+ border-radius: var(--radius-md);
1652
+ padding: var(--space-md);
1653
+ margin-top: var(--space-sm);
1654
+ box-shadow: var(--shadow-panel);
1655
+ }
1656
+
1657
+ .add-item-form .form-row {
1658
+ display: flex;
1659
+ gap: 10px;
1660
+ margin-bottom: var(--space-sm);
1661
+ }
1662
+
1663
+ .add-item-form .form-row:last-child { margin-bottom: 0; }
1664
+
1665
+ .add-item-form input,
1666
+ .add-item-form select {
1667
+ flex: 1;
1668
+ background: var(--bg-tertiary);
1669
+ border: 1px solid var(--border);
1670
+ color: var(--text-primary);
1671
+ padding: 8px var(--space-sm);
1672
+ border-radius: 6px;
1673
+ font-size: var(--font-small);
1674
+ font-family: inherit;
1675
+ transition: border-color 0.15s;
1676
+ }
1677
+
1678
+ .add-item-form input:focus,
1679
+ .add-item-form select:focus {
1680
+ outline: none;
1681
+ border-color: var(--accent);
1682
+ }
1683
+
1684
+ .add-item-form .form-actions {
1685
+ display: flex;
1686
+ gap: 10px;
1687
+ justify-content: flex-end;
1688
+ }
1689
+
1690
+ .add-item-form button {
1691
+ padding: 8px var(--space-md);
1692
+ border-radius: 6px;
1693
+ font-size: var(--font-small);
1694
+ cursor: pointer;
1695
+ border: none;
1696
+ font-weight: 500;
1697
+ transition: all 0.15s;
1698
+ }
1699
+
1700
+ .add-item-form button.cancel {
1701
+ background: var(--bg-tertiary);
1702
+ color: var(--text-secondary);
1703
+ }
1704
+
1705
+ .add-item-form button.confirm {
1706
+ background: var(--accent);
1707
+ color: var(--bg-primary);
1708
+ font-weight: 600;
1709
+ }
1710
+
1711
+ .add-item-form button.confirm:hover {
1712
+ background: var(--accent-light);
1713
+ }
1714
+
1715
+
1716
+ /* ============================================================================
1717
+ SYNTAX TOKENS — UNCHANGED colors
1718
+ ============================================================================ */
1719
+
1720
+ .kw { color: var(--gd-keyword); font-weight: 600; }
1721
+ .fn { color: var(--gd-func-name); }
1722
+ .tp { color: var(--gd-type); }
1723
+ .str { color: var(--gd-string); }
1724
+ .num { color: var(--gd-number); }
1725
+ .cmt { color: var(--gd-comment); font-style: italic; }
1726
+ .sig { color: var(--gd-signal); }
1727
+ .exp { color: var(--gd-export); }
1728
+ .param { color: var(--text-secondary); }
1729
+ .ret { color: var(--text-muted); }
1730
+
1731
+
1732
+ /* ============================================================================
1733
+ TAGS
1734
+ ============================================================================ */
1735
+
1736
+ .tag {
1737
+ font-size: var(--font-micro);
1738
+ padding: 3px 8px;
1739
+ border-radius: 4px;
1740
+ font-family: var(--font-sans);
1741
+ font-weight: 600;
1742
+ text-transform: uppercase;
1743
+ letter-spacing: 0.5px;
1744
+ }
1745
+
1746
+ .tag-export { background: rgba(187, 181, 41, 0.12); color: var(--gd-export); }
1747
+ .tag-signal { background: rgba(166, 227, 161, 0.12); color: var(--gd-signal); }
1748
+ .tag-lines { background: var(--bg-tertiary); color: var(--text-muted); font-weight: normal; }
1749
+ .tag-return { background: rgba(104, 151, 187, 0.12); color: var(--gd-type); }
1750
+
1751
+
1752
+ /* ============================================================================
1753
+ FUNCTION VIEWER
1754
+ ============================================================================ */
1755
+
1756
+ .func-viewer {
1757
+ margin-top: var(--space-lg);
1758
+ background: var(--bg-secondary);
1759
+ border: none;
1760
+ border-radius: var(--radius-md);
1761
+ overflow: hidden;
1762
+ box-shadow: var(--shadow-panel);
1763
+ }
1764
+
1765
+ .func-viewer-header {
1766
+ display: flex;
1767
+ align-items: center;
1768
+ justify-content: space-between;
1769
+ padding: var(--space-sm) var(--space-lg);
1770
+ background: var(--bg-tertiary);
1771
+ font-size: var(--font-body);
1772
+ color: var(--text-secondary);
1773
+ }
1774
+
1775
+ .func-viewer-header .func-title {
1776
+ color: var(--gd-func-name);
1777
+ font-weight: 600;
1778
+ }
1779
+
1780
+ .func-viewer-close {
1781
+ background: none;
1782
+ border: none;
1783
+ color: var(--text-muted);
1784
+ cursor: pointer;
1785
+ font-size: 16px;
1786
+ padding: 4px 8px;
1787
+ border-radius: 6px;
1788
+ transition: all 0.15s;
1789
+ }
1790
+
1791
+ .func-viewer-close:hover {
1792
+ color: var(--text-primary);
1793
+ background: var(--bg-hover);
1794
+ }
1795
+
1796
+ .func-viewer-code {
1797
+ position: relative;
1798
+ padding: var(--space-md) 0;
1799
+ font-family: var(--font-mono);
1800
+ font-size: 13px;
1801
+ line-height: 1.7;
1802
+ overflow: auto;
1803
+ tab-size: 4;
1804
+ }
1805
+
1806
+ /* Editable code area */
1807
+ .code-editor-container {
1808
+ position: relative;
1809
+ margin: 0 var(--space-lg);
1810
+ }
1811
+
1812
+ .code-editor-textarea {
1813
+ position: absolute;
1814
+ top: 0;
1815
+ left: 0;
1816
+ width: 100%;
1817
+ height: 100%;
1818
+ font-family: inherit;
1819
+ font-size: inherit;
1820
+ line-height: inherit;
1821
+ tab-size: inherit;
1822
+ padding: 0;
1823
+ margin: 0;
1824
+ border: none;
1825
+ background: transparent;
1826
+ color: transparent;
1827
+ caret-color: var(--text-primary);
1828
+ resize: none;
1829
+ outline: none;
1830
+ overflow: hidden;
1831
+ white-space: pre;
1832
+ }
1833
+
1834
+ .code-editor-textarea::selection {
1835
+ background: rgba(255, 255, 255, 0.15);
1836
+ }
1837
+
1838
+ .code-editor-highlight {
1839
+ white-space: pre;
1840
+ pointer-events: none;
1841
+ }
1842
+
1843
+ .code-editor-container:focus-within {
1844
+ outline: 1px solid var(--accent);
1845
+ outline-offset: 6px;
1846
+ border-radius: 4px;
1847
+ }
1848
+
1849
+ .func-viewer-footer {
1850
+ display: flex;
1851
+ align-items: center;
1852
+ justify-content: space-between;
1853
+ padding: 10px var(--space-lg);
1854
+ background: var(--bg-tertiary);
1855
+ font-size: var(--font-small);
1856
+ color: var(--text-muted);
1857
+ }
1858
+
1859
+ .func-viewer-footer .status { opacity: 0; transition: opacity 0.2s; }
1860
+ .func-viewer-footer .status.visible { opacity: 1; }
1861
+
1862
+ .func-viewer-footer .save-btn {
1863
+ background: var(--accent);
1864
+ color: var(--bg-primary);
1865
+ border: none;
1866
+ padding: 6px var(--space-md);
1867
+ border-radius: 6px;
1868
+ font-size: var(--font-small);
1869
+ font-weight: 600;
1870
+ cursor: pointer;
1871
+ opacity: 0.5;
1872
+ transition: all 0.2s;
1873
+ }
1874
+
1875
+ .func-viewer-footer .save-btn.active { opacity: 1; }
1876
+ .func-viewer-footer .save-btn.active:hover { background: var(--accent-light); }
1877
+
1878
+ .code-line {
1879
+ display: block;
1880
+ padding: 0 var(--space-lg);
1881
+ min-height: 1.5em;
1882
+ white-space: pre;
1883
+ }
1884
+
1885
+ .code-line:hover { background: rgba(255,255,255,0.02); }
1886
+
1887
+ .line-num {
1888
+ color: var(--text-muted);
1889
+ min-width: 40px;
1890
+ text-align: right;
1891
+ padding-right: var(--space-md);
1892
+ user-select: none;
1893
+ flex-shrink: 0;
1894
+ font-size: var(--font-small);
1895
+ }
1896
+
1897
+ .line-content {
1898
+ white-space: pre;
1899
+ flex: 1;
1900
+ }
1901
+
1902
+
1903
+ /* ============================================================================
1904
+ SCENE VIEW STYLES
1905
+ ============================================================================ */
1906
+
1907
+ #scene-back-btn {
1908
+ position: fixed;
1909
+ top: 24px;
1910
+ left: 200px;
1911
+ z-index: 100;
1912
+ display: flex;
1913
+ align-items: center;
1914
+ gap: 8px;
1915
+ background: var(--bg-secondary);
1916
+ border: none;
1917
+ border-radius: var(--radius-sm);
1918
+ padding: 10px var(--space-md);
1919
+ font-size: var(--font-small);
1920
+ color: var(--text-secondary);
1921
+ cursor: pointer;
1922
+ box-shadow: var(--shadow-panel);
1923
+ transition: all 0.15s;
1924
+ }
1925
+
1926
+ #scene-back-btn:hover {
1927
+ background: var(--bg-hover);
1928
+ color: var(--text-primary);
1929
+ }
1930
+
1931
+ #scene-back-btn svg {
1932
+ flex-shrink: 0;
1933
+ opacity: 0.6;
1934
+ width: 14px;
1935
+ height: 14px;
1936
+ }
1937
+
1938
+ #scene-back-btn .scene-name {
1939
+ color: var(--accent);
1940
+ font-weight: 600;
1941
+ max-width: 120px;
1942
+ overflow: hidden;
1943
+ text-overflow: ellipsis;
1944
+ white-space: nowrap;
1945
+ }
1946
+
1947
+
1948
+ /* ============================================================================
1949
+ SCENE NODE PROPERTIES PANEL STYLES
1950
+ ============================================================================ */
1951
+
1952
+ .loading-state,
1953
+ .error-state {
1954
+ padding: var(--space-2xl) var(--space-lg);
1955
+ text-align: center;
1956
+ color: var(--text-muted);
1957
+ font-size: var(--font-body);
1958
+ }
1959
+
1960
+ .error-state {
1961
+ color: #f38ba8;
1962
+ }
1963
+
1964
+ /* Property sections — Godot inspector style */
1965
+ .property-section {
1966
+ margin-bottom: 6px;
1967
+ border-radius: var(--radius-sm);
1968
+ overflow: hidden;
1969
+ }
1970
+
1971
+ .property-section .section-header {
1972
+ cursor: pointer;
1973
+ user-select: none;
1974
+ background: var(--bg-secondary);
1975
+ padding: var(--space-sm) var(--space-md);
1976
+ font-size: var(--font-h2);
1977
+ font-weight: 600;
1978
+ color: var(--text-primary);
1979
+ display: flex;
1980
+ justify-content: space-between;
1981
+ align-items: center;
1982
+ border-bottom: none;
1983
+ text-transform: none;
1984
+ letter-spacing: 0;
1985
+ transition: background 0.1s;
1986
+ }
1987
+
1988
+ .property-section .section-header:hover {
1989
+ background: var(--bg-hover);
1990
+ }
1991
+
1992
+ .property-section .section-count {
1993
+ background: transparent;
1994
+ color: var(--text-muted);
1995
+ font-size: var(--font-small);
1996
+ font-family: var(--font-mono);
1997
+ padding: 0;
1998
+ border-radius: 0;
1999
+ font-weight: 500;
2000
+ }
2001
+
2002
+ .property-section.collapsed .property-list {
2003
+ display: none;
2004
+ }
2005
+
2006
+ .property-section.collapsed .section-header span:first-child::before {
2007
+ content: '▶ ';
2008
+ }
2009
+
2010
+ .property-section:not(.collapsed) .section-header span:first-child::before {
2011
+ content: '▼ ';
2012
+ }
2013
+
2014
+ .property-section .section-header span:first-child {
2015
+ display: flex;
2016
+ align-items: center;
2017
+ }
2018
+
2019
+ .property-section .section-header span:first-child::before {
2020
+ margin-right: 6px;
2021
+ font-size: var(--font-small);
2022
+ opacity: 0.5;
2023
+ }
2024
+
2025
+ .property-list {
2026
+ padding: 6px 0;
2027
+ background: var(--bg-primary);
2028
+ }
2029
+
2030
+ /* Property rows */
2031
+ .property-row {
2032
+ display: flex;
2033
+ align-items: center;
2034
+ gap: var(--space-sm);
2035
+ padding: 8px var(--space-md);
2036
+ margin-bottom: 1px;
2037
+ transition: background 0.1s;
2038
+ }
2039
+
2040
+ .property-row:hover {
2041
+ background: rgba(255, 255, 255, 0.02);
2042
+ }
2043
+
2044
+ .property-name {
2045
+ flex: 0 0 40%;
2046
+ font-size: var(--font-body);
2047
+ color: var(--text-secondary);
2048
+ text-overflow: ellipsis;
2049
+ overflow: hidden;
2050
+ white-space: nowrap;
2051
+ padding-right: 10px;
2052
+ }
2053
+
2054
+ .property-value {
2055
+ flex: 1;
2056
+ display: flex;
2057
+ align-items: center;
2058
+ gap: 6px;
2059
+ min-width: 0;
2060
+ }
2061
+
2062
+ /* Property inputs */
2063
+ .property-input {
2064
+ width: 100%;
2065
+ background: var(--bg-tertiary);
2066
+ border: 1px solid var(--border);
2067
+ border-radius: 6px;
2068
+ padding: 8px var(--space-sm);
2069
+ font-size: var(--font-body);
2070
+ color: var(--text-primary);
2071
+ font-family: var(--font-mono);
2072
+ transition: border-color 0.15s;
2073
+ }
2074
+
2075
+ .property-input:focus {
2076
+ outline: none;
2077
+ border-color: var(--accent);
2078
+ }
2079
+
2080
+ .property-input::-webkit-inner-spin-button,
2081
+ .property-input::-webkit-outer-spin-button {
2082
+ opacity: 1;
2083
+ }
2084
+
2085
+ /* Property select */
2086
+ .property-select {
2087
+ width: 100%;
2088
+ background: var(--bg-tertiary);
2089
+ border: 1px solid var(--border);
2090
+ border-radius: 6px;
2091
+ padding: 8px var(--space-sm);
2092
+ font-size: var(--font-body);
2093
+ color: var(--text-primary);
2094
+ cursor: pointer;
2095
+ transition: border-color 0.15s;
2096
+ }
2097
+
2098
+ .property-select:focus {
2099
+ outline: none;
2100
+ border-color: var(--accent);
2101
+ }
2102
+
2103
+ /* Toggle switch */
2104
+ .toggle-switch {
2105
+ position: relative;
2106
+ display: inline-block;
2107
+ width: 38px;
2108
+ height: 22px;
2109
+ }
2110
+
2111
+ .toggle-switch input {
2112
+ opacity: 0;
2113
+ width: 0;
2114
+ height: 0;
2115
+ }
2116
+
2117
+ .toggle-slider {
2118
+ position: absolute;
2119
+ cursor: pointer;
2120
+ top: 0;
2121
+ left: 0;
2122
+ right: 0;
2123
+ bottom: 0;
2124
+ background-color: var(--bg-tertiary);
2125
+ border-radius: 22px;
2126
+ transition: 0.15s;
2127
+ }
2128
+
2129
+ .toggle-slider::before {
2130
+ position: absolute;
2131
+ content: "";
2132
+ height: 16px;
2133
+ width: 16px;
2134
+ left: 3px;
2135
+ bottom: 3px;
2136
+ background-color: var(--text-muted);
2137
+ border-radius: var(--radius-full);
2138
+ transition: 0.15s;
2139
+ }
2140
+
2141
+ .toggle-switch input:checked + .toggle-slider {
2142
+ background-color: rgba(166, 227, 161, 0.25);
2143
+ }
2144
+
2145
+ .toggle-switch input:checked + .toggle-slider::before {
2146
+ background-color: var(--gd-signal);
2147
+ transform: translateX(16px);
2148
+ }
2149
+
2150
+ /* Range input group */
2151
+ .range-input-group {
2152
+ display: flex;
2153
+ align-items: center;
2154
+ gap: 10px;
2155
+ width: 100%;
2156
+ }
2157
+
2158
+ .property-range {
2159
+ flex: 1;
2160
+ height: 4px;
2161
+ -webkit-appearance: none;
2162
+ background: var(--bg-tertiary);
2163
+ border-radius: 2px;
2164
+ outline: none;
2165
+ }
2166
+
2167
+ .property-range::-webkit-slider-thumb {
2168
+ -webkit-appearance: none;
2169
+ width: 16px;
2170
+ height: 16px;
2171
+ background: var(--accent);
2172
+ border-radius: var(--radius-full);
2173
+ cursor: pointer;
2174
+ transition: background 0.15s;
2175
+ }
2176
+
2177
+ .property-range::-webkit-slider-thumb:hover {
2178
+ background: var(--accent-light);
2179
+ }
2180
+
2181
+ .range-number {
2182
+ width: 60px !important;
2183
+ flex: 0 0 auto;
2184
+ }
2185
+
2186
+ /* Vector input group */
2187
+ .vector-input-group {
2188
+ display: flex;
2189
+ align-items: center;
2190
+ gap: 6px;
2191
+ width: 100%;
2192
+ }
2193
+
2194
+ .vector-input-group label {
2195
+ font-size: var(--font-micro);
2196
+ color: var(--text-muted);
2197
+ font-weight: 600;
2198
+ text-transform: uppercase;
2199
+ }
2200
+
2201
+ .vector-input-group .property-input {
2202
+ width: auto;
2203
+ flex: 1;
2204
+ min-width: 50px;
2205
+ }
2206
+
2207
+ .vector-input-group.vec3 .property-input {
2208
+ min-width: 40px;
2209
+ }
2210
+
2211
+ /* Color input group */
2212
+ .color-input-group {
2213
+ display: flex;
2214
+ align-items: center;
2215
+ gap: 8px;
2216
+ width: 100%;
2217
+ }
2218
+
2219
+ .property-color {
2220
+ width: 42px;
2221
+ height: 28px;
2222
+ padding: 0;
2223
+ border: 1px solid var(--border);
2224
+ border-radius: 6px;
2225
+ cursor: pointer;
2226
+ background: transparent;
2227
+ }
2228
+
2229
+ .property-color::-webkit-color-swatch-wrapper {
2230
+ padding: 2px;
2231
+ }
2232
+
2233
+ .property-color::-webkit-color-swatch {
2234
+ border-radius: 3px;
2235
+ border: none;
2236
+ }
2237
+
2238
+ .color-alpha {
2239
+ width: 50px !important;
2240
+ flex: 0 0 auto;
2241
+ }
2242
+
2243
+ /* Readonly property */
2244
+ .property-readonly {
2245
+ font-size: var(--font-small);
2246
+ color: var(--text-muted);
2247
+ font-family: var(--font-mono);
2248
+ background: var(--bg-tertiary);
2249
+ padding: 6px 10px;
2250
+ border-radius: 6px;
2251
+ max-width: 100%;
2252
+ overflow: hidden;
2253
+ text-overflow: ellipsis;
2254
+ white-space: nowrap;
2255
+ }
2256
+
2257
+ /* Resource path */
2258
+ .resource-path {
2259
+ font-size: var(--font-small);
2260
+ color: var(--gd-string);
2261
+ font-family: var(--font-mono);
2262
+ background: var(--bg-tertiary);
2263
+ padding: 6px 10px;
2264
+ border-radius: 6px;
2265
+ }
2266
+
2267
+
2268
+ /* ============================================================================
2269
+ DIFF STYLES
2270
+ ============================================================================ */
2271
+
2272
+ .diff-container { padding: 0; }
2273
+
2274
+ .diff-loading {
2275
+ padding: var(--space-md);
2276
+ color: var(--text-muted);
2277
+ font-size: var(--font-body);
2278
+ }
2279
+
2280
+ .diff-error {
2281
+ padding: var(--space-md);
2282
+ color: #f38ba8;
2283
+ font-size: var(--font-body);
2284
+ }
2285
+
2286
+ .diff-info {
2287
+ padding: var(--space-md);
2288
+ color: var(--text-muted);
2289
+ font-size: var(--font-body);
2290
+ font-style: italic;
2291
+ }
2292
+
2293
+ .diff-group { margin-bottom: var(--space-sm); }
2294
+
2295
+ .diff-group-header {
2296
+ display: flex;
2297
+ justify-content: space-between;
2298
+ align-items: center;
2299
+ padding: 8px var(--space-sm);
2300
+ background: rgba(255,255,255,0.02);
2301
+ font-size: var(--font-small);
2302
+ font-weight: 600;
2303
+ color: var(--text-primary);
2304
+ }
2305
+
2306
+ .diff-func-name {
2307
+ font-family: var(--font-mono);
2308
+ }
2309
+
2310
+ .diff-stats {
2311
+ display: flex;
2312
+ gap: 8px;
2313
+ font-family: var(--font-mono);
2314
+ }
2315
+
2316
+ .diff-stat-add { color: #a6e3a1; }
2317
+ .diff-stat-del { color: #f38ba8; }
2318
+
2319
+ .diff-hunk {
2320
+ font-family: var(--font-mono);
2321
+ font-size: var(--font-small);
2322
+ line-height: 1.6;
2323
+ }
2324
+
2325
+ .diff-line {
2326
+ padding: 0 var(--space-sm);
2327
+ white-space: pre-wrap;
2328
+ word-break: break-all;
2329
+ }
2330
+
2331
+ .diff-add { background: rgba(166, 227, 161, 0.08); color: #a6e3a1; }
2332
+ .diff-del { background: rgba(243, 139, 168, 0.08); color: #f38ba8; }
2333
+ .diff-ctx { color: var(--text-muted); }
2334
+
2335
+ </style>
2336
+ </head>
2337
+ <body>
2338
+ <div id="search-bar">
2339
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--text-muted)" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
2340
+ <input type="text" id="search" placeholder="Search scripts..." />
2341
+ <span class="stats" id="stats"></span>
2342
+ <button id="refresh-btn" onclick="refreshProject()" title="Refresh project (re-scan files & git status)">
2343
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2344
+ <path d="M23 4v6h-6M1 20v-6h6"/>
2345
+ <path d="M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15"/>
2346
+ </svg>
2347
+ </button>
2348
+ </div>
2349
+
2350
+ <div id="legend">
2351
+ <div class="item"><div class="line" style="background:var(--edge-extends)"></div> extends</div>
2352
+ <div class="item"><div class="line" style="background:var(--edge-preload)"></div> preload</div>
2353
+ <div class="item"><div class="line" style="background:var(--edge-signal);height:0;border-top:2px dotted var(--edge-signal)"></div> signal</div>
2354
+ </div>
2355
+
2356
+ <div id="zoom-indicator" title="Click to reset, or type custom zoom">
2357
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--text-muted)" stroke-width="2" onclick="resetZoom()" style="cursor:pointer"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/><path d="M8 11h6"/><path d="M11 8v6"/></svg>
2358
+ <input type="text" class="zoom-input" id="zoom-text" value="100%" onchange="setCustomZoom(this.value)" onkeydown="if(event.key==='Enter'){this.blur()}" onclick="this.select()">
2359
+ </div>
2360
+
2361
+ <div id="detail-panel">
2362
+ <div id="panel-resize-handle"></div>
2363
+ <div class="panel-header">
2364
+ <button class="close-btn" onclick="closePanel()">&times;</button>
2365
+ <h2 id="panel-title"></h2>
2366
+ <div class="path" id="panel-path"></div>
2367
+ </div>
2368
+ <div class="panel-body" id="panel-body"></div>
2369
+ </div>
2370
+
2371
+ <!-- Category Filter Panel -->
2372
+ <div id="category-panel">
2373
+ <div class="cat-header">
2374
+ <span class="cat-title">Categories</span>
2375
+ <div class="cat-controls">
2376
+ <button class="cat-mode-btn" id="cat-mode-btn" onclick="toggleGroupMode()" title="Toggle grouped layout">
2377
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2378
+ <rect x="3" y="3" width="7" height="7" rx="1"/>
2379
+ <rect x="14" y="3" width="7" height="7" rx="1"/>
2380
+ <rect x="14" y="14" width="7" height="7" rx="1"/>
2381
+ <rect x="3" y="14" width="7" height="7" rx="1"/>
2382
+ </svg>
2383
+ </button>
2384
+ <button class="cat-all-btn" onclick="toggleAllCategories()" title="Show/Hide all">All</button>
2385
+ </div>
2386
+ </div>
2387
+ <div class="cat-list" id="cat-list"></div>
2388
+ </div>
2389
+
2390
+ <!-- Changes Panel -->
2391
+ <div id="changes-panel">
2392
+ <div class="changes-header">
2393
+ <span class="changes-title">Changes</span>
2394
+ <label class="changes-toggle">
2395
+ <input type="checkbox" id="changes-toggle-input" checked onchange="toggleChangesVisible()">
2396
+ <span class="changes-toggle-slider"></span>
2397
+ </label>
2398
+ </div>
2399
+ <div class="changes-stats" id="changes-stats">
2400
+ <div class="changes-stat-row" data-type="modified" onclick="filterByChangeType('modified')">
2401
+ <span class="changes-dot" style="background:#f9e2af"></span>
2402
+ <span class="changes-label">Modified</span>
2403
+ <span class="changes-count" id="changes-modified-count">0</span>
2404
+ </div>
2405
+ <div class="changes-stat-row" data-type="added" onclick="filterByChangeType('added')">
2406
+ <span class="changes-dot" style="background:#a6e3a1"></span>
2407
+ <span class="changes-label">Added</span>
2408
+ <span class="changes-count" id="changes-added-count">0</span>
2409
+ </div>
2410
+ <div class="changes-stat-row" data-type="untracked" onclick="filterByChangeType('untracked')">
2411
+ <span class="changes-dot" style="background:#89b4fa"></span>
2412
+ <span class="changes-label">Untracked</span>
2413
+ <span class="changes-count" id="changes-untracked-count">0</span>
2414
+ </div>
2415
+ <div class="changes-stat-row" data-type="new" onclick="filterByChangeType('new')">
2416
+ <span class="changes-dot" style="background:#cdd6f4"></span>
2417
+ <span class="changes-label">New</span>
2418
+ <span class="changes-count" id="changes-new-count">0</span>
2419
+ </div>
2420
+ </div>
2421
+ <div class="changes-total" id="changes-total">0 changed files</div>
2422
+ </div>
2423
+
2424
+ <!-- Timeline Panel -->
2425
+ <div id="timeline-panel">
2426
+ <div class="tl-header" onclick="toggleTimelinePanel()">
2427
+ <span class="tl-title">Activity</span>
2428
+ <span class="tl-count" id="tl-count">0</span>
2429
+ <svg class="tl-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2430
+ <polyline points="6 9 12 15 18 9"/>
2431
+ </svg>
2432
+ </div>
2433
+ <div class="tl-body" id="tl-body">
2434
+ <div class="tl-empty" id="tl-empty">No actions recorded yet</div>
2435
+ <div class="tl-list" id="tl-list"></div>
2436
+ </div>
2437
+ </div>
2438
+
2439
+ <!-- View Tabs -->
2440
+ <div id="view-tabs">
2441
+ <button class="active" onclick="switchView('scripts')">Scripts</button>
2442
+ <button onclick="switchView('scenes')">Scenes</button>
2443
+ </div>
2444
+
2445
+ <!-- Scene Back Button (shown when scene is expanded) -->
2446
+ <div id="scene-back-btn" style="display:none" onclick="goBackToSceneOverview()">
2447
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2448
+ <path d="M19 12H5M12 19l-7-7 7-7"/>
2449
+ </svg>
2450
+ <span>← Back to Scenes</span>
2451
+ <span class="scene-name"></span>
2452
+ </div>
2453
+
2454
+ <!-- Context Menu (Scripts) -->
2455
+ <div id="context-menu">
2456
+ <div class="menu-item" onclick="createNewScript()">
2457
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2458
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
2459
+ <polyline points="14,2 14,8 20,8"/>
2460
+ <line x1="12" y1="18" x2="12" y2="12"/>
2461
+ <line x1="9" y1="15" x2="15" y2="15"/>
2462
+ </svg>
2463
+ New Script
2464
+ </div>
2465
+ <div class="menu-divider"></div>
2466
+ <div class="menu-item" onclick="refreshProject()">
2467
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2468
+ <path d="M23 4v6h-6M1 20v-6h6"/>
2469
+ <path d="M3.51 9a9 9 0 0114.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0020.49 15"/>
2470
+ </svg>
2471
+ Refresh
2472
+ </div>
2473
+ <div class="menu-item" onclick="resetLayout()">
2474
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2475
+ <rect x="3" y="3" width="7" height="7"/>
2476
+ <rect x="14" y="3" width="7" height="7"/>
2477
+ <rect x="14" y="14" width="7" height="7"/>
2478
+ <rect x="3" y="14" width="7" height="7"/>
2479
+ </svg>
2480
+ Reset Layout
2481
+ </div>
2482
+ </div>
2483
+
2484
+ <!-- Context Menu (Scene Nodes) -->
2485
+ <div id="scene-context-menu">
2486
+ <div class="menu-item" onclick="sceneNodeAction('add_child')">
2487
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2488
+ <circle cx="12" cy="12" r="10"/>
2489
+ <line x1="12" y1="8" x2="12" y2="16"/>
2490
+ <line x1="8" y1="12" x2="16" y2="12"/>
2491
+ </svg>
2492
+ Add Child Node
2493
+ </div>
2494
+ <div class="menu-item" onclick="sceneNodeAction('rename')">
2495
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2496
+ <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
2497
+ <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
2498
+ </svg>
2499
+ Rename
2500
+ </div>
2501
+ <div class="menu-item" onclick="sceneNodeAction('duplicate')">
2502
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2503
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
2504
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
2505
+ </svg>
2506
+ Duplicate
2507
+ </div>
2508
+ <div class="menu-divider"></div>
2509
+ <div class="menu-item" onclick="sceneNodeAction('move_up')">
2510
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2511
+ <polyline points="18 15 12 9 6 15"/>
2512
+ </svg>
2513
+ Move Up
2514
+ </div>
2515
+ <div class="menu-item" onclick="sceneNodeAction('move_down')">
2516
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2517
+ <polyline points="6 9 12 15 18 9"/>
2518
+ </svg>
2519
+ Move Down
2520
+ </div>
2521
+ <div class="menu-divider"></div>
2522
+ <div class="menu-item danger" onclick="sceneNodeAction('delete')">
2523
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2524
+ <polyline points="3 6 5 6 21 6"/>
2525
+ <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
2526
+ </svg>
2527
+ Delete
2528
+ </div>
2529
+ </div>
2530
+
2531
+ <!-- Floating Usage Panel -->
2532
+ <div id="usage-float-panel">
2533
+ <div class="ufp-header" id="ufp-header">
2534
+ <div class="ufp-info">
2535
+ <div class="ufp-title" id="ufp-title">⚠ Delete Variable</div>
2536
+ <div class="ufp-count" id="ufp-count"></div>
2537
+ </div>
2538
+ <div class="ufp-buttons">
2539
+ <button class="refresh-btn" onclick="refreshUsages()" title="Re-scan for usages">↻</button>
2540
+ <button class="close-btn" onclick="closeUsagePanel()" title="Cancel">×</button>
2541
+ </div>
2542
+ </div>
2543
+ <div class="ufp-list" id="ufp-list"></div>
2544
+ <div class="ufp-actions">
2545
+ <button class="cancel" onclick="closeUsagePanel()">Cancel</button>
2546
+ <button class="delete" id="ufp-delete-btn">Delete Anyway</button>
2547
+ </div>
2548
+ <div class="ufp-resize" id="ufp-resize"></div>
2549
+ </div>
2550
+
2551
+ <!-- New Script Modal -->
2552
+ <div id="new-script-modal" class="modal" style="display:none">
2553
+ <div class="modal-content">
2554
+ <div class="modal-header">
2555
+ <h3>Create New Script</h3>
2556
+ <button class="close-btn" onclick="closeNewScriptModal()">&times;</button>
2557
+ </div>
2558
+ <div class="modal-body">
2559
+ <div class="form-group">
2560
+ <label>Script Path</label>
2561
+ <input type="text" id="new-script-path" placeholder="res://scripts/my_script.gd">
2562
+ </div>
2563
+ <div class="form-group">
2564
+ <label>Extends</label>
2565
+ <select id="new-script-extends">
2566
+ <option value="Node">Node</option>
2567
+ <option value="Node2D">Node2D</option>
2568
+ <option value="Node3D">Node3D</option>
2569
+ <option value="CharacterBody2D">CharacterBody2D</option>
2570
+ <option value="CharacterBody3D">CharacterBody3D</option>
2571
+ <option value="RigidBody2D">RigidBody2D</option>
2572
+ <option value="Area2D">Area2D</option>
2573
+ <option value="Control">Control</option>
2574
+ <option value="Resource">Resource</option>
2575
+ <option value="RefCounted">RefCounted</option>
2576
+ </select>
2577
+ </div>
2578
+ <div class="form-group">
2579
+ <label>Class Name (optional)</label>
2580
+ <input type="text" id="new-script-classname" placeholder="MyClass">
2581
+ </div>
2582
+ </div>
2583
+ <div class="modal-footer">
2584
+ <button class="cancel" onclick="closeNewScriptModal()">Cancel</button>
2585
+ <button class="confirm" onclick="submitNewScript()">Create</button>
2586
+ </div>
2587
+ </div>
2588
+ </div>
2589
+
2590
+ <canvas id="canvas"></canvas>
2591
+
2592
+ <script>
2593
2593
  "use strict";
2594
2594
  (() => {
2595
2595
  // src/visualizer/state.js
@@ -6389,7 +6389,7 @@ canvas.dragging { cursor: grabbing; }
6389
6389
  init();
6390
6390
  }
6391
6391
  })();
6392
-
6393
- </script>
6394
- </body>
6395
- </html>
6392
+
6393
+ </script>
6394
+ </body>
6395
+ </html>