@scenetest/vite-plugin 0.10.1 → 0.12.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.
Files changed (104) hide show
  1. package/README.md +6 -0
  2. package/dist/dashboard.d.ts +8 -2
  3. package/dist/dashboard.d.ts.map +1 -1
  4. package/dist/dashboard.js +25 -1210
  5. package/dist/dashboard.js.map +1 -1
  6. package/dist/event-hub.d.ts +5 -0
  7. package/dist/event-hub.d.ts.map +1 -1
  8. package/dist/event-hub.js +11 -0
  9. package/dist/event-hub.js.map +1 -1
  10. package/dist/index.d.ts +8 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +8 -6
  13. package/dist/index.js.map +1 -1
  14. package/dist/middleware.d.ts +2 -0
  15. package/dist/middleware.d.ts.map +1 -1
  16. package/dist/middleware.js +235 -71
  17. package/dist/middleware.js.map +1 -1
  18. package/dist/panels/observer/audio.d.ts +81 -0
  19. package/dist/panels/observer/audio.d.ts.map +1 -0
  20. package/dist/panels/observer/audio.js +296 -0
  21. package/dist/panels/observer/audio.js.map +1 -0
  22. package/dist/panels/observer/auto.d.ts +10 -0
  23. package/dist/panels/observer/auto.d.ts.map +1 -0
  24. package/dist/panels/observer/auto.js +11 -0
  25. package/dist/panels/observer/auto.js.map +1 -0
  26. package/dist/panels/observer/fs-viewer.d.ts +20 -0
  27. package/dist/panels/observer/fs-viewer.d.ts.map +1 -0
  28. package/dist/panels/observer/fs-viewer.js +536 -0
  29. package/dist/panels/observer/fs-viewer.js.map +1 -0
  30. package/dist/panels/observer/fullscreen.d.ts +24 -0
  31. package/dist/panels/observer/fullscreen.d.ts.map +1 -0
  32. package/dist/panels/observer/fullscreen.js +701 -0
  33. package/dist/panels/observer/fullscreen.js.map +1 -0
  34. package/dist/panels/observer/history.d.ts +41 -0
  35. package/dist/panels/observer/history.d.ts.map +1 -0
  36. package/dist/panels/observer/history.js +307 -0
  37. package/dist/panels/observer/history.js.map +1 -0
  38. package/dist/panels/observer/index.d.ts +33 -0
  39. package/dist/panels/observer/index.d.ts.map +1 -0
  40. package/dist/panels/observer/index.js +128 -0
  41. package/dist/panels/observer/index.js.map +1 -0
  42. package/dist/panels/observer/panel.d.ts +12 -0
  43. package/dist/panels/observer/panel.d.ts.map +1 -0
  44. package/dist/panels/observer/panel.js +461 -0
  45. package/dist/panels/observer/panel.js.map +1 -0
  46. package/dist/panels/observer/render.d.ts +109 -0
  47. package/dist/panels/observer/render.d.ts.map +1 -0
  48. package/dist/panels/observer/render.js +760 -0
  49. package/dist/panels/observer/render.js.map +1 -0
  50. package/dist/panels/observer/state.d.ts +57 -0
  51. package/dist/panels/observer/state.d.ts.map +1 -0
  52. package/dist/panels/observer/state.js +187 -0
  53. package/dist/panels/observer/state.js.map +1 -0
  54. package/dist/panels/observer/styles.d.ts +6 -0
  55. package/dist/panels/observer/styles.d.ts.map +1 -0
  56. package/dist/panels/observer/styles.js +1706 -0
  57. package/dist/panels/observer/styles.js.map +1 -0
  58. package/dist/panels/observer/types.d.ts +102 -0
  59. package/dist/panels/observer/types.d.ts.map +1 -0
  60. package/dist/panels/observer/types.js +5 -0
  61. package/dist/panels/observer/types.js.map +1 -0
  62. package/dist/panels/observer/utils.d.ts +45 -0
  63. package/dist/panels/observer/utils.d.ts.map +1 -0
  64. package/dist/panels/observer/utils.js +101 -0
  65. package/dist/panels/observer/utils.js.map +1 -0
  66. package/dist/panels/recorder/auto.d.ts +10 -0
  67. package/dist/panels/recorder/auto.d.ts.map +1 -0
  68. package/dist/panels/recorder/auto.js +11 -0
  69. package/dist/panels/recorder/auto.js.map +1 -0
  70. package/dist/panels/recorder/capture.d.ts +18 -0
  71. package/dist/panels/recorder/capture.d.ts.map +1 -0
  72. package/dist/panels/recorder/capture.js +218 -0
  73. package/dist/panels/recorder/capture.js.map +1 -0
  74. package/dist/panels/recorder/index.d.ts +41 -0
  75. package/dist/panels/recorder/index.d.ts.map +1 -0
  76. package/dist/panels/recorder/index.js +208 -0
  77. package/dist/panels/recorder/index.js.map +1 -0
  78. package/dist/panels/recorder/panel.d.ts +55 -0
  79. package/dist/panels/recorder/panel.d.ts.map +1 -0
  80. package/dist/panels/recorder/panel.js +284 -0
  81. package/dist/panels/recorder/panel.js.map +1 -0
  82. package/dist/panels/recorder/reverse-selector.d.ts +31 -0
  83. package/dist/panels/recorder/reverse-selector.d.ts.map +1 -0
  84. package/dist/panels/recorder/reverse-selector.js +116 -0
  85. package/dist/panels/recorder/reverse-selector.js.map +1 -0
  86. package/dist/panels/recorder/styles.d.ts +5 -0
  87. package/dist/panels/recorder/styles.d.ts.map +1 -0
  88. package/dist/panels/recorder/styles.js +300 -0
  89. package/dist/panels/recorder/styles.js.map +1 -0
  90. package/dist/panels/recorder/types.d.ts +51 -0
  91. package/dist/panels/recorder/types.d.ts.map +1 -0
  92. package/dist/panels/recorder/types.js +15 -0
  93. package/dist/panels/recorder/types.js.map +1 -0
  94. package/dist/strip.d.ts.map +1 -1
  95. package/dist/strip.js +6 -3
  96. package/dist/strip.js.map +1 -1
  97. package/dist/transform.d.ts.map +1 -1
  98. package/dist/transform.js +5 -2
  99. package/dist/transform.js.map +1 -1
  100. package/dist/virtual-module.d.ts +3 -2
  101. package/dist/virtual-module.d.ts.map +1 -1
  102. package/dist/virtual-module.js +4 -3
  103. package/dist/virtual-module.js.map +1 -1
  104. package/package.json +13 -5
