prism-debugger 0.2.0

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.
@@ -0,0 +1,1224 @@
1
+ /* ──────────────────────────────────────────
2
+ Prism Debugger — Design System
3
+ ────────────────────────────────────────── */
4
+
5
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
6
+
7
+ /* ── Tokens: Light ── */
8
+ :root {
9
+ --bg: #f4f4f5;
10
+ --bg2: #e8edf4;
11
+ --card: #ffffff;
12
+ --ink: #18181b;
13
+ --muted: #71717a;
14
+ --accent: #0ea5e9;
15
+ --accent-dim: #e0f2fe;
16
+ --accent-dark: #0369a1;
17
+ --online: #16a34a;
18
+ --offline: #be123c;
19
+ --border: #e4e4e7;
20
+ --shadow: 0 1px 3px rgba(0,0,0,0.04), 0 4px 12px rgba(0,0,0,0.03);
21
+ --shadow-lg: 0 8px 32px rgba(0,0,0,0.08);
22
+ --radius: 12px;
23
+ --radius-sm: 8px;
24
+ --sidebar-w: 260px;
25
+ --console-bg: #0d1117;
26
+ --console-fg: #e6edf3;
27
+ --transition: background 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
28
+ }
29
+
30
+ /* ── Tokens: Dark ── */
31
+ [data-theme="dark"] {
32
+ --bg: #09090b;
33
+ --bg2: #18181b;
34
+ --card: #18181b;
35
+ --ink: #fafafa;
36
+ --muted: #a1a1aa;
37
+ --accent: #38bdf8;
38
+ --accent-dim: #0c2d3e;
39
+ --accent-dark: #7dd3fc;
40
+ --online: #3fb950;
41
+ --offline: #f85149;
42
+ --border: #27272a;
43
+ --shadow: 0 1px 3px rgba(0,0,0,0.3), 0 4px 12px rgba(0,0,0,0.2);
44
+ --shadow-lg: 0 8px 32px rgba(0,0,0,0.5);
45
+ --console-bg: #09090b;
46
+ --console-fg: #e6edf3;
47
+ }
48
+
49
+ * { box-sizing: border-box; }
50
+
51
+ body {
52
+ margin: 0;
53
+ font-family: 'Inter', -apple-system, 'Segoe UI', system-ui, sans-serif;
54
+ background: var(--bg);
55
+ color: var(--ink);
56
+ display: flex;
57
+ flex-direction: row;
58
+ height: 100vh;
59
+ overflow: hidden;
60
+ transition: var(--transition);
61
+ font-size: 14px;
62
+ line-height: 1.5;
63
+ }
64
+
65
+ /* ══════════════════════════════════════════
66
+ Sidebar
67
+ ══════════════════════════════════════════ */
68
+
69
+ .sidebar {
70
+ width: var(--sidebar-w);
71
+ flex-shrink: 0;
72
+ background: var(--card);
73
+ border-right: 1px solid var(--border);
74
+ display: flex;
75
+ flex-direction: column;
76
+ height: 100%;
77
+ overflow: hidden;
78
+ transition: var(--transition);
79
+ }
80
+
81
+ /* ── Brand ── */
82
+ .sidebar-brand {
83
+ display: flex;
84
+ align-items: center;
85
+ gap: 10px;
86
+ padding: 20px 20px 16px;
87
+ flex-shrink: 0;
88
+ }
89
+
90
+ .nav-logo-mark {
91
+ width: 32px;
92
+ height: 32px;
93
+ border-radius: 10px;
94
+ background: linear-gradient(135deg, #0ea5e9 0%, #8b5cf6 100%);
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ flex-shrink: 0;
99
+ }
100
+
101
+ .nav-logo-mark svg {
102
+ width: 24px;
103
+ height: 24px;
104
+ fill: none;
105
+ stroke-linecap: round;
106
+ }
107
+
108
+ .nav-logo-text {
109
+ font-size: 18px;
110
+ font-weight: 700;
111
+ letter-spacing: -0.3px;
112
+ background: linear-gradient(120deg, #0ea5e9, #8b5cf6);
113
+ -webkit-background-clip: text;
114
+ -webkit-text-fill-color: transparent;
115
+ background-clip: text;
116
+ }
117
+
118
+ .nav-logo-sub {
119
+ font-size: 10px;
120
+ font-weight: 500;
121
+ color: var(--muted);
122
+ letter-spacing: 0.06em;
123
+ text-transform: uppercase;
124
+ margin-top: -2px;
125
+ display: block;
126
+ -webkit-text-fill-color: var(--muted);
127
+ }
128
+
129
+ /* ── Navigation ── */
130
+ .sidebar-nav {
131
+ display: flex;
132
+ flex-direction: column;
133
+ gap: 2px;
134
+ padding: 0 12px;
135
+ flex-shrink: 0;
136
+ }
137
+
138
+ .main-tab-btn {
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 10px;
142
+ width: 100%;
143
+ padding: 9px 12px;
144
+ border-radius: var(--radius-sm);
145
+ background: transparent;
146
+ border: none;
147
+ color: var(--muted);
148
+ font-size: 14px;
149
+ font-weight: 500;
150
+ font-family: inherit;
151
+ cursor: pointer;
152
+ text-align: left;
153
+ transition: background 0.15s, color 0.15s;
154
+ line-height: 1.2;
155
+ }
156
+
157
+ .main-tab-btn svg {
158
+ width: 20px;
159
+ height: 20px;
160
+ flex-shrink: 0;
161
+ }
162
+
163
+ .main-tab-btn:hover {
164
+ background: var(--bg);
165
+ color: var(--ink);
166
+ }
167
+
168
+ .main-tab-btn.active {
169
+ background: var(--bg);
170
+ color: var(--ink);
171
+ font-weight: 600;
172
+ }
173
+
174
+ /* ── Sidebar sections ── */
175
+ .sidebar-divider {
176
+ height: 1px;
177
+ background: var(--border);
178
+ margin: 12px 0;
179
+ flex-shrink: 0;
180
+ border: none;
181
+ }
182
+
183
+ .sidebar > .sidebar-divider {
184
+ margin: 12px 16px;
185
+ }
186
+
187
+ .sidebar-debuggers {
188
+ flex: 1;
189
+ display: flex;
190
+ flex-direction: column;
191
+ padding: 0 12px;
192
+ overflow: hidden;
193
+ min-height: 0;
194
+ }
195
+
196
+ .sidebar-section-title-row {
197
+ display: flex;
198
+ align-items: center;
199
+ justify-content: space-between;
200
+ margin-bottom: 8px;
201
+ }
202
+
203
+ .sidebar-section-title {
204
+ font-size: 11px;
205
+ font-weight: 700;
206
+ text-transform: uppercase;
207
+ letter-spacing: 0.06em;
208
+ color: var(--muted);
209
+ padding: 0 4px;
210
+ margin-bottom: 0;
211
+ }
212
+
213
+ .clear-inactive-btn {
214
+ font-size: 11px;
215
+ font-weight: 500;
216
+ font-family: inherit;
217
+ color: var(--muted);
218
+ background: none;
219
+ border: 1px solid var(--border);
220
+ border-radius: 4px;
221
+ padding: 2px 8px;
222
+ cursor: pointer;
223
+ transition: var(--transition);
224
+ white-space: nowrap;
225
+ }
226
+
227
+ .clear-inactive-btn:hover {
228
+ color: var(--offline);
229
+ border-color: var(--offline);
230
+ }
231
+
232
+ .sidebar-debuggers input {
233
+ margin-bottom: 8px;
234
+ }
235
+
236
+ .sidebar-footer {
237
+ padding: 12px 16px;
238
+ border-top: 1px solid var(--border);
239
+ flex-shrink: 0;
240
+ }
241
+
242
+ .theme-toggle {
243
+ width: 36px;
244
+ height: 36px;
245
+ border-radius: var(--radius-sm);
246
+ background: var(--bg);
247
+ border: 1px solid var(--border);
248
+ cursor: pointer;
249
+ font-size: 16px;
250
+ display: flex;
251
+ align-items: center;
252
+ justify-content: center;
253
+ color: var(--ink);
254
+ transition: var(--transition);
255
+ padding: 0;
256
+ font-family: inherit;
257
+ }
258
+
259
+ .theme-toggle:hover {
260
+ background: var(--bg);
261
+ border-color: var(--muted);
262
+ }
263
+
264
+ /* ── Connect button ── */
265
+ .connect-btn {
266
+ display: flex;
267
+ align-items: center;
268
+ justify-content: center;
269
+ gap: 8px;
270
+ width: calc(100% - 40px);
271
+ margin: 4px 20px 0;
272
+ padding: 8px 12px;
273
+ border-radius: var(--radius-sm);
274
+ background: linear-gradient(135deg, #0ea5e9 0%, #8b5cf6 100%);
275
+ border: none;
276
+ color: #fff;
277
+ font-size: 13px;
278
+ font-weight: 600;
279
+ font-family: inherit;
280
+ cursor: pointer;
281
+ transition: opacity 0.15s, transform 0.1s;
282
+ }
283
+
284
+ .connect-btn svg {
285
+ width: 15px;
286
+ height: 15px;
287
+ flex-shrink: 0;
288
+ stroke: #fff;
289
+ }
290
+
291
+ .connect-btn:hover {
292
+ opacity: 0.88;
293
+ background: linear-gradient(135deg, #0ea5e9 0%, #8b5cf6 100%);
294
+ border: none;
295
+ color: #fff;
296
+ }
297
+
298
+ .connect-btn:active {
299
+ transform: scale(0.97);
300
+ }
301
+
302
+ /* ── Connect modal ── */
303
+ .modal-overlay {
304
+ position: fixed;
305
+ inset: 0;
306
+ background: rgba(0, 0, 0, 0.5);
307
+ z-index: 500;
308
+ display: flex;
309
+ align-items: center;
310
+ justify-content: center;
311
+ }
312
+
313
+ .modal-overlay.hidden { display: none; }
314
+
315
+ .modal-panel {
316
+ background: var(--card);
317
+ border: 1px solid var(--border);
318
+ border-radius: var(--radius);
319
+ width: 360px;
320
+ max-width: 90vw;
321
+ box-shadow: var(--shadow-lg);
322
+ overflow: hidden;
323
+ }
324
+
325
+ .modal-header {
326
+ display: flex;
327
+ align-items: center;
328
+ justify-content: space-between;
329
+ padding: 14px 16px;
330
+ border-bottom: 1px solid var(--border);
331
+ }
332
+
333
+ .modal-title {
334
+ font-size: 14px;
335
+ font-weight: 700;
336
+ }
337
+
338
+ .modal-body {
339
+ padding: 20px 16px;
340
+ display: flex;
341
+ flex-direction: column;
342
+ align-items: center;
343
+ gap: 16px;
344
+ }
345
+
346
+ .connect-qr {
347
+ display: flex;
348
+ align-items: center;
349
+ justify-content: center;
350
+ }
351
+
352
+ .connect-qr img {
353
+ display: block;
354
+ border-radius: 4px;
355
+ }
356
+
357
+ .connect-url-row {
358
+ display: flex;
359
+ gap: 6px;
360
+ width: 100%;
361
+ }
362
+
363
+ .connect-url-input {
364
+ flex: 1;
365
+ min-width: 0;
366
+ font-size: 12px;
367
+ font-family: 'JetBrains Mono', Menlo, monospace;
368
+ padding: 8px 10px;
369
+ background: var(--bg);
370
+ border: 1.5px solid var(--border);
371
+ border-radius: 6px;
372
+ color: var(--ink);
373
+ cursor: text;
374
+ }
375
+
376
+ /* ── Debugger list ── */
377
+ #debuggerList {
378
+ list-style: none;
379
+ margin: 0;
380
+ padding: 0;
381
+ overflow-y: auto;
382
+ flex: 1;
383
+ }
384
+
385
+ #debuggerList li {
386
+ border: 1.5px solid transparent;
387
+ border-radius: var(--radius-sm);
388
+ padding: 7px 10px;
389
+ margin-bottom: 2px;
390
+ cursor: pointer;
391
+ font-size: 13px;
392
+ transition: background 0.15s, border-color 0.15s;
393
+ }
394
+
395
+ #debuggerList li:hover {
396
+ background: var(--bg);
397
+ }
398
+
399
+ #debuggerList li.active {
400
+ background: var(--bg);
401
+ border-color: var(--border);
402
+ }
403
+
404
+ .dbg-row { display: flex; align-items: center; gap: 8px; }
405
+
406
+ .status-dot {
407
+ width: 7px;
408
+ height: 7px;
409
+ border-radius: 50%;
410
+ flex-shrink: 0;
411
+ }
412
+
413
+ .status-dot.online { background: var(--online); }
414
+ .status-dot.offline { background: var(--offline); }
415
+
416
+ .muted { color: var(--muted); font-size: 12px; }
417
+
418
+ /* ══════════════════════════════════════════
419
+ Main Content
420
+ ══════════════════════════════════════════ */
421
+
422
+ .main-content {
423
+ flex: 1;
424
+ display: flex;
425
+ flex-direction: column;
426
+ overflow: hidden;
427
+ min-width: 0;
428
+ }
429
+
430
+ .main-view { flex: 1; overflow: hidden; }
431
+ .main-view.hidden { display: none; }
432
+
433
+ /* ── Common panel ── */
434
+ .panel {
435
+ background: var(--card);
436
+ border: 1px solid var(--border);
437
+ border-radius: 0;
438
+ padding: 16px;
439
+ display: flex;
440
+ flex-direction: column;
441
+ overflow: hidden;
442
+ transition: var(--transition);
443
+ }
444
+
445
+ .panel header {
446
+ display: flex;
447
+ flex-direction: column;
448
+ gap: 10px;
449
+ flex-shrink: 0;
450
+ }
451
+
452
+ .panel h1, .panel h2 {
453
+ margin: 0 0 2px;
454
+ font-size: 13px;
455
+ font-weight: 700;
456
+ text-transform: uppercase;
457
+ letter-spacing: 0.06em;
458
+ color: var(--muted);
459
+ }
460
+
461
+ /* ── Form elements ── */
462
+ input, textarea, select {
463
+ border: 1.5px solid var(--border);
464
+ border-radius: var(--radius-sm);
465
+ padding: 8px 12px;
466
+ font: inherit;
467
+ font-size: 13px;
468
+ background: var(--bg);
469
+ color: var(--ink);
470
+ outline: none;
471
+ transition: border-color 0.15s, box-shadow 0.15s;
472
+ }
473
+
474
+ select {
475
+ appearance: none;
476
+ -webkit-appearance: none;
477
+ padding-right: 32px;
478
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%2371717a' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
479
+ background-repeat: no-repeat;
480
+ background-position: right 10px center;
481
+ background-size: 12px 8px;
482
+ }
483
+
484
+ [data-theme="dark"] select {
485
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23a1a1aa' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
486
+ }
487
+
488
+ input:focus, textarea:focus, select:focus {
489
+ border-color: var(--muted);
490
+ }
491
+
492
+ button {
493
+ background: var(--bg);
494
+ color: var(--ink);
495
+ border: 1.5px solid var(--border);
496
+ border-radius: var(--radius-sm);
497
+ padding: 9px 16px;
498
+ font: 600 13px/1 inherit;
499
+ cursor: pointer;
500
+ transition: background 0.15s, border-color 0.15s;
501
+ }
502
+
503
+ button:hover { background: var(--card); border-color: var(--muted); }
504
+ button:active { transform: scale(0.98); }
505
+
506
+ /* ══════════════════════════════════════════
507
+ Console View
508
+ ══════════════════════════════════════════ */
509
+
510
+ .console-layout {
511
+ display: grid;
512
+ grid-template-columns: 1fr 280px;
513
+ gap: 12px;
514
+ padding: 12px;
515
+ height: 100%;
516
+ overflow: hidden;
517
+ }
518
+
519
+ .panel-console { display: flex; flex-direction: column; }
520
+ .panel-console header { flex-shrink: 0; }
521
+
522
+ .filters {
523
+ display: flex;
524
+ gap: 8px;
525
+ flex-shrink: 0;
526
+ flex-wrap: wrap;
527
+ }
528
+
529
+ .filters > * {
530
+ flex: 1;
531
+ min-width: 100px;
532
+ }
533
+
534
+ .panel-send { overflow-y: auto; }
535
+ .panel-send > *:not(header) { margin-top: 10px; }
536
+ .panel-send label {
537
+ display: block;
538
+ margin-bottom: 5px;
539
+ font-weight: 600;
540
+ font-size: 12px;
541
+ color: var(--muted);
542
+ text-transform: uppercase;
543
+ letter-spacing: 0.05em;
544
+ }
545
+
546
+ textarea {
547
+ min-height: 200px;
548
+ resize: vertical;
549
+ font-family: 'JetBrains Mono', 'Fira Code', Menlo, Monaco, monospace;
550
+ }
551
+
552
+ /* ── Console output ── */
553
+ #console {
554
+ margin-top: 10px;
555
+ overflow-y: auto;
556
+ flex: 1;
557
+ border: 1.5px solid var(--border);
558
+ border-radius: 4px;
559
+ background: var(--console-bg);
560
+ color: var(--console-fg);
561
+ padding: 8px;
562
+ font-family: 'JetBrains Mono', 'Fira Code', Menlo, Monaco, monospace;
563
+ font-size: 12px;
564
+ line-height: 1.6;
565
+ }
566
+
567
+ .console-row {
568
+ padding: 6px 8px;
569
+ border-bottom: 1px solid rgba(255,255,255,0.06);
570
+ display: flex;
571
+ flex-direction: column;
572
+ gap: 4px;
573
+ }
574
+
575
+ .console-row:last-child { border-bottom: none; }
576
+
577
+ .console-row-header {
578
+ display: flex;
579
+ align-items: center;
580
+ gap: 8px;
581
+ flex-wrap: wrap;
582
+ }
583
+
584
+ .console-timestamp { color: #4d6066; font-size: 11px; }
585
+
586
+ .console-level {
587
+ padding: 2px 6px;
588
+ border-radius: 4px;
589
+ font-size: 10px;
590
+ font-weight: 700;
591
+ text-transform: uppercase;
592
+ letter-spacing: 0.03em;
593
+ }
594
+
595
+ .console-level.debug { background: #1e3a4a; color: #7ec8e3; }
596
+ .console-level.info { background: #1a3a5c; color: #7ecbf3; }
597
+ .console-level.warn { background: #3d2a00; color: #fbbf24; }
598
+ .console-level.error { background: #3d0c0c; color: #f87171; }
599
+ .console-level.perfwarning{ background: #3d2200; color: #fb923c; }
600
+
601
+ .console-event-name { color: #4ade80; font-weight: 600; }
602
+
603
+ .console-payload {
604
+ margin-left: 8px;
605
+ margin-top: 2px;
606
+ font-family: 'JetBrains Mono', Menlo, Monaco, monospace;
607
+ font-size: 12px;
608
+ }
609
+
610
+ /* ── JSON tree ── */
611
+ .json-node { line-height: 1.5; }
612
+ .json-line { display: flex; align-items: baseline; gap: 4px; padding: 1px 0; }
613
+ .json-line:hover { background: rgba(255,255,255,0.04); }
614
+ .json-arrow { cursor: pointer; user-select: none; color: #4ade80; font-size: 10px; width: 12px; display: inline-block; text-align: center; flex-shrink: 0; }
615
+ .json-arrow:hover { color: #86efac; }
616
+ .json-children.collapsed { display: none; }
617
+ .json-preview { color: #6b7280; font-style: italic; }
618
+ .json-key { color: #93c5fd; }
619
+ .json-string { color: #f9a8d4; }
620
+ .json-number { color: #fcd34d; }
621
+ .json-boolean { color: #a5b4fc; }
622
+ .json-null { color: #6b7280; }
623
+
624
+ /* ── Scrollbars ── */
625
+ #console::-webkit-scrollbar { width: 6px; }
626
+ #console::-webkit-scrollbar-track { background: transparent; }
627
+ #console::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 3px; }
628
+ #console::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.25); }
629
+
630
+ #debuggerList::-webkit-scrollbar { width: 5px; }
631
+ #debuggerList::-webkit-scrollbar-track { background: transparent; }
632
+ #debuggerList::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
633
+ #debuggerList::-webkit-scrollbar-thumb:hover { background: var(--muted); }
634
+
635
+ /* ══════════════════════════════════════════
636
+ Timeline
637
+ ══════════════════════════════════════════ */
638
+
639
+ .tl-view {
640
+ display: flex;
641
+ flex-direction: column;
642
+ height: 100%;
643
+ }
644
+
645
+ /* ── Label multi-filter ── */
646
+ .tl-label-anchor {
647
+ position: relative;
648
+ }
649
+
650
+ .tl-label-filter-wrap {
651
+ border: 1.5px solid var(--border);
652
+ border-radius: var(--radius-sm);
653
+ background: var(--bg);
654
+ padding: 5px 7px;
655
+ display: flex;
656
+ flex-wrap: wrap;
657
+ gap: 4px;
658
+ cursor: text;
659
+ transition: border-color 0.15s, box-shadow 0.15s;
660
+ align-items: center;
661
+ }
662
+
663
+ .tl-label-filter-wrap:focus-within {
664
+ border-color: var(--muted);
665
+ }
666
+
667
+ .tl-label-tags { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
668
+ .tl-label-tags:empty { display: none; }
669
+
670
+ .tl-label-tag {
671
+ display: inline-flex;
672
+ align-items: center;
673
+ gap: 4px;
674
+ background: var(--bg);
675
+ color: var(--ink);
676
+ border: 1px solid var(--border);
677
+ border-radius: 5px;
678
+ padding: 2px 8px;
679
+ font-size: 11px;
680
+ font-weight: 600;
681
+ max-width: 200px;
682
+ white-space: nowrap;
683
+ overflow: hidden;
684
+ flex-shrink: 0;
685
+ height: 20px;
686
+ }
687
+
688
+ .tl-label-tag-content {
689
+ display: flex;
690
+ align-items: center;
691
+ gap: 4px;
692
+ overflow: hidden;
693
+ min-width: 0;
694
+ }
695
+
696
+ .tl-label-tag-remove { cursor: pointer; font-size: 11px; opacity: 0.7; flex-shrink: 0; }
697
+ .tl-label-tag-remove:hover { opacity: 1; }
698
+
699
+ .tl-label-input {
700
+ border: none;
701
+ outline: none;
702
+ font: inherit;
703
+ font-size: 13px;
704
+ padding: 2px 0;
705
+ background: transparent;
706
+ flex: 1;
707
+ min-width: 80px;
708
+ color: var(--ink);
709
+ box-shadow: none !important;
710
+ }
711
+
712
+ .tl-label-suggestions {
713
+ position: absolute;
714
+ top: calc(100% + 4px);
715
+ left: 0;
716
+ right: 0;
717
+ border: 1.5px solid var(--border);
718
+ border-radius: 4px;
719
+ background: var(--card);
720
+ box-shadow: var(--shadow-lg);
721
+ z-index: 50;
722
+ max-height: 200px;
723
+ overflow-y: auto;
724
+ }
725
+
726
+ .tl-label-suggestions.hidden { display: none; }
727
+
728
+ .tl-label-suggestion-item {
729
+ display: flex;
730
+ align-items: center;
731
+ gap: 6px;
732
+ padding: 9px 12px;
733
+ cursor: pointer;
734
+ font-size: 14px;
735
+ white-space: nowrap;
736
+ overflow: hidden;
737
+ text-overflow: ellipsis;
738
+ transition: background 0.1s;
739
+ }
740
+
741
+ .tl-label-suggestion-item:hover,
742
+ .tl-label-suggestion-item.active { background: var(--bg); }
743
+
744
+ .tl-stats {
745
+ font-size: 12px;
746
+ color: var(--muted);
747
+ white-space: nowrap;
748
+ flex-shrink: 0;
749
+ }
750
+
751
+ .tl-legend { display: flex; flex-direction: column; gap: 6px; padding: 4px 0; }
752
+ .tl-legend-item { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--muted); white-space: nowrap; }
753
+ .tl-legend-dot { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
754
+ .tl-legend-dot.fast { background: #22c55e; }
755
+ .tl-legend-dot.medium { background: #f59e0b; }
756
+ .tl-legend-dot.slow { background: #ef4444; }
757
+
758
+ /* ── Toolbar ── */
759
+ .tl-toolbar {
760
+ display: flex;
761
+ align-items: center;
762
+ gap: 8px;
763
+ padding: 6px 12px;
764
+ border-bottom: 1px solid var(--border);
765
+ background: var(--card);
766
+ flex-shrink: 0;
767
+ }
768
+
769
+ .tl-toolbar-filters { align-items: flex-start; padding: 10px 12px; }
770
+
771
+ .tl-toolbar-controls { padding: 4px 12px; }
772
+
773
+ .tl-toolbar-spacer { flex: 1; }
774
+
775
+ .tl-toolbar-select { width: auto; min-width: 120px; font-size: 13px; padding: 6px 28px 6px 10px; flex-shrink: 0; }
776
+
777
+ .tl-toolbar-labels { flex: 0 1 50%; min-width: 120px; max-width: 50%; }
778
+ .tl-toolbar-labels .tl-label-filter-wrap {
779
+ padding: 3px 6px;
780
+ height: 52px;
781
+ overflow-y: auto;
782
+ align-content: flex-start;
783
+ }
784
+ .tl-toolbar-labels .tl-label-input { font-size: 13px; }
785
+
786
+ .tl-toolbar-labels .tl-label-filter-wrap::-webkit-scrollbar { width: 4px; }
787
+ .tl-toolbar-labels .tl-label-filter-wrap::-webkit-scrollbar-track { background: transparent; }
788
+ .tl-toolbar-labels .tl-label-filter-wrap::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
789
+
790
+ .tl-toolbar-actions {
791
+ display: flex;
792
+ align-items: center;
793
+ gap: 4px;
794
+ flex-shrink: 0;
795
+ }
796
+
797
+ .tl-toolbar-sep {
798
+ width: 1px;
799
+ height: 20px;
800
+ background: var(--border);
801
+ margin: 0 2px;
802
+ flex-shrink: 0;
803
+ }
804
+
805
+ .tl-tool-btn {
806
+ background: var(--bg);
807
+ color: var(--ink);
808
+ border: 1px solid var(--border);
809
+ border-radius: 6px;
810
+ padding: 5px 10px;
811
+ font-size: 12px;
812
+ font-family: inherit;
813
+ font-weight: 500;
814
+ cursor: pointer;
815
+ line-height: 1;
816
+ display: flex;
817
+ align-items: center;
818
+ gap: 4px;
819
+ transition: background 0.15s, border-color 0.15s;
820
+ white-space: nowrap;
821
+ }
822
+
823
+ .tl-tool-btn:hover { background: var(--card); border-color: var(--muted); }
824
+ .tl-tool-btn svg { flex-shrink: 0; }
825
+
826
+ .tl-report-btn {
827
+ display: flex;
828
+ align-items: center;
829
+ gap: 6px;
830
+ padding: 7px 14px;
831
+ font-size: 13px;
832
+ font-weight: 600;
833
+ font-family: inherit;
834
+ border-radius: 6px;
835
+ background: var(--ink);
836
+ color: var(--bg);
837
+ border: none;
838
+ cursor: pointer;
839
+ line-height: 1;
840
+ white-space: nowrap;
841
+ transition: opacity 0.15s;
842
+ }
843
+
844
+ .tl-report-btn svg { flex-shrink: 0; stroke: var(--bg); }
845
+ .tl-report-btn:hover { opacity: 0.8; background: var(--ink); color: var(--bg); border: none; }
846
+ .tl-report-btn:active { transform: scale(0.97); }
847
+
848
+ .tl-scale-input {
849
+ width: 80px;
850
+ padding: 0;
851
+ border: none;
852
+ background: transparent;
853
+ box-shadow: none;
854
+ flex-shrink: 0;
855
+ }
856
+
857
+ .tl-scale-label { font-size: 11px; flex-shrink: 0; }
858
+
859
+ /* ── Dropdown menus ── */
860
+ .tl-dropdown-wrap { position: relative; }
861
+
862
+ .tl-dropdown-menu {
863
+ position: absolute;
864
+ top: calc(100% + 4px);
865
+ left: 0;
866
+ background: var(--card);
867
+ border: 1px solid var(--border);
868
+ border-radius: 6px;
869
+ padding: 12px;
870
+ min-width: 180px;
871
+ z-index: 100;
872
+ box-shadow: var(--shadow-lg);
873
+ display: flex;
874
+ flex-direction: column;
875
+ gap: 10px;
876
+ }
877
+
878
+ .tl-dropdown-menu.tl-dropdown-right { left: auto; right: 0; }
879
+ .tl-dropdown-menu.hidden { display: none; }
880
+
881
+ .tl-dropdown-field { display: flex; flex-direction: column; gap: 4px; }
882
+ .tl-dropdown-field label {
883
+ font-size: 11px;
884
+ font-weight: 700;
885
+ color: var(--muted);
886
+ text-transform: uppercase;
887
+ letter-spacing: 0.06em;
888
+ }
889
+ .tl-dropdown-field select { width: 100%; font-size: 13px; }
890
+
891
+ .tl-dropdown-action {
892
+ width: 100%;
893
+ padding: 8px;
894
+ font-size: 13px;
895
+ font-weight: 600;
896
+ }
897
+
898
+ .tl-empty {
899
+ flex: 1;
900
+ display: flex;
901
+ align-items: center;
902
+ justify-content: center;
903
+ color: var(--muted);
904
+ font-size: 14px;
905
+ background: var(--card);
906
+ }
907
+
908
+ .tl-scroll {
909
+ flex: 1;
910
+ overflow: auto;
911
+ display: none;
912
+ background: var(--card);
913
+ }
914
+ .tl-scroll.visible { display: block; }
915
+
916
+ /* ── Chart structure ── */
917
+ .tl-inner { position: relative; min-height: 100%; }
918
+
919
+ .tl-time-axis-row {
920
+ display: flex;
921
+ height: 38px;
922
+ position: sticky;
923
+ top: 0;
924
+ z-index: 10;
925
+ background: var(--card);
926
+ border-bottom: 1px solid var(--border);
927
+ }
928
+
929
+ .tl-axis-corner {
930
+ width: var(--label-w, 240px);
931
+ flex-shrink: 0;
932
+ border-right: 1px solid var(--border);
933
+ }
934
+
935
+ .tl-time-axis { position: relative; flex-shrink: 0; overflow: visible; }
936
+
937
+ .tl-tick {
938
+ position: absolute;
939
+ top: 50%;
940
+ transform: translate(-50%, -50%);
941
+ font-size: 11px;
942
+ color: var(--muted);
943
+ white-space: nowrap;
944
+ font-family: 'JetBrains Mono', Menlo, monospace;
945
+ pointer-events: none;
946
+ }
947
+
948
+ .tl-tick::before {
949
+ content: '';
950
+ position: absolute;
951
+ bottom: -6px;
952
+ left: 50%;
953
+ width: 1px;
954
+ height: 4px;
955
+ background: var(--border);
956
+ transform: translateX(-50%);
957
+ }
958
+
959
+ /* ── Context group header ── */
960
+ .tl-group-header {
961
+ display: flex;
962
+ align-items: center;
963
+ height: 30px;
964
+ background: var(--bg);
965
+ border-bottom: 1px solid var(--border);
966
+ position: sticky;
967
+ top: 38px;
968
+ z-index: 5;
969
+ }
970
+
971
+ .tl-group-label {
972
+ width: var(--label-w, 240px);
973
+ flex-shrink: 0;
974
+ padding: 0 10px;
975
+ font-size: 11px;
976
+ font-weight: 700;
977
+ color: var(--accent);
978
+ text-transform: uppercase;
979
+ letter-spacing: 0.07em;
980
+ cursor: pointer;
981
+ white-space: nowrap;
982
+ overflow: hidden;
983
+ text-overflow: ellipsis;
984
+ position: sticky;
985
+ left: 0;
986
+ background: var(--bg);
987
+ z-index: 6;
988
+ border-right: 1px solid var(--border);
989
+ }
990
+
991
+ .tl-group-stripe {
992
+ flex-shrink: 0;
993
+ height: 100%;
994
+ border-top: 1px dashed var(--border);
995
+ opacity: 0.5;
996
+ }
997
+
998
+ /* ── Data rows ── */
999
+ .tl-row {
1000
+ display: flex;
1001
+ height: 46px;
1002
+ border-bottom: 1px solid rgba(0,0,0,0.04);
1003
+ }
1004
+
1005
+ [data-theme="dark"] .tl-row {
1006
+ border-bottom-color: rgba(255,255,255,0.04);
1007
+ }
1008
+
1009
+ .tl-row:hover { background: rgba(14,165,233,0.03); }
1010
+
1011
+ .tl-row-label {
1012
+ width: var(--label-w, 240px);
1013
+ min-width: var(--label-w, 240px);
1014
+ font-size: 13px;
1015
+ color: var(--muted);
1016
+ padding: 0 10px;
1017
+ display: flex;
1018
+ align-items: center;
1019
+ gap: 5px;
1020
+ cursor: pointer;
1021
+ white-space: nowrap;
1022
+ overflow: hidden;
1023
+ text-overflow: ellipsis;
1024
+ position: sticky;
1025
+ left: 0;
1026
+ background: var(--card);
1027
+ z-index: 4;
1028
+ border-right: 1px solid var(--border);
1029
+ flex-shrink: 0;
1030
+ transition: var(--transition);
1031
+ }
1032
+
1033
+ .label-badge {
1034
+ display: inline-block;
1035
+ padding: 2px 7px;
1036
+ border-radius: 4px;
1037
+ font-size: 11px;
1038
+ font-weight: 700;
1039
+ letter-spacing: 0.02em;
1040
+ white-space: nowrap;
1041
+ flex-shrink: 0;
1042
+ }
1043
+
1044
+ .tl-row-bars { position: relative; flex-shrink: 0; }
1045
+
1046
+ .tl-bar {
1047
+ position: absolute;
1048
+ top: 9px;
1049
+ height: 28px;
1050
+ border-radius: 6px;
1051
+ display: flex;
1052
+ align-items: center;
1053
+ padding: 0 7px;
1054
+ min-width: 3px;
1055
+ cursor: pointer;
1056
+ opacity: 0.85;
1057
+ transition: opacity 0.12s, box-shadow 0.12s;
1058
+ overflow: hidden;
1059
+ }
1060
+
1061
+ .tl-bar-new {
1062
+ animation: tl-bar-in 0.25s ease-out;
1063
+ transform-origin: left center;
1064
+ }
1065
+
1066
+ @keyframes tl-bar-in {
1067
+ from { opacity: 0; transform: scaleX(0.3); }
1068
+ to { opacity: 0.85; transform: scaleX(1); }
1069
+ }
1070
+
1071
+ .tl-bar:hover {
1072
+ opacity: 1;
1073
+ z-index: 1;
1074
+ box-shadow: 0 2px 8px rgba(0,0,0,0.25);
1075
+ }
1076
+
1077
+ .tl-bar span {
1078
+ font-size: 11px;
1079
+ color: rgba(255,255,255,0.95);
1080
+ white-space: nowrap;
1081
+ font-family: 'JetBrains Mono', Menlo, Monaco, monospace;
1082
+ font-weight: 600;
1083
+ pointer-events: none;
1084
+ }
1085
+
1086
+ .tl-bar.fast { background: linear-gradient(90deg, #16a34a, #22c55e); }
1087
+ .tl-bar.medium { background: linear-gradient(90deg, #d97706, #f59e0b); }
1088
+ .tl-bar.slow { background: linear-gradient(90deg, #dc2626, #ef4444); }
1089
+
1090
+
1091
+ /* ── Timeline context menu ── */
1092
+ .tl-ctx-menu {
1093
+ position: fixed;
1094
+ background: var(--card);
1095
+ color: var(--ink);
1096
+ border: 1px solid var(--border);
1097
+ border-radius: var(--radius-sm);
1098
+ padding: 4px 0;
1099
+ min-width: 180px;
1100
+ z-index: 200;
1101
+ box-shadow: var(--shadow-lg);
1102
+ font-size: 13px;
1103
+ }
1104
+
1105
+ .tl-ctx-menu.hidden { display: none; }
1106
+
1107
+ .tl-ctx-menu-item {
1108
+ padding: 7px 14px;
1109
+ cursor: pointer;
1110
+ color: var(--ink);
1111
+ display: flex;
1112
+ align-items: center;
1113
+ gap: 8px;
1114
+ }
1115
+
1116
+ .tl-ctx-menu-item:hover {
1117
+ background: var(--bg);
1118
+ }
1119
+
1120
+ .tl-ctx-menu-item-icon {
1121
+ width: 16px;
1122
+ height: 16px;
1123
+ flex-shrink: 0;
1124
+ display: flex;
1125
+ align-items: center;
1126
+ justify-content: center;
1127
+ color: var(--muted);
1128
+ }
1129
+
1130
+ /* ── PerfPoint detail popover ── */
1131
+ .tl-detail {
1132
+ position: fixed;
1133
+ width: 360px;
1134
+ max-height: 400px;
1135
+ background: #111827;
1136
+ border: 1px solid rgba(255,255,255,0.12);
1137
+ border-radius: 6px;
1138
+ box-shadow: var(--shadow-lg);
1139
+ display: flex;
1140
+ flex-direction: column;
1141
+ font-family: 'JetBrains Mono', Menlo, Monaco, monospace;
1142
+ font-size: 12px;
1143
+ color: #e5e7eb;
1144
+ z-index: 200;
1145
+ overflow: hidden;
1146
+ }
1147
+
1148
+ .tl-detail.hidden { display: none; }
1149
+
1150
+ .tl-detail-header {
1151
+ display: flex;
1152
+ align-items: center;
1153
+ gap: 10px;
1154
+ padding: 10px 14px;
1155
+ border-bottom: 1px solid rgba(255,255,255,0.08);
1156
+ flex-shrink: 0;
1157
+ background: rgba(255,255,255,0.03);
1158
+ }
1159
+
1160
+ .tl-detail-label { flex: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
1161
+ .tl-detail-dur { color: #fbbf24; font-weight: 700; white-space: nowrap; font-size: 14px; }
1162
+
1163
+ .tl-detail-close {
1164
+ background: transparent;
1165
+ border: none;
1166
+ color: #6b7280;
1167
+ cursor: pointer;
1168
+ font-size: 14px;
1169
+ padding: 2px 6px;
1170
+ line-height: 1;
1171
+ border-radius: 4px;
1172
+ font-family: inherit;
1173
+ }
1174
+
1175
+ .tl-detail-close:hover { color: #e5e7eb; background: rgba(255,255,255,0.08); }
1176
+
1177
+ .tl-detail-body { overflow-y: auto; flex: 1; padding: 10px 14px; }
1178
+ .tl-detail-body::-webkit-scrollbar { width: 4px; }
1179
+ .tl-detail-body::-webkit-scrollbar-track { background: transparent; }
1180
+ .tl-detail-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 2px; }
1181
+
1182
+ /* ── Tl scrollbar ── */
1183
+ .tl-scroll::-webkit-scrollbar { width: 6px; height: 6px; }
1184
+ .tl-scroll::-webkit-scrollbar-track { background: transparent; }
1185
+ .tl-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
1186
+ .tl-scroll::-webkit-scrollbar-thumb:hover { background: var(--muted); }
1187
+ .tl-scroll::-webkit-scrollbar-corner { background: transparent; }
1188
+
1189
+ /* ── Responsive ── */
1190
+ @media (max-width: 1080px) {
1191
+ body { flex-direction: column; }
1192
+ .sidebar { width: 100%; height: auto; max-height: 200px; flex-direction: row; flex-wrap: wrap; border-right: none; border-bottom: 1px solid var(--border); }
1193
+ .sidebar-brand { padding: 12px 16px; }
1194
+ .sidebar-nav { flex-direction: row; padding: 0 8px; }
1195
+ .sidebar-debuggers { display: none; }
1196
+ .sidebar-footer { margin-left: auto; display: flex; align-items: center; }
1197
+ .sidebar-divider { display: none; }
1198
+ .console-layout { grid-template-columns: 1fr; height: auto; overflow-y: auto; }
1199
+ .panel { min-height: 280px; }
1200
+ .tl-toolbar { flex-wrap: wrap; }
1201
+ .tl-toolbar-labels { max-width: 100%; }
1202
+ }
1203
+
1204
+ /* ── Disconnected banner ── */
1205
+ .disconnected-banner {
1206
+ position: fixed;
1207
+ top: 0;
1208
+ left: 0;
1209
+ right: 0;
1210
+ z-index: 1000;
1211
+ background: var(--offline);
1212
+ color: #fff;
1213
+ text-align: center;
1214
+ padding: 8px 16px;
1215
+ font-size: 13px;
1216
+ font-weight: 600;
1217
+ letter-spacing: 0.02em;
1218
+ animation: banner-slide-in 0.3s ease-out;
1219
+ }
1220
+
1221
+ @keyframes banner-slide-in {
1222
+ from { transform: translateY(-100%); }
1223
+ to { transform: translateY(0); }
1224
+ }