bugpatrol 0.0.1 → 0.1.4

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,1230 @@
1
+ :root {
2
+ --bg: #0f1115;
3
+ --panel: #171a21;
4
+ --panel-2: #1e222b;
5
+ --line: #2a2f3a;
6
+ --fg: #e7e9ee;
7
+ --muted: #9aa3b2;
8
+ --accent: #6ea8fe;
9
+ --critical: #ff6b6b;
10
+ --major: #ffa94d;
11
+ --minor: #ffd43b;
12
+ --cosmetic: #8ce99a;
13
+ --ok: #51cf66;
14
+ --gh-open: #51cf66;
15
+ --gh-merged: #b197fc;
16
+ --gh-closed: #ff6b6b;
17
+ }
18
+ @media (prefers-color-scheme: light) {
19
+ :root {
20
+ --bg: #f6f7f9;
21
+ --panel: #fff;
22
+ --panel-2: #f0f2f6;
23
+ --line: #dfe3ea;
24
+ --fg: #14171c;
25
+ --muted: #5b6270;
26
+ --accent: #2b59d8;
27
+ --gh-open: #237a36;
28
+ --gh-merged: #7042b8;
29
+ --gh-closed: #b73535;
30
+ }
31
+ }
32
+
33
+ * {
34
+ box-sizing: border-box;
35
+ }
36
+ html,
37
+ body {
38
+ height: 100%;
39
+ }
40
+ body {
41
+ margin: 0;
42
+ background: var(--bg);
43
+ color: var(--fg);
44
+ font:
45
+ 14px / 1.55 ui-sans-serif,
46
+ system-ui,
47
+ -apple-system,
48
+ sans-serif;
49
+ }
50
+ button {
51
+ font: inherit;
52
+ color: inherit;
53
+ cursor: pointer;
54
+ }
55
+
56
+ /* ---------- top bar ---------- */
57
+ .topbar {
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 1.25rem;
61
+ padding: 0.6rem 1rem;
62
+ border-bottom: 1px solid var(--line);
63
+ background: var(--panel);
64
+ position: sticky;
65
+ top: 0;
66
+ z-index: 20;
67
+ }
68
+ .brand {
69
+ display: flex;
70
+ align-items: center;
71
+ gap: 0.5rem;
72
+ }
73
+ .mark {
74
+ width: 12px;
75
+ height: 12px;
76
+ border-radius: 3px;
77
+ background: var(--accent);
78
+ }
79
+ .tabs {
80
+ display: flex;
81
+ gap: 0.25rem;
82
+ }
83
+ .tabs button {
84
+ background: transparent;
85
+ border: 1px solid transparent;
86
+ border-radius: 6px;
87
+ padding: 0.3rem 0.7rem;
88
+ color: var(--muted);
89
+ }
90
+ .tabs button:hover {
91
+ color: var(--fg);
92
+ }
93
+ .tabs button.active {
94
+ background: var(--panel-2);
95
+ border-color: var(--line);
96
+ color: var(--fg);
97
+ }
98
+ .status {
99
+ margin-left: auto;
100
+ display: flex;
101
+ align-items: center;
102
+ gap: 0.75rem;
103
+ font-size: 0.8rem;
104
+ }
105
+ .live {
106
+ display: inline-flex;
107
+ align-items: center;
108
+ gap: 0.35rem;
109
+ color: var(--ok);
110
+ font-size: 0.72rem;
111
+ text-transform: uppercase;
112
+ letter-spacing: 0.04em;
113
+ }
114
+ .live::before {
115
+ content: "";
116
+ width: 7px;
117
+ height: 7px;
118
+ border-radius: 50%;
119
+ background: var(--ok);
120
+ }
121
+ .live.stale {
122
+ color: var(--muted);
123
+ }
124
+ .live.stale::before {
125
+ background: var(--muted);
126
+ }
127
+ .muted {
128
+ color: var(--muted);
129
+ }
130
+
131
+ main {
132
+ padding: 1rem;
133
+ }
134
+
135
+ /* ---------- generic ---------- */
136
+ .empty {
137
+ color: var(--muted);
138
+ padding: 3rem 1rem;
139
+ text-align: center;
140
+ }
141
+ .empty code {
142
+ background: var(--panel-2);
143
+ padding: 0.15rem 0.4rem;
144
+ border-radius: 4px;
145
+ }
146
+ .card {
147
+ background: var(--panel);
148
+ border: 1px solid var(--line);
149
+ border-radius: 10px;
150
+ }
151
+ h2 {
152
+ font-size: 0.95rem;
153
+ margin: 0 0 0.6rem;
154
+ }
155
+ h3 {
156
+ font-size: 0.85rem;
157
+ margin: 0 0 0.4rem;
158
+ }
159
+ code,
160
+ .mono {
161
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
162
+ font-size: 0.82em;
163
+ }
164
+
165
+ .badge {
166
+ display: inline-block;
167
+ padding: 0.08rem 0.45rem;
168
+ border-radius: 999px;
169
+ font-size: 0.7rem;
170
+ font-weight: 600;
171
+ letter-spacing: 0.02em;
172
+ }
173
+ .badge.fail {
174
+ background: var(--critical);
175
+ color: #fff;
176
+ }
177
+ .badge.pass {
178
+ background: var(--ok);
179
+ color: #05270d;
180
+ }
181
+ .badge.warn {
182
+ background: var(--major);
183
+ color: #2a1600;
184
+ }
185
+ .badge.info {
186
+ background: var(--panel-2);
187
+ color: var(--muted);
188
+ border: 1px solid var(--line);
189
+ }
190
+ .gh-chip {
191
+ display: inline-flex;
192
+ flex: none;
193
+ align-items: center;
194
+ border: 1px solid currentColor;
195
+ border-radius: 999px;
196
+ padding: 0.08rem 0.45rem;
197
+ font-size: 0.7rem;
198
+ text-decoration: none;
199
+ white-space: nowrap;
200
+ color: var(--muted);
201
+ }
202
+ .gh-chip:hover {
203
+ text-decoration: underline;
204
+ }
205
+ .gh-open {
206
+ color: var(--gh-open);
207
+ }
208
+ .gh-merged {
209
+ color: var(--gh-merged);
210
+ }
211
+ .gh-closed {
212
+ color: var(--gh-closed);
213
+ }
214
+ .gh-chip.ci-failed,
215
+ .gh-chip.ci-gave-up {
216
+ color: var(--gh-closed);
217
+ }
218
+ .github-summary {
219
+ font-size: 0.8rem;
220
+ margin-bottom: 0.75rem;
221
+ }
222
+
223
+ .sev-critical {
224
+ --sev: var(--critical);
225
+ }
226
+ .sev-major {
227
+ --sev: var(--major);
228
+ }
229
+ .sev-minor {
230
+ --sev: var(--minor);
231
+ }
232
+ .sev-cosmetic {
233
+ --sev: var(--cosmetic);
234
+ }
235
+
236
+ /* ---------- runs list ---------- */
237
+ .layout {
238
+ display: grid;
239
+ grid-template-columns: 300px 1fr;
240
+ gap: 1rem;
241
+ align-items: start;
242
+ }
243
+ @media (max-width: 900px) {
244
+ .layout {
245
+ grid-template-columns: 1fr;
246
+ }
247
+ }
248
+
249
+ .runlist {
250
+ padding: 0.4rem;
251
+ max-height: calc(100vh - 6rem);
252
+ overflow: auto;
253
+ }
254
+ .runitem {
255
+ display: block;
256
+ width: 100%;
257
+ text-align: left;
258
+ background: transparent;
259
+ border: 1px solid transparent;
260
+ border-radius: 8px;
261
+ padding: 0.55rem 0.6rem;
262
+ margin-bottom: 0.2rem;
263
+ }
264
+ .runitem:hover {
265
+ background: var(--panel-2);
266
+ }
267
+ .runitem.active {
268
+ background: var(--panel-2);
269
+ border-color: var(--accent);
270
+ }
271
+ .runitem .row {
272
+ display: flex;
273
+ align-items: center;
274
+ gap: 0.4rem;
275
+ }
276
+ .runitem .when {
277
+ color: var(--muted);
278
+ font-size: 0.75rem;
279
+ margin-top: 0.15rem;
280
+ }
281
+
282
+ /* ---------- run detail ---------- */
283
+ .detail {
284
+ padding: 1rem 1.1rem;
285
+ }
286
+ .kv {
287
+ display: flex;
288
+ flex-wrap: wrap;
289
+ gap: 0.4rem 1.25rem;
290
+ color: var(--muted);
291
+ font-size: 0.8rem;
292
+ margin-bottom: 0.9rem;
293
+ }
294
+ .notes {
295
+ margin: 0 0 1rem;
296
+ padding: 0.6rem 0.8rem;
297
+ background: var(--panel-2);
298
+ border-left: 3px solid var(--accent);
299
+ border-radius: 0 6px 6px 0;
300
+ }
301
+ .notes p {
302
+ margin: 0.2rem 0;
303
+ font-size: 0.82rem;
304
+ color: var(--muted);
305
+ }
306
+
307
+ .screen {
308
+ border-top: 1px solid var(--line);
309
+ padding: 1rem 0;
310
+ }
311
+ .screen:first-of-type {
312
+ border-top: 0;
313
+ }
314
+ .screen-head {
315
+ display: flex;
316
+ align-items: baseline;
317
+ gap: 0.6rem;
318
+ flex-wrap: wrap;
319
+ margin-bottom: 0.6rem;
320
+ }
321
+ .screen-head .vp {
322
+ color: var(--muted);
323
+ font-size: 0.78rem;
324
+ }
325
+
326
+ .shots {
327
+ display: grid;
328
+ grid-template-columns: repeat(3, 1fr);
329
+ gap: 0.5rem;
330
+ margin: 0.5rem 0 0.8rem;
331
+ }
332
+ .shots figure {
333
+ margin: 0;
334
+ }
335
+ .shots img {
336
+ width: 100%;
337
+ display: block;
338
+ border: 1px solid var(--line);
339
+ border-radius: 6px;
340
+ background: var(--panel-2);
341
+ cursor: zoom-in;
342
+ max-height: 260px;
343
+ object-fit: cover;
344
+ object-position: top;
345
+ }
346
+ .shots figcaption {
347
+ color: var(--muted);
348
+ font-size: 0.72rem;
349
+ text-align: center;
350
+ margin-top: 0.25rem;
351
+ }
352
+
353
+ .checks {
354
+ display: flex;
355
+ flex-wrap: wrap;
356
+ gap: 0.3rem;
357
+ margin: 0.5rem 0;
358
+ }
359
+ .chk {
360
+ font-size: 0.72rem;
361
+ padding: 0.1rem 0.45rem;
362
+ border-radius: 4px;
363
+ border: 1px solid var(--line);
364
+ color: var(--muted);
365
+ background: var(--panel-2);
366
+ }
367
+ .chk.fired {
368
+ border-color: var(--sev, var(--major));
369
+ color: var(--fg);
370
+ background: color-mix(in srgb, var(--sev, var(--major)) 18%, transparent);
371
+ }
372
+
373
+ .finding {
374
+ border-left: 3px solid var(--sev, var(--line));
375
+ background: var(--panel-2);
376
+ border-radius: 0 8px 8px 0;
377
+ padding: 0.6rem 0.8rem;
378
+ margin: 0.45rem 0;
379
+ }
380
+ .finding .why {
381
+ color: var(--muted);
382
+ font-size: 0.78rem;
383
+ margin-top: 0.3rem;
384
+ }
385
+ .finding .meta {
386
+ color: var(--muted);
387
+ font-size: 0.72rem;
388
+ margin-top: 0.25rem;
389
+ }
390
+
391
+ .reasoning {
392
+ margin-top: 0.6rem;
393
+ }
394
+ .reasoning summary {
395
+ cursor: pointer;
396
+ color: var(--muted);
397
+ font-size: 0.78rem;
398
+ }
399
+ .reasoning table {
400
+ width: 100%;
401
+ border-collapse: collapse;
402
+ margin-top: 0.4rem;
403
+ font-size: 0.78rem;
404
+ }
405
+ .reasoning td {
406
+ padding: 0.2rem 0.4rem;
407
+ border-bottom: 1px solid var(--line);
408
+ vertical-align: top;
409
+ }
410
+ .reasoning td:first-child {
411
+ color: var(--muted);
412
+ white-space: nowrap;
413
+ width: 1%;
414
+ }
415
+
416
+ /* ---------- lightbox ---------- */
417
+ .lightbox {
418
+ position: fixed;
419
+ inset: 0;
420
+ background: rgba(0, 0, 0, 0.85);
421
+ z-index: 50;
422
+ display: flex;
423
+ flex-direction: column;
424
+ align-items: center;
425
+ justify-content: center;
426
+ gap: 0.75rem;
427
+ padding: 2rem;
428
+ }
429
+ /* `display: flex` above outranks the UA rule for [hidden], so without this the
430
+ closed lightbox stays a full-screen transparent overlay that swallows every
431
+ click -- the "the button does nothing" bug, in our own UI. */
432
+ .lightbox[hidden] {
433
+ display: none;
434
+ }
435
+ .lightbox img {
436
+ max-width: 95vw;
437
+ max-height: 85vh;
438
+ object-fit: contain;
439
+ border-radius: 6px;
440
+ }
441
+ .lightbox p {
442
+ color: #ddd;
443
+ font-size: 0.8rem;
444
+ margin: 0;
445
+ }
446
+ .lightbox-close {
447
+ position: absolute;
448
+ top: 1rem;
449
+ right: 1.25rem;
450
+ background: transparent;
451
+ border: 0;
452
+ color: #fff;
453
+ font-size: 2rem;
454
+ line-height: 1;
455
+ }
456
+
457
+ /* ---------- live run banner ---------- */
458
+ .runbanner {
459
+ display: flex;
460
+ align-items: center;
461
+ gap: 0.6rem;
462
+ margin-bottom: 0.75rem;
463
+ padding: 0.5rem 0.75rem;
464
+ border-radius: 8px;
465
+ font-size: 0.82rem;
466
+ background: color-mix(in srgb, var(--accent) 14%, transparent);
467
+ border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
468
+ }
469
+ .spinner {
470
+ width: 11px;
471
+ height: 11px;
472
+ border-radius: 50%;
473
+ flex: none;
474
+ border: 2px solid color-mix(in srgb, var(--accent) 35%, transparent);
475
+ border-top-color: var(--accent);
476
+ animation: spin 0.8s linear infinite;
477
+ }
478
+ @keyframes spin {
479
+ to {
480
+ transform: rotate(360deg);
481
+ }
482
+ }
483
+ @media (prefers-reduced-motion: reduce) {
484
+ .spinner {
485
+ animation: none;
486
+ }
487
+ }
488
+
489
+ /* ---------- grouped findings ---------- */
490
+ .finding .members {
491
+ margin-top: 0.35rem;
492
+ }
493
+ .finding .members summary {
494
+ cursor: pointer;
495
+ color: var(--muted);
496
+ font-size: 0.75rem;
497
+ }
498
+ .finding .members ul {
499
+ margin: 0.35rem 0 0;
500
+ padding-left: 1.1rem;
501
+ max-height: 220px;
502
+ overflow: auto;
503
+ }
504
+ .finding .members li {
505
+ font-size: 0.72rem;
506
+ color: var(--muted);
507
+ margin: 0.1rem 0;
508
+ }
509
+
510
+ /* Agent views keep the same visual hierarchy in light and dark schemes. */
511
+ :root {
512
+ --cosmetic: #8e949d;
513
+ }
514
+ main {
515
+ max-width: 1600px;
516
+ margin: auto;
517
+ padding: 1.25rem;
518
+ }
519
+ h1 {
520
+ font-size: 1.35rem;
521
+ line-height: 1.25;
522
+ margin: 0;
523
+ }
524
+ .topbar {
525
+ min-height: 56px;
526
+ }
527
+ .status {
528
+ white-space: nowrap;
529
+ }
530
+ .pill {
531
+ border: 1px solid var(--line);
532
+ border-radius: 999px;
533
+ padding: 0.15rem 0.6rem;
534
+ color: var(--muted);
535
+ }
536
+ .pill.running {
537
+ color: var(--accent);
538
+ border-color: var(--accent);
539
+ }
540
+ .live {
541
+ font-size: 0;
542
+ }
543
+ .live::before {
544
+ background: var(--muted);
545
+ }
546
+ .live.working::before {
547
+ background: var(--ok);
548
+ animation: pulse 1.5s infinite;
549
+ }
550
+ @keyframes pulse {
551
+ 50% {
552
+ opacity: 0.3;
553
+ }
554
+ }
555
+ @media (prefers-reduced-motion: reduce) {
556
+ .live.working::before,
557
+ .state-dot.working {
558
+ animation: none;
559
+ }
560
+ }
561
+ .agent-grid {
562
+ display: grid;
563
+ grid-template-columns: repeat(3, minmax(0, 1fr));
564
+ gap: 0.85rem;
565
+ margin-bottom: 0.85rem;
566
+ }
567
+ .agent-card,
568
+ .panel {
569
+ padding: 1rem;
570
+ }
571
+ .agent-card p {
572
+ margin: 0.75rem 0;
573
+ min-height: 1.4em;
574
+ }
575
+ .agent-head,
576
+ .section-title,
577
+ .detail-heading {
578
+ display: flex;
579
+ align-items: center;
580
+ gap: 0.55rem;
581
+ }
582
+ .agent-head .state-dot {
583
+ margin-left: auto;
584
+ }
585
+ .role-icon {
586
+ display: inline-flex;
587
+ width: 18px;
588
+ height: 18px;
589
+ flex: none;
590
+ color: var(--accent);
591
+ }
592
+ .role-icon svg {
593
+ width: 100%;
594
+ height: 100%;
595
+ }
596
+ .state-dot {
597
+ width: 8px;
598
+ height: 8px;
599
+ border-radius: 50%;
600
+ background: var(--muted);
601
+ }
602
+ .state-dot.working {
603
+ background: var(--accent);
604
+ animation: pulse 1.5s infinite;
605
+ }
606
+ .state-dot.idle,
607
+ .state-dot.waiting {
608
+ background: var(--ok);
609
+ }
610
+ .state-dot.failed {
611
+ background: var(--critical);
612
+ }
613
+ .section-title {
614
+ justify-content: space-between;
615
+ margin-bottom: 0.75rem;
616
+ }
617
+ .section-title h2 {
618
+ margin: 0;
619
+ font-size: 1rem;
620
+ }
621
+ .overview-grid {
622
+ display: grid;
623
+ grid-template-columns: minmax(0, 1.6fr) minmax(300px, 1fr);
624
+ gap: 0.85rem;
625
+ }
626
+ .coverage {
627
+ margin-top: 0.85rem;
628
+ }
629
+ .usage {
630
+ margin-top: 0.85rem;
631
+ overflow-x: auto;
632
+ }
633
+ .usage-table {
634
+ width: 100%;
635
+ border-collapse: collapse;
636
+ font-size: 0.82rem;
637
+ }
638
+ .usage-table th {
639
+ text-align: left;
640
+ font-weight: 600;
641
+ color: var(--muted, #64748b);
642
+ padding: 0.35rem 0.5rem;
643
+ border-bottom: 1px solid var(--line, #e2e8f0);
644
+ }
645
+ .usage-table td {
646
+ padding: 0.35rem 0.5rem;
647
+ border-bottom: 1px solid var(--line, #e2e8f0);
648
+ font-variant-numeric: tabular-nums;
649
+ }
650
+ .session-usage {
651
+ margin: 0.35rem 0 0.6rem;
652
+ font-size: 0.8rem;
653
+ }
654
+ .token-chip {
655
+ white-space: nowrap;
656
+ font-variant-numeric: tabular-nums;
657
+ }
658
+ .stack,
659
+ .event-list {
660
+ display: flex;
661
+ flex-direction: column;
662
+ }
663
+ .attention-row,
664
+ .list-row {
665
+ display: flex;
666
+ align-items: center;
667
+ width: 100%;
668
+ gap: 0.7rem;
669
+ text-align: left;
670
+ background: transparent;
671
+ border: 0;
672
+ border-top: 1px solid var(--line);
673
+ padding: 0.65rem 0.2rem;
674
+ }
675
+ .attention-row:hover,
676
+ .list-row:hover,
677
+ .list-row.active {
678
+ background: var(--panel-2);
679
+ }
680
+ .grow {
681
+ flex: 1;
682
+ min-width: 0;
683
+ }
684
+ .attention-row strong,
685
+ .list-row strong {
686
+ display: block;
687
+ font-weight: 600;
688
+ }
689
+ .attention-row small,
690
+ .list-row small {
691
+ display: block;
692
+ }
693
+ .thumb,
694
+ .event-thumb {
695
+ width: 48px;
696
+ height: 42px;
697
+ border-radius: 5px;
698
+ object-fit: cover;
699
+ background: var(--panel-2);
700
+ flex: none;
701
+ }
702
+ .severity {
703
+ border-radius: 999px;
704
+ padding: 0.12rem 0.5rem;
705
+ font-size: 0.72rem;
706
+ font-weight: 650;
707
+ text-transform: capitalize;
708
+ white-space: nowrap;
709
+ }
710
+ .severity-critical {
711
+ background: #b93038;
712
+ color: white;
713
+ }
714
+ .severity-major {
715
+ background: #ae551c;
716
+ color: white;
717
+ }
718
+ .severity-minor {
719
+ background: #f0d36a;
720
+ color: #302600;
721
+ }
722
+ .severity-cosmetic {
723
+ background: #737983;
724
+ color: white;
725
+ }
726
+ .live-shot {
727
+ width: 100%;
728
+ height: 230px;
729
+ object-fit: contain;
730
+ background: var(--panel-2);
731
+ border-radius: 6px;
732
+ }
733
+ .image-empty {
734
+ background: var(--panel-2);
735
+ color: var(--muted);
736
+ display: grid;
737
+ place-items: center;
738
+ }
739
+ .event-row {
740
+ display: flex;
741
+ align-items: center;
742
+ gap: 0.5rem;
743
+ border-top: 1px solid var(--line);
744
+ padding: 0.4rem 0;
745
+ min-width: 0;
746
+ }
747
+ .event-row time {
748
+ color: var(--muted);
749
+ font-size: 0.75rem;
750
+ white-space: nowrap;
751
+ }
752
+ .event-row details {
753
+ flex: none;
754
+ font-size: 0.75rem;
755
+ }
756
+ .event-row details[open] {
757
+ max-width: 45%;
758
+ }
759
+ .event-row pre {
760
+ white-space: pre-wrap;
761
+ overflow-wrap: anywhere;
762
+ }
763
+ .truncate {
764
+ overflow: hidden;
765
+ text-overflow: ellipsis;
766
+ white-space: nowrap;
767
+ }
768
+ .quiet {
769
+ color: var(--muted);
770
+ }
771
+ .coverage-row {
772
+ display: flex;
773
+ gap: 0.65rem;
774
+ overflow-x: auto;
775
+ }
776
+ .coverage-item {
777
+ width: 136px;
778
+ flex: none;
779
+ background: transparent;
780
+ border: 0;
781
+ color: var(--fg);
782
+ text-align: left;
783
+ padding: 0;
784
+ }
785
+ .coverage-item img,
786
+ .coverage-item .image-empty {
787
+ width: 136px;
788
+ height: 80px;
789
+ object-fit: cover;
790
+ border-radius: 6px;
791
+ }
792
+ .coverage-item span {
793
+ display: block;
794
+ overflow: hidden;
795
+ text-overflow: ellipsis;
796
+ white-space: nowrap;
797
+ }
798
+ .master-detail {
799
+ display: grid;
800
+ grid-template-columns: minmax(260px, 350px) minmax(0, 1fr);
801
+ gap: 0.85rem;
802
+ align-items: start;
803
+ }
804
+ .filters {
805
+ display: flex;
806
+ gap: 0.3rem;
807
+ flex-wrap: wrap;
808
+ margin-bottom: 0.6rem;
809
+ }
810
+ .filter {
811
+ background: transparent;
812
+ border: 1px solid var(--line);
813
+ border-radius: 999px;
814
+ padding: 0.17rem 0.5rem;
815
+ color: var(--muted);
816
+ font-size: 0.8rem;
817
+ }
818
+ .filter.active {
819
+ border-color: var(--accent);
820
+ color: var(--fg);
821
+ background: var(--panel-2);
822
+ }
823
+ .detail-heading {
824
+ justify-content: space-between;
825
+ align-items: flex-start;
826
+ margin-bottom: 0.75rem;
827
+ }
828
+ /* A grid item grows to its widest child; a long diff line must scroll in its
829
+ own block, not widen the page. */
830
+ .master-detail > * {
831
+ min-width: 0;
832
+ }
833
+ .issue-detail .section-title {
834
+ margin-top: 1.2rem;
835
+ }
836
+ .issue-detail .kv {
837
+ margin-bottom: 1rem;
838
+ }
839
+ .markdown p {
840
+ margin: 0.5rem 0;
841
+ }
842
+ .markdown pre,
843
+ .diff-block,
844
+ .fix pre {
845
+ background: var(--panel-2);
846
+ border-radius: 6px;
847
+ padding: 0.6rem;
848
+ overflow: auto;
849
+ font-size: 0.75rem;
850
+ }
851
+ .evidence-grid {
852
+ display: grid;
853
+ grid-template-columns: repeat(3, minmax(0, 1fr));
854
+ gap: 0.5rem;
855
+ }
856
+ .evidence-grid figure {
857
+ margin: 0;
858
+ }
859
+ .evidence-grid img {
860
+ width: 100%;
861
+ height: 180px;
862
+ object-fit: contain;
863
+ background: var(--panel-2);
864
+ cursor: zoom-in;
865
+ }
866
+ .evidence-grid figcaption {
867
+ color: var(--muted);
868
+ text-align: center;
869
+ font-size: 0.75rem;
870
+ }
871
+ .diff-file {
872
+ border: 1px solid var(--line);
873
+ border-radius: 6px;
874
+ margin: 0.6rem 0;
875
+ overflow: hidden;
876
+ }
877
+ .diff-file h3 {
878
+ padding: 0.5rem 0.6rem;
879
+ margin: 0;
880
+ background: var(--panel-2);
881
+ overflow-wrap: anywhere;
882
+ }
883
+ .diff-block {
884
+ margin: 0;
885
+ border-radius: 0;
886
+ }
887
+ .diff-block span {
888
+ display: block;
889
+ min-height: 1em;
890
+ white-space: pre;
891
+ }
892
+ .diff-block .added {
893
+ background: color-mix(in srgb, var(--ok) 18%, transparent);
894
+ }
895
+ .diff-block .removed {
896
+ background: color-mix(in srgb, var(--critical) 18%, transparent);
897
+ }
898
+ .diff-block .hunk {
899
+ color: var(--muted);
900
+ }
901
+ .retest-block {
902
+ border-top: 1px solid var(--line);
903
+ padding: 0.75rem 0;
904
+ }
905
+ .retest-block p {
906
+ margin: 0.35rem 0;
907
+ }
908
+ .retest-shot-pair {
909
+ margin: 0.7rem 0;
910
+ }
911
+ .retest-shot-pair h4 {
912
+ font-size: 0.85rem;
913
+ margin: 0 0 0.25rem;
914
+ }
915
+ .retest-shots {
916
+ display: grid;
917
+ grid-template-columns: repeat(2, minmax(0, 1fr));
918
+ gap: 0.6rem;
919
+ }
920
+ .retest-shots figure {
921
+ margin: 0;
922
+ min-width: 0;
923
+ }
924
+ .retest-shots img,
925
+ .retest-shots .image-empty {
926
+ width: 100%;
927
+ height: 220px;
928
+ object-fit: contain;
929
+ background: var(--panel-2);
930
+ cursor: zoom-in;
931
+ }
932
+ .retest-shots figcaption {
933
+ text-align: center;
934
+ color: var(--muted);
935
+ font-size: 0.75rem;
936
+ }
937
+ .earlier-retests summary {
938
+ cursor: pointer;
939
+ color: var(--muted);
940
+ }
941
+ @media (max-width: 600px) {
942
+ .retest-shots {
943
+ grid-template-columns: 1fr;
944
+ }
945
+ }
946
+ .toggle {
947
+ display: flex;
948
+ align-items: center;
949
+ gap: 0.4rem;
950
+ margin-bottom: 0.5rem;
951
+ }
952
+ .candidate {
953
+ display: flex;
954
+ justify-content: space-between;
955
+ gap: 0.5rem;
956
+ border-top: 1px solid var(--line);
957
+ padding: 0.5rem 0;
958
+ }
959
+ .screen-grid {
960
+ display: grid;
961
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
962
+ gap: 0.85rem;
963
+ }
964
+ .screen-card {
965
+ text-align: left;
966
+ padding: 0;
967
+ overflow: hidden;
968
+ }
969
+ .screen-card:hover {
970
+ border-color: var(--accent);
971
+ }
972
+ .screen-card > img,
973
+ .screen-card > .image-empty {
974
+ display: block;
975
+ width: 100%;
976
+ height: 145px;
977
+ object-fit: cover;
978
+ }
979
+ .screen-copy {
980
+ padding: 0.75rem;
981
+ }
982
+ .screen-copy p {
983
+ margin: 0.2rem 0;
984
+ }
985
+ .issue-count {
986
+ float: right;
987
+ color: var(--major);
988
+ font-size: 0.75rem;
989
+ }
990
+ .screen-large {
991
+ width: 100%;
992
+ max-height: 520px;
993
+ object-fit: contain;
994
+ background: var(--panel-2);
995
+ }
996
+ .back {
997
+ border: 0;
998
+ background: transparent;
999
+ color: var(--accent);
1000
+ padding: 0 0 0.7rem;
1001
+ }
1002
+ .screen-mode {
1003
+ display: inline-flex;
1004
+ margin: 0.5rem 0 0.75rem;
1005
+ border: 1px solid var(--line);
1006
+ border-radius: 7px;
1007
+ overflow: hidden;
1008
+ }
1009
+ .screen-mode button {
1010
+ border: 0;
1011
+ background: var(--panel);
1012
+ padding: 0.25rem 0.8rem;
1013
+ }
1014
+ .screen-mode button.active {
1015
+ background: var(--accent);
1016
+ color: var(--bg);
1017
+ }
1018
+ .graph-wrap {
1019
+ min-width: 0;
1020
+ width: 100%;
1021
+ }
1022
+ .graph-toolbar {
1023
+ display: flex;
1024
+ align-items: center;
1025
+ gap: 0.35rem;
1026
+ flex-wrap: wrap;
1027
+ }
1028
+ .graph-toolbar button {
1029
+ border: 1px solid var(--line);
1030
+ border-radius: 5px;
1031
+ background: var(--panel);
1032
+ padding: 0.15rem 0.55rem;
1033
+ }
1034
+ .graph-toolbar label {
1035
+ margin-left: 0.5rem;
1036
+ color: var(--muted);
1037
+ }
1038
+ .graph-legend {
1039
+ color: var(--muted);
1040
+ font-size: 0.75rem;
1041
+ margin: 0.45rem 0;
1042
+ }
1043
+ .screen-graph {
1044
+ display: block;
1045
+ width: 100%;
1046
+ height: min(70vh, 700px);
1047
+ min-height: 420px;
1048
+ background: var(--panel);
1049
+ border: 1px solid var(--line);
1050
+ border-radius: 8px;
1051
+ touch-action: none;
1052
+ cursor: grab;
1053
+ }
1054
+ .screen-graph:active {
1055
+ cursor: grabbing;
1056
+ }
1057
+ .graph-edge {
1058
+ fill: none;
1059
+ stroke: var(--accent);
1060
+ opacity: 0.7;
1061
+ pointer-events: stroke;
1062
+ }
1063
+ .graph-edge.open {
1064
+ stroke-dasharray: 7 5;
1065
+ }
1066
+ .graph-edge.route {
1067
+ stroke: var(--muted);
1068
+ opacity: 0.6;
1069
+ }
1070
+ .graph-edge.other {
1071
+ stroke: var(--muted);
1072
+ opacity: 0.45;
1073
+ }
1074
+ .graph-edge.back {
1075
+ stroke: var(--muted);
1076
+ stroke-dasharray: 3 5;
1077
+ opacity: 0.45;
1078
+ }
1079
+ .graph-edge.faded {
1080
+ opacity: 0.08;
1081
+ }
1082
+ #graph-arrow path {
1083
+ fill: var(--accent);
1084
+ }
1085
+ #graph-arrow-muted path {
1086
+ fill: var(--muted);
1087
+ }
1088
+ .graph-card {
1089
+ fill: var(--panel-2);
1090
+ stroke: var(--line);
1091
+ }
1092
+ .graph-start rect {
1093
+ fill: var(--panel-2);
1094
+ stroke: var(--accent);
1095
+ }
1096
+ .graph-start text {
1097
+ fill: var(--fg);
1098
+ font-size: 13px;
1099
+ font-weight: 650;
1100
+ }
1101
+ .graph-node {
1102
+ cursor: pointer;
1103
+ }
1104
+ .graph-node:hover .graph-card,
1105
+ .graph-node:focus .graph-card {
1106
+ stroke: var(--accent);
1107
+ stroke-width: 2;
1108
+ }
1109
+ .graph-name,
1110
+ .graph-unlinked {
1111
+ fill: var(--fg);
1112
+ font-size: 14px;
1113
+ font-weight: 600;
1114
+ }
1115
+ .graph-unlinked {
1116
+ fill: var(--muted);
1117
+ }
1118
+ .graph-issue {
1119
+ fill: var(--critical);
1120
+ }
1121
+ .graph-issue-text {
1122
+ fill: white;
1123
+ font-size: 12px;
1124
+ font-weight: 700;
1125
+ }
1126
+ .screen-links {
1127
+ margin: 0.8rem 0;
1128
+ }
1129
+ .screen-links .list-row {
1130
+ display: flex;
1131
+ justify-content: space-between;
1132
+ }
1133
+ @media (max-width: 900px) {
1134
+ .topbar {
1135
+ flex-wrap: wrap;
1136
+ }
1137
+ .status {
1138
+ margin-left: 0;
1139
+ }
1140
+ .overview-grid,
1141
+ .master-detail {
1142
+ grid-template-columns: 1fr;
1143
+ }
1144
+ }
1145
+ @media (max-width: 600px) {
1146
+ main {
1147
+ min-width: 0;
1148
+ overflow-x: hidden;
1149
+ }
1150
+ .screen-graph {
1151
+ height: 60vh;
1152
+ min-height: 360px;
1153
+ }
1154
+ .agent-grid {
1155
+ grid-template-columns: 1fr;
1156
+ }
1157
+ .tabs {
1158
+ overflow-x: auto;
1159
+ width: 100%;
1160
+ order: 3;
1161
+ }
1162
+ .attention-row {
1163
+ flex-wrap: wrap;
1164
+ }
1165
+ }
1166
+ .viewport-tags {
1167
+ display: flex;
1168
+ gap: 0.3rem;
1169
+ margin-top: 0.4rem;
1170
+ }
1171
+ .viewport-tags span {
1172
+ border: 1px solid var(--line);
1173
+ border-radius: 4px;
1174
+ padding: 0 0.35rem;
1175
+ color: var(--muted);
1176
+ font-size: 0.72rem;
1177
+ }
1178
+
1179
+ /* The replayable path behind an issue: exact, but one click away. */
1180
+ .recorded-path {
1181
+ margin: 16px 0;
1182
+ }
1183
+ .recorded-path summary {
1184
+ cursor: pointer;
1185
+ color: var(--muted, #6b7280);
1186
+ font-weight: 600;
1187
+ }
1188
+ .recorded-path ol {
1189
+ margin-top: 8px;
1190
+ }
1191
+
1192
+ /* A long agent summary reads as a note under the timeline title. */
1193
+ .session-summary {
1194
+ margin: 4px 0 12px;
1195
+ color: var(--muted, #6b7280);
1196
+ font-size: 13px;
1197
+ }
1198
+
1199
+ .diff-details summary {
1200
+ cursor: pointer;
1201
+ color: var(--muted);
1202
+ margin: 0.4rem 0;
1203
+ }
1204
+ .memory-group {
1205
+ margin: 1rem 0;
1206
+ }
1207
+ .memory-row {
1208
+ display: flex;
1209
+ align-items: center;
1210
+ gap: 0.75rem;
1211
+ border-top: 1px solid var(--line);
1212
+ padding: 0.45rem 0;
1213
+ }
1214
+ .memory-row .muted {
1215
+ font-size: 0.75rem;
1216
+ white-space: nowrap;
1217
+ }
1218
+ @media (max-width: 600px) {
1219
+ .memory-row {
1220
+ flex-wrap: wrap;
1221
+ }
1222
+ }
1223
+
1224
+ .row-meta {
1225
+ display: flex;
1226
+ flex-wrap: wrap;
1227
+ align-items: center;
1228
+ gap: 0.35rem 0.5rem;
1229
+ margin-top: 0.2rem;
1230
+ }