@@ -0,0 +1,1706 @@
1
+ /**
2
+ * CSS styles for the dev panel
3
+ */
4
+ export const panelStyles = `
5
+ #scenetest-panel {
6
+ position: fixed;
7
+ bottom: 16px;
8
+ right: 16px;
9
+ width: 400px;
10
+ max-height: 450px;
11
+ background: #1a1a2e;
12
+ border: 1px solid #4a4a6a;
13
+ border-radius: 8px;
14
+ font-family: ui-monospace, monospace;
15
+ font-size: 12px;
16
+ color: #e0e0e0;
17
+ z-index: 999999;
18
+ box-shadow: 0 4px 24px rgba(0,0,0,0.4);
19
+ display: flex;
20
+ flex-direction: column;
21
+ }
22
+ #scenetest-panel.dragging {
23
+ opacity: 0.92;
24
+ }
25
+ #scenetest-panel.unsnapping {
26
+ transition: top 0.12s cubic-bezier(0.2, 0, 0, 1),
27
+ left 0.12s cubic-bezier(0.2, 0, 0, 1),
28
+ box-shadow 0.12s ease;
29
+ box-shadow: 0 8px 32px rgba(0,0,0,0.5);
30
+ }
31
+ #scenetest-panel.snapping {
32
+ transition: top 0.3s cubic-bezier(0.2, 0, 0.2, 1),
33
+ left 0.3s cubic-bezier(0.2, 0, 0.2, 1);
34
+ }
35
+ #scenetest-panel.flicking {
36
+ transition: top 0.4s cubic-bezier(0.16, 1, 0.3, 1),
37
+ left 0.4s cubic-bezier(0.16, 1, 0.3, 1);
38
+ }
39
+ #scenetest-panel.corner-bottom-right {
40
+ bottom: 16px;
41
+ right: 16px;
42
+ top: auto;
43
+ left: auto;
44
+ }
45
+ #scenetest-panel.corner-bottom-left {
46
+ bottom: 16px;
47
+ left: 16px;
48
+ top: auto;
49
+ right: auto;
50
+ }
51
+ #scenetest-panel.corner-top-right {
52
+ top: 16px;
53
+ right: 16px;
54
+ bottom: auto;
55
+ left: auto;
56
+ }
57
+ #scenetest-panel.corner-top-left {
58
+ top: 16px;
59
+ left: 16px;
60
+ bottom: auto;
61
+ right: auto;
62
+ }
63
+ #scenetest-panel.collapsed {
64
+ max-height: none;
65
+ width: auto;
66
+ }
67
+ #scenetest-panel.collapsed #scenetest-list,
68
+ #scenetest-panel.collapsed #scenetest-actions {
69
+ display: none;
70
+ }
71
+ #scenetest-header {
72
+ padding: 10px 12px;
73
+ background: #252542;
74
+ border-radius: 8px 8px 0 0;
75
+ display: flex;
76
+ justify-content: space-between;
77
+ align-items: center;
78
+ cursor: grab;
79
+ user-select: none;
80
+ border-bottom: 1px solid #4a4a6a;
81
+ }
82
+ #scenetest-panel.dragging #scenetest-header {
83
+ cursor: grabbing;
84
+ }
85
+ #scenetest-header:hover {
86
+ background: #2a2a4a;
87
+ }
88
+ #scenetest-title {
89
+ font-weight: 600;
90
+ color: #a0a0ff;
91
+ display: flex;
92
+ align-items: center;
93
+ gap: 6px;
94
+ }
95
+ .scenetest-icon {
96
+ display: inline-flex;
97
+ align-items: center;
98
+ justify-content: center;
99
+ width: 22px;
100
+ height: 22px;
101
+ border-radius: 50%;
102
+ background: #a0a0ff;
103
+ font-size: 12px;
104
+ filter: drop-shadow(0 2px 4px rgba(0,0,0,0.3));
105
+ }
106
+ .scenetest-icon span {
107
+ filter: drop-shadow(0px 0px 4px #ffffff);
108
+ }
109
+ #scenetest-counts {
110
+ display: flex;
111
+ gap: 8px;
112
+ align-items: center;
113
+ }
114
+ .scenetest-count {
115
+ padding: 2px 8px;
116
+ border-radius: 4px;
117
+ font-weight: 500;
118
+ cursor: pointer;
119
+ transition: opacity 0.15s;
120
+ }
121
+ .scenetest-count:hover {
122
+ opacity: 0.8;
123
+ }
124
+ .scenetest-count.pass {
125
+ background: #1a3a1a;
126
+ color: #4ade80;
127
+ }
128
+ .scenetest-count.fail {
129
+ background: #3a1a1a;
130
+ color: #f87171;
131
+ }
132
+ .scenetest-count.active {
133
+ outline: 2px solid currentColor;
134
+ outline-offset: 1px;
135
+ }
136
+ #scenetest-actions {
137
+ display: flex;
138
+ gap: 8px;
139
+ padding: 6px 12px;
140
+ background: #202038;
141
+ border-bottom: 1px solid #3a3a5a;
142
+ flex-wrap: wrap;
143
+ align-items: center;
144
+ }
145
+ .scenetest-btn-group {
146
+ display: flex;
147
+ border: 1px solid #4a4a6a;
148
+ border-radius: 4px;
149
+ overflow: hidden;
150
+ }
151
+ .scenetest-btn-group .scenetest-btn {
152
+ border: none;
153
+ border-radius: 0;
154
+ border-right: 1px solid #4a4a6a;
155
+ }
156
+ .scenetest-btn-group .scenetest-btn:last-child {
157
+ border-right: none;
158
+ }
159
+ .scenetest-btn {
160
+ background: none;
161
+ border: 1px solid #4a4a6a;
162
+ color: #a0a0a0;
163
+ padding: 4px 10px;
164
+ border-radius: 4px;
165
+ cursor: pointer;
166
+ font-size: 11px;
167
+ font-family: inherit;
168
+ transition: all 0.15s;
169
+ text-decoration: none;
170
+ }
171
+ .scenetest-btn:hover {
172
+ background: #3a3a5a;
173
+ color: #e0e0e0;
174
+ }
175
+ .scenetest-btn.active {
176
+ background: #4a4a6a;
177
+ color: #fff;
178
+ }
179
+ .scenetest-separator {
180
+ width: 1px;
181
+ height: 16px;
182
+ background: #3a3a5a;
183
+ }
184
+ #scenetest-list {
185
+ overflow-y: auto;
186
+ max-height: 340px;
187
+ padding: 8px 0;
188
+ }
189
+ .scenetest-group {
190
+ margin: 4px 8px;
191
+ border: 1px solid #3a3a5a;
192
+ border-radius: 6px;
193
+ overflow: hidden;
194
+ }
195
+ .scenetest-group-header {
196
+ padding: 6px 10px;
197
+ background: #252542;
198
+ display: flex;
199
+ justify-content: space-between;
200
+ align-items: center;
201
+ cursor: pointer;
202
+ font-size: 11px;
203
+ }
204
+ .scenetest-group-header:hover {
205
+ background: #2a2a4a;
206
+ }
207
+ .scenetest-group-summary {
208
+ display: flex;
209
+ gap: 8px;
210
+ align-items: center;
211
+ }
212
+ .scenetest-group-time {
213
+ color: #6a6a8a;
214
+ }
215
+ .scenetest-group-stats {
216
+ display: flex;
217
+ gap: 6px;
218
+ }
219
+ .scenetest-group-stat {
220
+ font-size: 10px;
221
+ padding: 1px 5px;
222
+ border-radius: 3px;
223
+ }
224
+ .scenetest-group-stat.pass {
225
+ background: #1a3a1a;
226
+ color: #4ade80;
227
+ }
228
+ .scenetest-group-stat.fail {
229
+ background: #3a1a1a;
230
+ color: #f87171;
231
+ }
232
+ .scenetest-group-stat.zero {
233
+ background: #2a2a3a;
234
+ color: #6a6a8a;
235
+ }
236
+ .scenetest-group-items {
237
+ border-top: 1px solid #3a3a5a;
238
+ }
239
+ .scenetest-group.collapsed .scenetest-group-items {
240
+ display: none;
241
+ }
242
+ .scenetest-group-toggle {
243
+ color: #6a6a8a;
244
+ font-size: 10px;
245
+ }
246
+ .scenetest-item {
247
+ padding: 6px 10px;
248
+ border-bottom: 1px solid #2a2a4a;
249
+ display: flex;
250
+ gap: 8px;
251
+ align-items: flex-start;
252
+ cursor: pointer;
253
+ position: relative;
254
+ }
255
+ .scenetest-item:hover {
256
+ background: #252545;
257
+ }
258
+ .scenetest-item:last-child {
259
+ border-bottom: none;
260
+ }
261
+ .scenetest-item .scenetest-icon {
262
+ flex-shrink: 0;
263
+ width: 22px;
264
+ height: 22px;
265
+ display: inline-flex;
266
+ align-items: center;
267
+ justify-content: center;
268
+ border-radius: 50%;
269
+ font-weight: bold;
270
+ text-align: center;
271
+ }
272
+ .scenetest-item.pass .scenetest-icon {
273
+ background: #22c55e;
274
+ color: white;
275
+ font-size: 14px;
276
+ }
277
+ .scenetest-item.fail .scenetest-icon {
278
+ background: #f87171;
279
+ color: white;
280
+ font-size: 20px;
281
+ box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.3);
282
+ }
283
+ .scenetest-content {
284
+ flex: 1;
285
+ min-width: 0;
286
+ }
287
+ .scenetest-desc {
288
+ word-break: break-word;
289
+ }
290
+ .scenetest-item.fail .scenetest-desc {
291
+ color: #f87171;
292
+ }
293
+ .scenetest-desc.negated {
294
+ text-decoration: line-through;
295
+ opacity: 0.7;
296
+ }
297
+ .scenetest-location {
298
+ font-size: 9px;
299
+ color: #6a6a8a;
300
+ margin-top: 2px;
301
+ overflow: hidden;
302
+ text-overflow: ellipsis;
303
+ white-space: nowrap;
304
+ }
305
+ .scenetest-location:hover {
306
+ color: #a0a0ff;
307
+ text-decoration: underline;
308
+ }
309
+ .scenetest-context {
310
+ font-size: 10px;
311
+ color: #8a8aaa;
312
+ margin-top: 3px;
313
+ padding: 4px 6px;
314
+ background: #12122a;
315
+ border-radius: 3px;
316
+ font-family: ui-monospace, monospace;
317
+ max-height: 60px;
318
+ overflow: auto;
319
+ white-space: pre-wrap;
320
+ word-break: break-all;
321
+ }
322
+ .scenetest-time {
323
+ color: #6a6a8a;
324
+ flex-shrink: 0;
325
+ font-size: 10px;
326
+ }
327
+ #scenetest-empty {
328
+ padding: 20px;
329
+ text-align: center;
330
+ color: #6a6a8a;
331
+ }
332
+ .scenetest-ungrouped {
333
+ padding: 4px 8px;
334
+ }
335
+ .scenetest-history {
336
+ font-size: 9px;
337
+ color: #8a8aaa;
338
+ margin-top: 2px;
339
+ font-style: italic;
340
+ }
341
+ /* Audio controls */
342
+ .scenetest-audio-controls {
343
+ display: flex;
344
+ }
345
+ .scenetest-audio-btn {
346
+ min-width: 32px;
347
+ padding: 4px 8px;
348
+ font-size: 14px;
349
+ transition: all 0.15s;
350
+ }
351
+ .scenetest-audio-btn:hover {
352
+ background: #3a3a5a;
353
+ }
354
+ .scenetest-audio-btn.muted {
355
+ opacity: 0.5;
356
+ }
357
+ .scenetest-audio-btn.playing {
358
+ background: #2a4a2a;
359
+ color: #4ade80;
360
+ animation: scenetest-pulse 1s ease-in-out infinite;
361
+ }
362
+ @keyframes scenetest-pulse {
363
+ 0%, 100% { opacity: 1; }
364
+ 50% { opacity: 0.7; }
365
+ }
366
+ /* Note badge for musical indicators */
367
+ .scenetest-note {
368
+ font-size: 9px;
369
+ padding: 2px 5px;
370
+ border-radius: 3px;
371
+ font-family: ui-monospace, monospace;
372
+ flex-shrink: 0;
373
+ opacity: 0.7;
374
+ transition: opacity 0.15s;
375
+ }
376
+ .scenetest-note:hover {
377
+ opacity: 1;
378
+ }
379
+ .scenetest-note.pass {
380
+ background: #1a3a1a;
381
+ color: #4ade80;
382
+ }
383
+ .scenetest-note.fail {
384
+ background: #3a1a1a;
385
+ color: #f87171;
386
+ }
387
+ /* Server badge for multi-context assertions */
388
+ .scenetest-server-badge {
389
+ display: inline-block;
390
+ font-size: 9px;
391
+ padding: 1px 4px;
392
+ border-radius: 3px;
393
+ background: #3a2a5a;
394
+ color: #c4b5fd;
395
+ margin-right: 6px;
396
+ font-weight: 500;
397
+ text-transform: uppercase;
398
+ letter-spacing: 0.3px;
399
+ vertical-align: middle;
400
+ }
401
+ .scenetest-item.server {
402
+ border-left: 2px solid #a78bfa;
403
+ }
404
+ `;
405
+ export const fullscreenStyles = `
406
+ * { box-sizing: border-box; }
407
+ body {
408
+ margin: 0;
409
+ padding: 0;
410
+ background: #0f0f1a;
411
+ color: #e0e0e0;
412
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
413
+ font-size: 13px;
414
+ }
415
+ #header {
416
+ position: sticky;
417
+ top: 0;
418
+ background: #1a1a2e;
419
+ border-bottom: 1px solid #4a4a6a;
420
+ padding: 16px 24px;
421
+ display: flex;
422
+ justify-content: space-between;
423
+ align-items: center;
424
+ z-index: 100;
425
+ flex-wrap: wrap;
426
+ gap: 12px;
427
+ }
428
+ #title {
429
+ font-size: 18px;
430
+ font-weight: 600;
431
+ color: #a0a0ff;
432
+ display: flex;
433
+ align-items: center;
434
+ gap: 10px;
435
+ }
436
+ #title .icon {
437
+ display: inline-flex;
438
+ align-items: center;
439
+ justify-content: center;
440
+ width: 32px;
441
+ height: 32px;
442
+ border-radius: 50%;
443
+ background: #a0a0ff;
444
+ font-size: 18px;
445
+ filter: drop-shadow(0 2px 6px rgba(0,0,0,0.3));
446
+ }
447
+ #title .icon span {
448
+ filter: drop-shadow(0px 0px 5px #ffffff);
449
+ }
450
+ #controls {
451
+ display: flex;
452
+ gap: 12px;
453
+ align-items: center;
454
+ flex-wrap: wrap;
455
+ }
456
+ #counts {
457
+ display: flex;
458
+ gap: 12px;
459
+ align-items: center;
460
+ }
461
+ .count {
462
+ padding: 4px 12px;
463
+ border-radius: 6px;
464
+ font-weight: 600;
465
+ font-size: 14px;
466
+ }
467
+ .count.pass {
468
+ background: #1a3a1a;
469
+ color: #4ade80;
470
+ }
471
+ .count.fail {
472
+ background: #3a1a1a;
473
+ color: #f87171;
474
+ }
475
+ .btn {
476
+ background: #252542;
477
+ border: 1px solid #4a4a6a;
478
+ color: #a0a0a0;
479
+ padding: 8px 16px;
480
+ border-radius: 6px;
481
+ cursor: pointer;
482
+ font-size: 13px;
483
+ font-family: inherit;
484
+ transition: all 0.15s;
485
+ }
486
+ .btn:hover {
487
+ background: #3a3a5a;
488
+ color: #e0e0e0;
489
+ }
490
+ .btn.active {
491
+ background: #4a4a6a;
492
+ color: #fff;
493
+ }
494
+ #filters {
495
+ display: flex;
496
+ gap: 0;
497
+ }
498
+ .btn-group {
499
+ display: flex;
500
+ border: 1px solid #4a4a6a;
501
+ border-radius: 6px;
502
+ overflow: hidden;
503
+ }
504
+ .btn-group .btn {
505
+ border: none;
506
+ border-radius: 0;
507
+ border-right: 1px solid #4a4a6a;
508
+ }
509
+ .btn-group .btn:last-child {
510
+ border-right: none;
511
+ }
512
+ .separator {
513
+ width: 1px;
514
+ height: 24px;
515
+ background: #4a4a6a;
516
+ }
517
+ #list {
518
+ padding: 16px;
519
+ }
520
+ .ungrouped-list {
521
+ display: flex;
522
+ flex-direction: column;
523
+ gap: 8px;
524
+ }
525
+ .group {
526
+ margin-bottom: 16px;
527
+ border: 1px solid #3a3a5a;
528
+ border-radius: 8px;
529
+ overflow: hidden;
530
+ }
531
+ .group-header {
532
+ padding: 12px 16px;
533
+ background: #1a1a2e;
534
+ display: flex;
535
+ justify-content: space-between;
536
+ align-items: center;
537
+ cursor: pointer;
538
+ }
539
+ .group-header:hover {
540
+ background: #252542;
541
+ }
542
+ .group-info {
543
+ display: flex;
544
+ gap: 16px;
545
+ align-items: center;
546
+ }
547
+ .group-time {
548
+ color: #a0a0ff;
549
+ font-weight: 500;
550
+ }
551
+ .group-stats {
552
+ display: flex;
553
+ gap: 8px;
554
+ }
555
+ .group-stat {
556
+ padding: 2px 8px;
557
+ border-radius: 4px;
558
+ font-size: 12px;
559
+ }
560
+ .group-stat.pass {
561
+ background: #1a3a1a;
562
+ color: #4ade80;
563
+ }
564
+ .group-stat.fail {
565
+ background: #3a1a1a;
566
+ color: #f87171;
567
+ }
568
+ .group-toggle {
569
+ color: #6a6a8a;
570
+ font-size: 12px;
571
+ }
572
+ .group-items {
573
+ border-top: 1px solid #3a3a5a;
574
+ }
575
+ .group.collapsed .group-items {
576
+ display: none;
577
+ }
578
+ .item {
579
+ padding: 10px 16px;
580
+ background: #12121f;
581
+ display: flex;
582
+ gap: 12px;
583
+ align-items: flex-start;
584
+ border-bottom: 1px solid #2a2a4a;
585
+ }
586
+ .item:last-child {
587
+ border-bottom: none;
588
+ }
589
+ .item.fail {
590
+ background: #1a1212;
591
+ }
592
+ .icon {
593
+ font-size: 14px;
594
+ width: 22px;
595
+ height: 22px;
596
+ display: inline-flex;
597
+ align-items: center;
598
+ justify-content: center;
599
+ border-radius: 50%;
600
+ font-weight: bold;
601
+ text-align: center;
602
+ flex-shrink: 0;
603
+ }
604
+ .item.pass .icon {
605
+ background: #22c55e;
606
+ color: white;
607
+ }
608
+ .item.fail .icon {
609
+ background: #f87171;
610
+ color: white;
611
+ font-size: 20px;
612
+ box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.3);
613
+ }
614
+ .content {
615
+ flex: 1;
616
+ }
617
+ .desc {
618
+ margin-bottom: 4px;
619
+ word-break: break-word;
620
+ }
621
+ .desc[data-action] {
622
+ cursor: pointer;
623
+ border-radius: 3px;
624
+ padding: 1px 3px;
625
+ margin: -1px -3px;
626
+ }
627
+ .desc[data-action]:hover {
628
+ background: rgba(160, 160, 255, 0.1);
629
+ }
630
+ .item.fail .desc {
631
+ color: #f87171;
632
+ }
633
+ .desc.negated {
634
+ text-decoration: line-through;
635
+ opacity: 0.7;
636
+ }
637
+ .location {
638
+ font-size: 11px;
639
+ color: #6a6a8a;
640
+ margin-top: 4px;
641
+ cursor: pointer;
642
+ }
643
+ .location:hover {
644
+ color: #a0a0ff;
645
+ text-decoration: underline;
646
+ }
647
+ .context {
648
+ margin-top: 8px;
649
+ padding: 8px;
650
+ background: #0a0a12;
651
+ border-radius: 4px;
652
+ font-size: 11px;
653
+ color: #a0a0c0;
654
+ white-space: pre-wrap;
655
+ word-break: break-all;
656
+ max-height: 100px;
657
+ overflow: auto;
658
+ }
659
+ .meta {
660
+ font-size: 11px;
661
+ color: #6a6a8a;
662
+ }
663
+ .stack {
664
+ margin-top: 8px;
665
+ padding: 8px;
666
+ background: #0a0a12;
667
+ border-radius: 4px;
668
+ font-size: 11px;
669
+ color: #8a8a9a;
670
+ white-space: pre-wrap;
671
+ word-break: break-all;
672
+ }
673
+ .history {
674
+ font-size: 11px;
675
+ color: #8a8aaa;
676
+ margin-top: 4px;
677
+ font-style: italic;
678
+ }
679
+ #empty {
680
+ text-align: center;
681
+ padding: 60px 20px;
682
+ color: #6a6a8a;
683
+ }
684
+ #empty-icon {
685
+ font-size: 48px;
686
+ margin-bottom: 16px;
687
+ }
688
+ .group.highlighted {
689
+ box-shadow: 0 0 0 3px #a0a0ff, 0 0 20px rgba(160, 160, 255, 0.4);
690
+ }
691
+
692
+ /* View mode toggle */
693
+ #view-modes {
694
+ display: flex;
695
+ gap: 0;
696
+ }
697
+
698
+ /* Location view styles */
699
+ .location-row {
700
+ display: flex;
701
+ align-items: center;
702
+ justify-content: space-between;
703
+ padding: 12px 16px;
704
+ background: #12121f;
705
+ border: 1px solid #3a3a5a;
706
+ border-radius: 8px;
707
+ margin-bottom: 8px;
708
+ cursor: pointer;
709
+ transition: all 0.15s;
710
+ }
711
+ .location-row:hover {
712
+ background: #1a1a2e;
713
+ border-color: #4a4a6a;
714
+ }
715
+ .location-row.all-pass {
716
+ border-left: 3px solid #4ade80;
717
+ }
718
+ .location-row.has-fails {
719
+ border-left: 3px solid #f59e0b;
720
+ }
721
+ .location-row.last-fail {
722
+ border-left: 3px solid #f87171;
723
+ background: #1a1212;
724
+ }
725
+ .location-main {
726
+ flex: 1;
727
+ display: flex;
728
+ justify-content: space-between;
729
+ align-items: center;
730
+ gap: 16px;
731
+ min-width: 0;
732
+ }
733
+ .location-info {
734
+ display: flex;
735
+ flex-direction: column;
736
+ gap: 4px;
737
+ min-width: 0;
738
+ }
739
+ .location-file {
740
+ font-size: 12px;
741
+ color: #a0a0ff;
742
+ font-weight: 500;
743
+ }
744
+ .location-desc {
745
+ font-size: 13px;
746
+ color: #e0e0e0;
747
+ }
748
+ .location-stats {
749
+ display: flex;
750
+ align-items: center;
751
+ gap: 12px;
752
+ flex-shrink: 0;
753
+ }
754
+ /* Current state icon - prominent indicator on the left */
755
+ .state-icon {
756
+ width: 28px;
757
+ height: 28px;
758
+ display: flex;
759
+ align-items: center;
760
+ justify-content: center;
761
+ font-size: 16px;
762
+ font-weight: bold;
763
+ border-radius: 50%;
764
+ flex-shrink: 0;
765
+ margin-right: 12px;
766
+ }
767
+ .state-icon.pass {
768
+ background: #1a3a1a;
769
+ color: #4ade80;
770
+ }
771
+ .state-icon.warn {
772
+ background: #3a2a0a;
773
+ color: #f59e0b;
774
+ }
775
+ .state-icon.fail {
776
+ background: #f87171;
777
+ color: white;
778
+ font-size: 20px;
779
+ box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.3);
780
+ }
781
+
782
+ .status-dots {
783
+ display: flex;
784
+ gap: 4px;
785
+ align-items: center;
786
+ }
787
+ .status-dot {
788
+ width: 14px;
789
+ height: 14px;
790
+ border-radius: 50%;
791
+ transition: transform 0.15s;
792
+ position: relative;
793
+ display: inline-flex;
794
+ align-items: center;
795
+ justify-content: center;
796
+ }
797
+ .status-dot.pass {
798
+ background: #4ade80;
799
+ }
800
+ .status-dot.fail {
801
+ background: #f87171;
802
+ }
803
+ /* Accessibility: X marker on failure dots for colorblind users */
804
+ .status-dot .dot-x {
805
+ position: absolute;
806
+ color: white;
807
+ font-size: 20px;
808
+ font-weight: bold;
809
+ line-height: 1;
810
+ top: 50%;
811
+ left: 50%;
812
+ transform: translate(-50%, -50%);
813
+ text-shadow: 0 0 2px rgba(0,0,0,0.5);
814
+ }
815
+ .status-dot:last-child {
816
+ animation: pulse-dot 0.5s ease-out;
817
+ }
818
+ @keyframes pulse-dot {
819
+ 0% { transform: scale(1.5); }
820
+ 100% { transform: scale(1); }
821
+ }
822
+ .location-count {
823
+ font-size: 11px;
824
+ color: #6a6a8a;
825
+ }
826
+ .location-summary {
827
+ display: flex;
828
+ gap: 6px;
829
+ }
830
+ .location-summary .stat {
831
+ padding: 2px 6px;
832
+ border-radius: 4px;
833
+ font-size: 11px;
834
+ }
835
+ .location-summary .stat.pass {
836
+ background: #1a3a1a;
837
+ color: #4ade80;
838
+ }
839
+ .location-summary .stat.fail {
840
+ background: #3a1a1a;
841
+ color: #f87171;
842
+ }
843
+ .location-actions {
844
+ margin-left: 12px;
845
+ }
846
+ .loc-btn {
847
+ background: #252542;
848
+ border: 1px solid #4a4a6a;
849
+ color: #a0a0a0;
850
+ padding: 4px 8px;
851
+ border-radius: 4px;
852
+ cursor: pointer;
853
+ font-size: 12px;
854
+ }
855
+ .loc-btn:hover {
856
+ background: #3a3a5a;
857
+ color: #e0e0e0;
858
+ }
859
+
860
+ /* Sequence view styles */
861
+ .sequence-header {
862
+ background: #1a1a2e;
863
+ border: 1px solid #4a4a6a;
864
+ border-radius: 8px;
865
+ padding: 16px;
866
+ margin-bottom: 8px;
867
+ display: flex;
868
+ align-items: flex-start;
869
+ gap: 12px;
870
+ border-left: 3px solid #4ade80;
871
+ }
872
+ .sequence-header.warn {
873
+ border-left-color: #f59e0b;
874
+ background: linear-gradient(90deg, rgba(245, 158, 11, 0.1) 0%, #1a1a2e 50%);
875
+ }
876
+ .sequence-header.fail {
877
+ border-left-color: #f87171;
878
+ background: linear-gradient(90deg, rgba(248, 113, 113, 0.1) 0%, #1a1a2e 50%);
879
+ }
880
+ .sequence-info {
881
+ flex: 1;
882
+ }
883
+ .sequence-location {
884
+ margin-bottom: 4px;
885
+ }
886
+ .sequence-file {
887
+ color: #a0a0ff;
888
+ font-size: 14px;
889
+ cursor: pointer;
890
+ }
891
+ .sequence-file:hover {
892
+ text-decoration: underline;
893
+ }
894
+ .sequence-desc {
895
+ font-size: 15px;
896
+ color: #e0e0e0;
897
+ margin-bottom: 8px;
898
+ }
899
+ .sequence-header.warn .sequence-desc {
900
+ color: #f59e0b;
901
+ }
902
+ .sequence-header.fail .sequence-desc {
903
+ color: #f87171;
904
+ }
905
+ .sequence-summary {
906
+ display: flex;
907
+ align-items: center;
908
+ gap: 16px;
909
+ }
910
+ .sequence-total {
911
+ color: #6a6a8a;
912
+ font-size: 12px;
913
+ }
914
+ .sequence-stats {
915
+ display: flex;
916
+ gap: 8px;
917
+ }
918
+ .sequence-stats .stat {
919
+ padding: 2px 8px;
920
+ border-radius: 4px;
921
+ font-size: 12px;
922
+ }
923
+ .sequence-stats .stat.pass {
924
+ background: #1a3a1a;
925
+ color: #4ade80;
926
+ }
927
+ .sequence-stats .stat.fail {
928
+ background: #3a1a1a;
929
+ color: #f87171;
930
+ }
931
+
932
+ /* Flaky test info styles - own line in location row */
933
+ .flaky-info {
934
+ font-size: 11px;
935
+ padding: 4px 8px;
936
+ border-radius: 4px;
937
+ font-family: ui-monospace, monospace;
938
+ margin-top: 2px;
939
+ }
940
+ .flaky-info.failing {
941
+ background: #3a1a1a;
942
+ color: #f87171;
943
+ }
944
+ .flaky-info.resolved {
945
+ background: #1a3a1a;
946
+ color: #4ade80;
947
+ }
948
+
949
+ .flaky-status {
950
+ font-size: 12px;
951
+ padding: 8px 12px;
952
+ margin-top: 8px;
953
+ border-radius: 4px;
954
+ background: #3a1a1a;
955
+ color: #f87171;
956
+ border-left: 3px solid #f87171;
957
+ font-family: ui-monospace, monospace;
958
+ }
959
+
960
+ .resolution-info {
961
+ font-size: 12px;
962
+ padding: 8px 12px;
963
+ margin-top: 6px;
964
+ border-radius: 4px;
965
+ background: #1a3a1a;
966
+ color: #4ade80;
967
+ border-left: 3px solid #4ade80;
968
+ font-family: ui-monospace, monospace;
969
+ }
970
+
971
+ /* Direction hint */
972
+ .sequence-direction-hint {
973
+ display: flex;
974
+ align-items: center;
975
+ gap: 8px;
976
+ padding: 8px 16px;
977
+ margin-bottom: 8px;
978
+ color: #6a6a8a;
979
+ font-size: 11px;
980
+ background: #0f0f1a;
981
+ border-radius: 4px;
982
+ }
983
+ .direction-arrow {
984
+ color: #a0a0ff;
985
+ font-size: 14px;
986
+ }
987
+
988
+ /* Timeline track for sequence entries */
989
+ .sequence-list {
990
+ position: relative;
991
+ padding-left: 8px;
992
+ }
993
+ .sequence-entry {
994
+ padding: 12px 16px 12px 0;
995
+ background: #12121f;
996
+ display: flex;
997
+ gap: 0;
998
+ align-items: stretch;
999
+ border: 1px solid #3a3a5a;
1000
+ border-radius: 6px;
1001
+ margin-bottom: 0;
1002
+ margin-left: 20px;
1003
+ position: relative;
1004
+ }
1005
+ .sequence-entry.fail {
1006
+ background: #1a1212;
1007
+ border-color: #4a2a2a;
1008
+ }
1009
+
1010
+ /* Timeline track with connecting line */
1011
+ .timeline-track {
1012
+ width: 40px;
1013
+ display: flex;
1014
+ flex-direction: column;
1015
+ align-items: center;
1016
+ position: relative;
1017
+ flex-shrink: 0;
1018
+ }
1019
+ .timeline-line {
1020
+ position: absolute;
1021
+ left: 50%;
1022
+ transform: translateX(-50%);
1023
+ width: 2px;
1024
+ background: #3a3a5a;
1025
+ top: -8px;
1026
+ bottom: -8px;
1027
+ }
1028
+ .timeline-line.first {
1029
+ top: 50%;
1030
+ }
1031
+ .timeline-line.last {
1032
+ bottom: 50%;
1033
+ }
1034
+ .timeline-line.first.last {
1035
+ display: none;
1036
+ }
1037
+ .timeline-dot {
1038
+ width: 14px;
1039
+ height: 14px;
1040
+ border-radius: 50%;
1041
+ position: relative;
1042
+ z-index: 1;
1043
+ display: flex;
1044
+ align-items: center;
1045
+ justify-content: center;
1046
+ margin-top: 4px;
1047
+ }
1048
+ .timeline-dot.pass {
1049
+ background: #4ade80;
1050
+ box-shadow: 0 0 0 3px #1a3a1a;
1051
+ }
1052
+ .timeline-dot.fail {
1053
+ background: #f87171;
1054
+ box-shadow: 0 0 0 3px #3a1a1a;
1055
+ }
1056
+ .timeline-dot .dot-x {
1057
+ color: white;
1058
+ font-size: 20px;
1059
+ font-weight: bold;
1060
+ line-height: 1;
1061
+ text-shadow: 0 0 2px rgba(0,0,0,0.5);
1062
+ }
1063
+
1064
+ .sequence-entry .content {
1065
+ flex: 1;
1066
+ padding-left: 8px;
1067
+ }
1068
+ .sequence-time {
1069
+ font-size: 11px;
1070
+ color: #6a6a8a;
1071
+ margin-bottom: 4px;
1072
+ }
1073
+
1074
+ /* End label */
1075
+ .sequence-end-label {
1076
+ margin-left: 20px;
1077
+ padding: 8px 16px 8px 40px;
1078
+ color: #6a6a8a;
1079
+ font-size: 11px;
1080
+ position: relative;
1081
+ }
1082
+ .sequence-end-label::before {
1083
+ content: '';
1084
+ position: absolute;
1085
+ left: 28px;
1086
+ top: 0;
1087
+ width: 2px;
1088
+ height: 8px;
1089
+ background: #3a3a5a;
1090
+ }
1091
+
1092
+ .back-btn {
1093
+ display: flex;
1094
+ align-items: center;
1095
+ gap: 6px;
1096
+ margin-bottom: 16px;
1097
+ color: #a0a0ff;
1098
+ cursor: pointer;
1099
+ font-size: 13px;
1100
+ }
1101
+ .back-btn:hover {
1102
+ text-decoration: underline;
1103
+ }
1104
+
1105
+ /* Audio controls */
1106
+ #audio-controls {
1107
+ display: flex;
1108
+ }
1109
+ .audio-btn {
1110
+ min-width: 40px;
1111
+ padding: 8px 12px;
1112
+ font-size: 16px;
1113
+ transition: all 0.15s;
1114
+ }
1115
+ .audio-btn:hover {
1116
+ background: #3a3a5a;
1117
+ }
1118
+ .audio-btn.muted {
1119
+ opacity: 0.5;
1120
+ }
1121
+ .audio-btn.playing {
1122
+ background: #2a4a2a;
1123
+ color: #4ade80;
1124
+ animation: audio-pulse 1s ease-in-out infinite;
1125
+ }
1126
+ @keyframes audio-pulse {
1127
+ 0%, 100% { opacity: 1; }
1128
+ 50% { opacity: 0.7; }
1129
+ }
1130
+ /* Note badge for musical indicators */
1131
+ .note-badge {
1132
+ font-size: 11px;
1133
+ padding: 3px 8px;
1134
+ border-radius: 4px;
1135
+ font-family: ui-monospace, monospace;
1136
+ flex-shrink: 0;
1137
+ opacity: 0.7;
1138
+ transition: all 0.15s;
1139
+ align-self: flex-start;
1140
+ margin-top: 2px;
1141
+ }
1142
+ .note-badge:hover {
1143
+ opacity: 1;
1144
+ transform: scale(1.1);
1145
+ }
1146
+ .note-badge.pass {
1147
+ background: #1a3a1a;
1148
+ color: #4ade80;
1149
+ }
1150
+ .note-badge.fail {
1151
+ background: #3a1a1a;
1152
+ color: #f87171;
1153
+ }
1154
+ .note-badge.warn {
1155
+ background: #3a2a0a;
1156
+ color: #f59e0b;
1157
+ }
1158
+ /* Server badge for multi-context assertions */
1159
+ .server-badge {
1160
+ display: inline-block;
1161
+ font-size: 10px;
1162
+ padding: 2px 6px;
1163
+ border-radius: 4px;
1164
+ background: #3a2a5a;
1165
+ color: #c4b5fd;
1166
+ margin-right: 8px;
1167
+ font-weight: 500;
1168
+ text-transform: uppercase;
1169
+ letter-spacing: 0.3px;
1170
+ vertical-align: middle;
1171
+ }
1172
+ .item.server {
1173
+ border-left: 3px solid #a78bfa;
1174
+ }
1175
+ .note-badge.clickable {
1176
+ cursor: pointer;
1177
+ }
1178
+ .note-badge.clickable:hover {
1179
+ opacity: 1;
1180
+ transform: scale(1.15);
1181
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3);
1182
+ }
1183
+ .note-badge.clickable:active {
1184
+ transform: scale(0.95);
1185
+ }
1186
+
1187
+ /* File view toggle (tree/graph) */
1188
+ .file-view-toggle {
1189
+ display: flex;
1190
+ gap: 0;
1191
+ margin-bottom: 8px;
1192
+ }
1193
+ .file-view-btn {
1194
+ font-size: 11px !important;
1195
+ padding: 3px 10px !important;
1196
+ border-radius: 4px;
1197
+ background: transparent;
1198
+ border: 1px solid #3a3a5a;
1199
+ color: #8a8aaa;
1200
+ cursor: pointer;
1201
+ transition: all 0.15s;
1202
+ }
1203
+ .file-view-btn:first-child {
1204
+ border-radius: 4px 0 0 4px;
1205
+ }
1206
+ .file-view-btn:last-child {
1207
+ border-radius: 0 4px 4px 0;
1208
+ border-left: none;
1209
+ }
1210
+ .file-view-btn.active {
1211
+ background: #2a2a4a;
1212
+ color: #e0e0e0;
1213
+ border-color: #5a5a8a;
1214
+ }
1215
+ .file-view-btn:hover:not(.active) {
1216
+ background: #1a1a3a;
1217
+ color: #c0c0d0;
1218
+ }
1219
+
1220
+ /* Filesystem viewer styles */
1221
+ .fs-viewer-container {
1222
+ position: relative;
1223
+ width: 100%;
1224
+ height: 350px;
1225
+ background: #0d1117;
1226
+ border: 1px solid #3a3a5a;
1227
+ border-radius: 8px;
1228
+ overflow: hidden;
1229
+ margin-bottom: 16px;
1230
+ }
1231
+ .fs-viewer-canvas {
1232
+ position: absolute;
1233
+ top: 0;
1234
+ left: 0;
1235
+ width: 100%;
1236
+ height: 100%;
1237
+ }
1238
+ .fs-viewer-status {
1239
+ position: absolute;
1240
+ bottom: 16px;
1241
+ left: 16px;
1242
+ font-size: 11px;
1243
+ color: #6a6a8a;
1244
+ font-family: ui-monospace, monospace;
1245
+ pointer-events: none;
1246
+ z-index: 10;
1247
+ }
1248
+
1249
+ /* File tree view styles */
1250
+ .file-tree {
1251
+ background: #12121f;
1252
+ border: 1px solid #3a3a5a;
1253
+ border-radius: 8px;
1254
+ padding: 12px;
1255
+ margin-bottom: 16px;
1256
+ overflow-x: auto;
1257
+ }
1258
+ .file-tree-header {
1259
+ display: flex;
1260
+ justify-content: space-between;
1261
+ align-items: center;
1262
+ margin-bottom: 12px;
1263
+ }
1264
+ .file-tree-title {
1265
+ font-weight: 600;
1266
+ color: #a0a0ff;
1267
+ font-size: 14px;
1268
+ }
1269
+ .file-tree-hint {
1270
+ font-size: 11px;
1271
+ color: #6a6a8a;
1272
+ }
1273
+ .file-tree-content {
1274
+ /* contents */
1275
+ }
1276
+ .ft-node {
1277
+ border-radius: 4px;
1278
+ }
1279
+ /* Directory header */
1280
+ .ft-dir-header,
1281
+ .ft-file-header {
1282
+ display: flex;
1283
+ align-items: center;
1284
+ gap: 6px;
1285
+ padding: 6px 8px;
1286
+ cursor: pointer;
1287
+ border-radius: 4px;
1288
+ transition: background 0.12s;
1289
+ user-select: none;
1290
+ }
1291
+ .ft-dir-header:hover,
1292
+ .ft-file-header:hover {
1293
+ background: #1a1a2e;
1294
+ }
1295
+ .ft-indent {
1296
+ flex-shrink: 0;
1297
+ }
1298
+ .ft-toggle {
1299
+ font-size: 9px;
1300
+ color: #6a6a8a;
1301
+ width: 12px;
1302
+ text-align: center;
1303
+ flex-shrink: 0;
1304
+ }
1305
+ .ft-dir-icon,
1306
+ .ft-file-icon {
1307
+ font-size: 14px;
1308
+ flex-shrink: 0;
1309
+ filter: saturate(0.7);
1310
+ }
1311
+ .ft-status-icon {
1312
+ font-size: 12px;
1313
+ font-weight: bold;
1314
+ flex-shrink: 0;
1315
+ width: 16px;
1316
+ text-align: center;
1317
+ }
1318
+ .ft-status-icon.pass { color: #4ade80; }
1319
+ .ft-status-icon.warn { color: #f59e0b; }
1320
+ .ft-status-icon.fail { color: #f87171; }
1321
+ .ft-name {
1322
+ font-size: 13px;
1323
+ color: #e0e0e0;
1324
+ overflow: hidden;
1325
+ text-overflow: ellipsis;
1326
+ white-space: nowrap;
1327
+ }
1328
+ .ft-dir .ft-name {
1329
+ font-weight: 500;
1330
+ }
1331
+ .ft-badge {
1332
+ font-size: 10px;
1333
+ color: #6a6a8a;
1334
+ background: #252542;
1335
+ padding: 1px 6px;
1336
+ border-radius: 8px;
1337
+ margin-left: auto;
1338
+ flex-shrink: 0;
1339
+ }
1340
+ .ft-fail-badge {
1341
+ font-size: 10px;
1342
+ color: #f87171;
1343
+ background: #3a1a1a;
1344
+ padding: 1px 6px;
1345
+ border-radius: 8px;
1346
+ flex-shrink: 0;
1347
+ }
1348
+ .ft-children {
1349
+ border-left: 1px solid #2a2a4a;
1350
+ margin-left: 22px;
1351
+ }
1352
+ .ft-assertions {
1353
+ border-left: 1px solid #2a2a4a;
1354
+ margin-left: 22px;
1355
+ }
1356
+ /* Assertion row inside a file */
1357
+ .ft-assertion {
1358
+ display: flex;
1359
+ align-items: center;
1360
+ gap: 6px;
1361
+ padding: 4px 8px;
1362
+ cursor: pointer;
1363
+ border-radius: 4px;
1364
+ transition: background 0.12s;
1365
+ font-size: 12px;
1366
+ }
1367
+ .ft-assertion:hover {
1368
+ background: #1a1a2e;
1369
+ }
1370
+ .ft-assert-icon {
1371
+ font-size: 11px;
1372
+ font-weight: bold;
1373
+ width: 14px;
1374
+ text-align: center;
1375
+ flex-shrink: 0;
1376
+ }
1377
+ .ft-assert-icon.pass { color: #4ade80; }
1378
+ .ft-assert-icon.warn { color: #f59e0b; }
1379
+ .ft-assert-icon.fail { color: #f87171; }
1380
+ .ft-assert-desc {
1381
+ color: #c0c0d0;
1382
+ overflow: hidden;
1383
+ text-overflow: ellipsis;
1384
+ white-space: nowrap;
1385
+ min-width: 0;
1386
+ }
1387
+ .ft-assertion.fail .ft-assert-desc {
1388
+ color: #f87171;
1389
+ }
1390
+ .ft-assert-line {
1391
+ color: #6a6a8a;
1392
+ font-size: 10px;
1393
+ flex-shrink: 0;
1394
+ }
1395
+ .ft-dots {
1396
+ display: flex;
1397
+ gap: 2px;
1398
+ align-items: center;
1399
+ margin-left: auto;
1400
+ flex-shrink: 0;
1401
+ }
1402
+ .ft-dot {
1403
+ width: 6px;
1404
+ height: 6px;
1405
+ border-radius: 50%;
1406
+ }
1407
+ .ft-dot.pass { background: #4ade80; }
1408
+ .ft-dot.fail { background: #f87171; }
1409
+ .ft-assert-count {
1410
+ color: #6a6a8a;
1411
+ font-size: 10px;
1412
+ flex-shrink: 0;
1413
+ min-width: 20px;
1414
+ text-align: right;
1415
+ }
1416
+
1417
+ /* Light-up glow animation for recently-active nodes */
1418
+ .ft-active > .ft-dir-header,
1419
+ .ft-active > .ft-file-header {
1420
+ animation: ft-glow 2s ease-out;
1421
+ }
1422
+ .ft-assertion.ft-active {
1423
+ animation: ft-glow 2s ease-out;
1424
+ }
1425
+ @keyframes ft-glow {
1426
+ 0% {
1427
+ background: rgba(160, 160, 255, 0.25);
1428
+ box-shadow: 0 0 12px rgba(160, 160, 255, 0.3);
1429
+ }
1430
+ 100% {
1431
+ background: transparent;
1432
+ box-shadow: none;
1433
+ }
1434
+ }
1435
+ /* File-level glow coloring based on status */
1436
+ .ft-file.pass.ft-active > .ft-file-header {
1437
+ animation: ft-glow-pass 2s ease-out;
1438
+ }
1439
+ .ft-file.fail.ft-active > .ft-file-header {
1440
+ animation: ft-glow-fail 2s ease-out;
1441
+ }
1442
+ .ft-assertion.pass.ft-active {
1443
+ animation: ft-glow-pass 2s ease-out;
1444
+ }
1445
+ .ft-assertion.fail.ft-active {
1446
+ animation: ft-glow-fail 2s ease-out;
1447
+ }
1448
+ @keyframes ft-glow-pass {
1449
+ 0% {
1450
+ background: rgba(74, 222, 128, 0.2);
1451
+ box-shadow: 0 0 12px rgba(74, 222, 128, 0.25);
1452
+ }
1453
+ 100% {
1454
+ background: transparent;
1455
+ box-shadow: none;
1456
+ }
1457
+ }
1458
+ @keyframes ft-glow-fail {
1459
+ 0% {
1460
+ background: rgba(248, 113, 113, 0.2);
1461
+ box-shadow: 0 0 12px rgba(248, 113, 113, 0.25);
1462
+ }
1463
+ 100% {
1464
+ background: transparent;
1465
+ box-shadow: none;
1466
+ }
1467
+ }
1468
+
1469
+ /* Piano roll visualization - grid style */
1470
+ .piano-roll {
1471
+ background: #12121f;
1472
+ border: 1px solid #3a3a5a;
1473
+ border-radius: 8px;
1474
+ padding: 12px;
1475
+ margin-bottom: 16px;
1476
+ overflow-x: auto;
1477
+ }
1478
+ .piano-roll-header {
1479
+ display: flex;
1480
+ justify-content: space-between;
1481
+ align-items: center;
1482
+ margin-bottom: 12px;
1483
+ }
1484
+ .piano-roll-title {
1485
+ font-weight: 600;
1486
+ color: #a0a0ff;
1487
+ font-size: 14px;
1488
+ }
1489
+ .piano-roll-hint {
1490
+ font-size: 11px;
1491
+ color: #6a6a8a;
1492
+ }
1493
+ .piano-grid {
1494
+ display: flex;
1495
+ flex-direction: column;
1496
+ gap: 2px;
1497
+ }
1498
+ .piano-row {
1499
+ display: flex;
1500
+ align-items: center;
1501
+ gap: 8px;
1502
+ border-left: 3px solid transparent;
1503
+ padding-left: 4px;
1504
+ }
1505
+ .piano-row.pass {
1506
+ border-left-color: #4ade80;
1507
+ }
1508
+ .piano-row.warn {
1509
+ border-left-color: #f59e0b;
1510
+ }
1511
+ .piano-row.fail {
1512
+ border-left-color: #f87171;
1513
+ }
1514
+ .piano-note {
1515
+ font-family: ui-monospace, monospace;
1516
+ font-weight: 600;
1517
+ min-width: 28px;
1518
+ font-size: 11px;
1519
+ text-align: right;
1520
+ padding-right: 6px;
1521
+ }
1522
+ .piano-row.pass .piano-note {
1523
+ color: #4ade80;
1524
+ }
1525
+ .piano-row.warn .piano-note {
1526
+ color: #f59e0b;
1527
+ }
1528
+ .piano-row.fail .piano-note {
1529
+ color: #f87171;
1530
+ }
1531
+ .piano-cells {
1532
+ display: flex;
1533
+ gap: 2px;
1534
+ }
1535
+ .piano-cell {
1536
+ width: 14px;
1537
+ height: 14px;
1538
+ border-radius: 2px;
1539
+ cursor: pointer;
1540
+ transition: all 0.1s;
1541
+ }
1542
+ .piano-cell.empty {
1543
+ background: #1a1a2e;
1544
+ }
1545
+ .piano-cell.empty:hover {
1546
+ background: #2a2a4a;
1547
+ }
1548
+ .piano-cell.pass {
1549
+ background: #4ade80;
1550
+ box-shadow: 0 0 4px rgba(74, 222, 128, 0.4);
1551
+ }
1552
+ .piano-cell.pass:hover {
1553
+ transform: scale(1.2);
1554
+ box-shadow: 0 0 8px rgba(74, 222, 128, 0.6);
1555
+ }
1556
+ .piano-cell.fail {
1557
+ background: #f87171;
1558
+ box-shadow: 0 0 4px rgba(248, 113, 113, 0.4);
1559
+ }
1560
+ .piano-cell.fail:hover {
1561
+ transform: scale(1.2);
1562
+ box-shadow: 0 0 8px rgba(248, 113, 113, 0.6);
1563
+ }
1564
+ /* Column highlight on hover */
1565
+ .piano-roll.col-hover .piano-cell[data-col].col-active {
1566
+ filter: brightness(1.3);
1567
+ }
1568
+ .piano-timeline {
1569
+ display: flex;
1570
+ align-items: center;
1571
+ gap: 8px;
1572
+ margin-top: 4px;
1573
+ padding-left: 4px;
1574
+ }
1575
+ .piano-time-markers {
1576
+ display: flex;
1577
+ gap: 2px;
1578
+ }
1579
+ .piano-time-marker {
1580
+ width: 14px;
1581
+ height: 6px;
1582
+ background: #2a2a4a;
1583
+ border-radius: 1px;
1584
+ cursor: pointer;
1585
+ transition: all 0.1s;
1586
+ }
1587
+ .piano-time-marker:hover {
1588
+ background: #a0a0ff;
1589
+ }
1590
+ .piano-time-marker.playing {
1591
+ background: #a0a0ff;
1592
+ animation: piano-marker-pulse 0.3s ease-out;
1593
+ }
1594
+ @keyframes piano-marker-pulse {
1595
+ 0% { transform: scaleY(2); }
1596
+ 100% { transform: scaleY(1); }
1597
+ }
1598
+
1599
+ /* Chord tooltip styles */
1600
+ .chord-trigger {
1601
+ cursor: pointer;
1602
+ display: inline-flex;
1603
+ align-items: center;
1604
+ gap: 6px;
1605
+ padding: 2px 6px;
1606
+ border-radius: 4px;
1607
+ transition: all 0.15s;
1608
+ }
1609
+ .chord-trigger:hover {
1610
+ background: #2a2a4a;
1611
+ }
1612
+ .chord-icon {
1613
+ font-size: 12px;
1614
+ opacity: 0.5;
1615
+ transition: opacity 0.15s;
1616
+ }
1617
+ .chord-trigger:hover .chord-icon {
1618
+ opacity: 1;
1619
+ }
1620
+ .chord-tooltip {
1621
+ position: fixed;
1622
+ z-index: 10000;
1623
+ background: #1a1a2e;
1624
+ border: 1px solid #4a4a6a;
1625
+ border-radius: 8px;
1626
+ padding: 12px;
1627
+ min-width: 280px;
1628
+ max-width: 400px;
1629
+ box-shadow: 0 8px 32px rgba(0,0,0,0.5);
1630
+ animation: chord-fade-in 0.15s ease-out;
1631
+ }
1632
+ @keyframes chord-fade-in {
1633
+ from { opacity: 0; transform: translateY(-8px); }
1634
+ to { opacity: 1; transform: translateY(0); }
1635
+ }
1636
+ .chord-header {
1637
+ display: flex;
1638
+ justify-content: space-between;
1639
+ align-items: center;
1640
+ margin-bottom: 10px;
1641
+ padding-bottom: 8px;
1642
+ border-bottom: 1px solid #3a3a5a;
1643
+ }
1644
+ .chord-title {
1645
+ font-weight: 600;
1646
+ color: #a0a0ff;
1647
+ }
1648
+ .chord-stats {
1649
+ display: flex;
1650
+ gap: 8px;
1651
+ font-size: 12px;
1652
+ }
1653
+ .chord-stats .pass {
1654
+ color: #4ade80;
1655
+ }
1656
+ .chord-stats .fail {
1657
+ color: #f87171;
1658
+ }
1659
+ .chord-notes {
1660
+ display: flex;
1661
+ flex-direction: column;
1662
+ gap: 6px;
1663
+ }
1664
+ .chord-note {
1665
+ display: flex;
1666
+ align-items: center;
1667
+ gap: 8px;
1668
+ padding: 6px 8px;
1669
+ border-radius: 4px;
1670
+ font-size: 12px;
1671
+ }
1672
+ .chord-note.pass {
1673
+ background: #1a3a1a;
1674
+ }
1675
+ .chord-note.fail {
1676
+ background: #3a1a1a;
1677
+ }
1678
+ .note-indicator {
1679
+ font-family: ui-monospace, monospace;
1680
+ font-weight: 600;
1681
+ min-width: 36px;
1682
+ }
1683
+ .chord-note.pass .note-indicator {
1684
+ color: #4ade80;
1685
+ }
1686
+ .chord-note.fail .note-indicator {
1687
+ color: #f87171;
1688
+ }
1689
+ .note-desc {
1690
+ flex: 1;
1691
+ overflow: hidden;
1692
+ text-overflow: ellipsis;
1693
+ white-space: nowrap;
1694
+ color: #e0e0e0;
1695
+ }
1696
+ .note-status {
1697
+ font-size: 14px;
1698
+ }
1699
+ .chord-note.pass .note-status {
1700
+ color: #4ade80;
1701
+ }
1702
+ .chord-note.fail .note-status {
1703
+ color: #f87171;
1704
+ }
1705
+ `;
1706
+ //# sourceMappingURL=styles.js.map