@worca/ui 0.40.0 → 0.42.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.
package/app/styles.css CHANGED
@@ -155,15 +155,50 @@ h1, h2, h3, h4, h5, h6 {
155
155
  }
156
156
 
157
157
  .sidebar.collapsed .sidebar-section-header,
158
- .sidebar.collapsed .sidebar-item span,
158
+ /* `.sidebar-item-left > span` targets only label spans — the outer
159
+ `.sidebar-item-left` is itself a span and would have been swept up
160
+ by the broader `.sidebar-item span` selector, hiding the icon too. */
161
+ .sidebar.collapsed .sidebar-item-left > span,
159
162
  .sidebar.collapsed .conn-label,
160
- .sidebar.collapsed .logo-text {
163
+ .sidebar.collapsed .logo-text,
164
+ .sidebar.collapsed .sidebar-project-section,
165
+ .sidebar.collapsed .sidebar-new-run-chevron-dropdown {
161
166
  display: none;
162
167
  }
163
168
 
169
+ /* In the collapsed rail, nav items become icon-only — center them so they
170
+ sit under the toggle button rather than floating against the left edge. */
171
+ .sidebar.collapsed .sidebar-item {
172
+ justify-content: center;
173
+ margin: 2px 6px;
174
+ padding: 8px 6px;
175
+ }
176
+ .sidebar.collapsed .sidebar-item-left {
177
+ gap: 0;
178
+ }
179
+ .sidebar.collapsed .sidebar-new-run {
180
+ padding: 4px 6px;
181
+ }
182
+ .sidebar.collapsed .sidebar-new-run-split {
183
+ width: auto;
184
+ }
185
+ .sidebar.collapsed .sidebar-footer {
186
+ justify-content: center;
187
+ padding: 12px 6px;
188
+ }
189
+
164
190
  .sidebar-logo {
165
- padding: 20px 16px 12px;
191
+ padding: 16px 12px 12px 16px;
166
192
  border-bottom: 1px solid var(--border-subtle);
193
+ display: flex;
194
+ align-items: center;
195
+ justify-content: space-between;
196
+ gap: 8px;
197
+ }
198
+
199
+ .sidebar.collapsed .sidebar-logo {
200
+ justify-content: center;
201
+ padding: 16px 6px 12px;
167
202
  }
168
203
 
169
204
  .logo-text {
@@ -174,6 +209,35 @@ h1, h2, h3, h4, h5, h6 {
174
209
  color: var(--fg);
175
210
  }
176
211
 
212
+ .sidebar-toggle-btn {
213
+ display: inline-flex;
214
+ align-items: center;
215
+ justify-content: center;
216
+ width: 28px;
217
+ height: 28px;
218
+ padding: 0;
219
+ border: 1px solid transparent;
220
+ border-radius: var(--radius);
221
+ background: transparent;
222
+ color: var(--muted);
223
+ cursor: pointer;
224
+ flex-shrink: 0;
225
+ transition:
226
+ background var(--transition-fast),
227
+ color var(--transition-fast),
228
+ border-color var(--transition-fast);
229
+ }
230
+
231
+ .sidebar-toggle-btn:hover {
232
+ background: var(--border);
233
+ color: var(--fg);
234
+ }
235
+
236
+ .sidebar-toggle-btn:focus-visible {
237
+ outline: none;
238
+ border-color: var(--accent);
239
+ }
240
+
177
241
  /* --- 6. Sidebar Sections --- */
178
242
  .sidebar-section {
179
243
  padding: 8px 0;
@@ -410,709 +474,1264 @@ h1, h2, h3, h4, h5, h6 {
410
474
  color: #ffffff;
411
475
  }
412
476
 
477
+ .action-btn--ghost {
478
+ border-color: transparent;
479
+ color: var(--text-muted);
480
+ }
481
+
482
+ .action-btn--ghost:hover {
483
+ border-color: var(--border);
484
+ color: var(--text);
485
+ }
486
+
413
487
  .action-btn:disabled {
414
488
  opacity: 0.6;
415
489
  cursor: not-allowed;
416
490
  }
417
491
 
418
- .action-btn:disabled:hover {
419
- background: var(--bg-secondary);
420
- color: inherit;
421
- }
422
-
423
- .error-dialog-body {
492
+ .run-stage-actions {
424
493
  display: flex;
425
494
  align-items: center;
426
- gap: 16px;
427
- padding: 8px 0;
428
- }
429
- .error-dialog-body p {
430
- margin: 0;
431
- font-size: 14px;
432
- line-height: 1.5;
433
- }
434
- .error-dialog-icon {
435
- color: var(--status-error);
436
- flex-shrink: 0;
495
+ justify-content: flex-end;
496
+ gap: 6px;
497
+ padding: 0 0 4px;
498
+ flex-wrap: wrap;
437
499
  }
438
500
 
439
- /* --- 10. Run Header --- */
440
- .run-header {
441
- display: flex;
442
- align-items: flex-start;
443
- justify-content: space-between;
444
- padding: 16px 0;
445
- margin-bottom: 16px;
446
- border-bottom: 1px solid var(--border-subtle);
501
+ /* --- Run Timeline ---
502
+ Local tokens layered on the global palette. --text-strong gives a
503
+ WCAG-AA-safe muted color for labels (4.5:1 on white at 12-13px), avoiding
504
+ the very pale --muted (#94a3b8). All other colors route through brand vars
505
+ so dark mode and theme tweaks land for free. */
506
+ .run-timeline {
507
+ --tl-text-strong: #475569;
508
+ --tl-row-alt-bg: rgba(15, 23, 42, 0.04);
509
+ --tl-row-divider: rgba(15, 23, 42, 0.08);
510
+ --tl-grid-line: rgba(15, 23, 42, 0.05);
511
+ --tl-axis-line: rgba(15, 23, 42, 0.18);
512
+ --tl-axis-tick: rgba(15, 23, 42, 0.28);
513
+ --tl-axis-label: rgba(15, 23, 42, 0.62);
514
+ --tl-row-label: rgba(15, 23, 42, 0.78);
515
+ --tl-row-label-count: rgba(15, 23, 42, 0.45);
516
+ --tl-loopback-default-opacity: 0.7;
517
+ --tl-loopback-hint: rgba(15, 23, 42, 0.4);
518
+ --tl-bar-stroke: rgba(15, 23, 42, 0.22);
519
+ --tl-bar-shadow: rgba(15, 23, 42, 0.22);
520
+ --timeline-gap-fill: rgba(15, 23, 42, 0.04);
521
+ --timeline-gap-dot: rgba(15, 23, 42, 0.32);
522
+
523
+ padding: 16px 20px 24px;
524
+ background: var(--bg, #fff);
525
+ border: 1px solid var(--border-subtle, rgba(226, 232, 240, 0.6));
526
+ border-radius: 10px;
527
+ overflow-x: auto;
528
+ position: relative;
447
529
  }
448
530
 
449
- .run-header-left {
531
+ /* worca-ui drives dark mode via [data-theme="dark"] on the html element,
532
+ not via prefers-color-scheme. Both selectors here so the timeline tokens
533
+ flip with the rest of the chrome. */
534
+ [data-theme="dark"] .run-timeline,
535
+ .run-timeline[data-theme="dark"] {
536
+ --tl-text-strong: #cbd5e1;
537
+ --tl-row-alt-bg: rgba(255, 255, 255, 0.04);
538
+ --tl-row-divider: rgba(255, 255, 255, 0.1);
539
+ --tl-grid-line: rgba(255, 255, 255, 0.07);
540
+ --tl-axis-line: rgba(255, 255, 255, 0.22);
541
+ --tl-axis-tick: rgba(255, 255, 255, 0.35);
542
+ --tl-axis-label: rgba(255, 255, 255, 0.7);
543
+ --tl-row-label: rgba(255, 255, 255, 0.9);
544
+ --tl-row-label-count: rgba(255, 255, 255, 0.55);
545
+ --tl-loopback-hint: rgba(255, 255, 255, 0.5);
546
+ --tl-bar-stroke: rgba(255, 255, 255, 0.32);
547
+ --tl-bar-shadow: rgba(0, 0, 0, 0.45);
548
+ --timeline-gap-fill: rgba(255, 255, 255, 0.06);
549
+ --timeline-gap-dot: rgba(255, 255, 255, 0.4);
550
+ }
551
+
552
+ /* Top stats summary */
553
+ .timeline-summary {
554
+ display: flex;
555
+ align-items: center;
556
+ gap: 28px;
557
+ /* Right-padding reserves space for the absolutely-positioned .timeline-toolbar
558
+ anchored at top:16px / right:20px so the stats never run under the buttons. */
559
+ padding: 4px 260px 16px 0;
560
+ flex-wrap: wrap;
561
+ }
562
+ .summary-stat {
450
563
  display: flex;
451
- align-items: center;
452
- gap: 12px;
564
+ flex-direction: column;
565
+ gap: 2px;
566
+ min-width: 64px;
453
567
  }
454
-
455
- .run-title {
456
- font-size: 22px;
568
+ .summary-stat-label {
569
+ font-size: 11px;
570
+ text-transform: uppercase;
571
+ letter-spacing: 0.04em;
572
+ color: var(--tl-text-strong);
573
+ font-weight: 500;
574
+ }
575
+ .summary-stat-value {
576
+ font-size: 18px;
457
577
  font-weight: 600;
458
- color: var(--fg);
459
- letter-spacing: -0.01em;
578
+ color: var(--fg, #0f172a);
579
+ font-variant-numeric: tabular-nums;
580
+ }
581
+ .summary-spacer {
582
+ flex: 1;
460
583
  }
461
584
 
462
- .run-header-right {
585
+ /* Toolbar — anchored to the top-right corner of the timeline box.
586
+ Stacks the zoom button group above the keyboard-hint text, both right-aligned. */
587
+ .timeline-toolbar {
588
+ position: absolute;
589
+ top: 16px;
590
+ right: 20px;
591
+ z-index: 2;
463
592
  display: flex;
593
+ flex-direction: column;
594
+ align-items: flex-end;
595
+ gap: 6px;
596
+ }
597
+ .timeline-toolbar-group {
598
+ display: inline-flex;
599
+ border: 1px solid var(--border, #e2e8f0);
600
+ border-radius: 6px;
601
+ overflow: hidden;
602
+ background: var(--bg, #fff);
603
+ }
604
+ .timeline-zoom-btn {
605
+ display: inline-flex;
464
606
  align-items: center;
465
- gap: 16px;
607
+ justify-content: center;
608
+ min-width: 30px;
609
+ height: 28px;
610
+ padding: 0 8px;
611
+ border: none;
612
+ background: transparent;
613
+ color: var(--tl-text-strong);
614
+ cursor: pointer;
615
+ user-select: none;
616
+ border-right: 1px solid var(--border, #e2e8f0);
617
+ }
618
+ .timeline-zoom-btn:last-child {
619
+ border-right: none;
620
+ }
621
+ .timeline-zoom-btn:hover {
622
+ background: var(--bg-secondary, #f8fafc);
623
+ color: var(--fg, #0f172a);
624
+ }
625
+ .timeline-zoom-btn:active {
626
+ background: var(--bg-tertiary, #f1f5f9);
627
+ }
628
+ .timeline-zoom-btn:focus-visible {
629
+ outline: 2px solid var(--accent, #3b82f6);
630
+ outline-offset: -2px;
631
+ z-index: 1;
632
+ }
633
+ .timeline-toolbar-hint {
634
+ font-size: 11px;
635
+ color: var(--tl-text-strong);
636
+ text-align: right;
466
637
  }
467
638
 
468
- .run-meta {
469
- font-size: 13px;
470
- color: var(--muted);
639
+ /* SVG wrapper */
640
+ .timeline-svg-wrap {
641
+ position: relative;
642
+ overflow: visible;
471
643
  }
472
644
 
473
- .meta-label {
474
- font-weight: 500;
475
- color: var(--fg);
476
- opacity: 0.7;
645
+ /* Row backgrounds */
646
+ .row-bg-alt {
647
+ fill: var(--tl-row-alt-bg);
648
+ }
649
+ .row-divider {
650
+ stroke: var(--tl-row-divider);
651
+ stroke-width: 1;
652
+ shape-rendering: crispEdges;
653
+ }
654
+ .grid-line {
655
+ stroke: var(--tl-grid-line);
656
+ stroke-width: 1;
657
+ shape-rendering: crispEdges;
477
658
  }
478
659
 
479
- .meta-value {
660
+ /* Row labels — match the uppercase tracking used by .pipeline-stage-name so
661
+ timeline rows read like the stage section headers elsewhere in the UI. */
662
+ .row-label {
663
+ font-size: 12px;
480
664
  font-weight: 600;
481
- color: var(--fg);
665
+ fill: var(--tl-row-label);
666
+ font-family: var(--sl-font-sans, system-ui, sans-serif);
667
+ text-transform: uppercase;
668
+ letter-spacing: 0.03em;
482
669
  }
483
-
484
- .run-pr-link {
485
- color: var(--accent);
486
- text-decoration: none;
670
+ .row-label-count {
671
+ font-size: 11px;
487
672
  font-weight: 500;
673
+ fill: var(--tl-row-label-count);
674
+ text-transform: none;
675
+ letter-spacing: 0;
488
676
  }
489
-
490
- .run-pr-link:hover {
491
- text-decoration: underline;
677
+ .loopback-hint {
678
+ font-size: 10px;
679
+ fill: var(--tl-loopback-hint);
680
+ pointer-events: none;
492
681
  }
493
682
 
494
- .run-meta-grid {
495
- display: flex;
496
- flex-direction: column;
497
- gap: 6px;
498
- padding: 12px 16px;
499
- background: var(--bg-hover);
500
- border-radius: var(--radius-md);
501
- margin-bottom: 8px;
502
- font-size: 13px;
503
- color: var(--muted);
504
- font-variant-numeric: tabular-nums;
683
+ /* Bars
684
+ Default: thin contrasting hairline stroke so bar edges read clearly without
685
+ any per-bar divider. Hover/active: lift via translateY + drop-shadow so the
686
+ bar "raises" off the chart. Active state persists while the iteration drawer
687
+ is open (driven by the .is-active class). Reduced-motion drops the lift. */
688
+ .timeline-bar {
689
+ cursor: pointer;
690
+ stroke: var(--tl-bar-stroke);
691
+ stroke-width: 1;
692
+ transition:
693
+ filter 130ms ease,
694
+ transform 130ms ease,
695
+ stroke-width 130ms ease;
696
+ /* SVG rect transforms relative to the SVG viewport origin, not the rect
697
+ itself — fine for translateY since we want a small vertical lift. */
698
+ }
699
+ .timeline-bar:hover,
700
+ .timeline-bar.is-active {
701
+ filter: drop-shadow(0 3px 6px var(--tl-bar-shadow));
702
+ transform: translateY(-1px);
703
+ stroke-width: 1.25;
505
704
  }
506
-
507
- .run-meta-row {
508
- display: flex;
509
- flex-wrap: wrap;
510
- gap: 4px 20px;
705
+ .timeline-bar:focus-visible {
706
+ /* Subtle keyboard-focus indicator — no bold ring. The raised+shadow state
707
+ above also kicks in on focus via :focus-visible :is() below. */
708
+ outline: 1.5px dashed var(--accent, #3b82f6);
709
+ outline-offset: 2px;
511
710
  }
512
-
513
- .timing-strip {
514
- display: flex;
515
- flex-wrap: wrap;
516
- gap: 4px 20px;
517
- font-size: 13px;
518
- color: var(--muted);
711
+ .timeline-bar:focus-visible {
712
+ filter: drop-shadow(0 3px 6px var(--tl-bar-shadow));
713
+ transform: translateY(-1px);
714
+ }
715
+ @media (prefers-reduced-motion: reduce) {
716
+ .timeline-bar,
717
+ .timeline-bar:hover,
718
+ .timeline-bar.is-active,
719
+ .timeline-bar:focus-visible {
720
+ transform: none;
721
+ }
722
+ }
723
+ .bar-label {
724
+ font-size: 10px;
725
+ font-weight: 600;
726
+ fill: #fff;
727
+ font-family: var(--sl-font-sans, system-ui, sans-serif);
519
728
  font-variant-numeric: tabular-nums;
729
+ letter-spacing: 0.02em;
520
730
  }
521
731
 
522
- .timing-strip-item {
523
- white-space: nowrap;
732
+ /* Gaps */
733
+ .timeline-gap {
734
+ cursor: default;
524
735
  }
525
-
526
- .run-card .timing-strip {
527
- font-size: 12px;
528
- gap: 6px 16px;
529
- padding-left: 26px;
736
+ .timeline-gap:focus-visible {
737
+ outline: 2px solid var(--accent, #3b82f6);
738
+ outline-offset: 1px;
530
739
  }
531
-
532
- .stage-detail .timing-strip {
533
- margin-bottom: 8px;
534
- padding-bottom: 8px;
535
- border-bottom: 1px solid var(--border);
740
+ .gap-bg {
741
+ fill: var(--timeline-gap-fill);
536
742
  }
537
-
538
- .run-info-section {
539
- padding: 12px 16px;
540
- background: var(--bg-hover);
541
- border-radius: var(--radius-md);
542
- margin-bottom: 8px;
543
- display: flex;
544
- flex-direction: column;
545
- gap: 6px;
743
+ .gap-dot {
744
+ fill: var(--timeline-gap-dot);
546
745
  }
547
746
 
548
- /* Project / Branch / Pipeline-Template / Worktree rows inside
549
- `.run-info-section` all share the same label-value typography so the
550
- block reads as a uniform stack. Mirror .run-group below it. */
551
- .run-project,
552
- .run-branch,
553
- .run-template,
554
- .run-worktree {
555
- display: flex;
556
- align-items: center;
557
- gap: 6px;
558
- font-size: 13px;
747
+ /* Loopbacks */
748
+ .loopback {
749
+ stroke-opacity: var(--tl-loopback-default-opacity);
750
+ transition: stroke-opacity 120ms ease, stroke-width 120ms ease;
559
751
  }
560
-
561
- .pipeline-cost-strip {
562
- display: flex;
563
- flex-wrap: wrap;
564
- gap: 4px 20px;
565
- font-size: 13px;
566
- font-weight: 600;
567
- color: var(--fg);
752
+ .loopback.highlight {
753
+ stroke-opacity: 1;
754
+ stroke-width: 2.5;
568
755
  }
569
756
 
570
- /* Pipeline timing bar */
571
- .pipeline-timing-bar-container {
572
- margin-top: 8px;
757
+ /* Time axis */
758
+ .axis-baseline {
759
+ stroke: var(--tl-axis-line);
760
+ stroke-width: 1;
761
+ shape-rendering: crispEdges;
573
762
  }
574
-
575
- .pipeline-timing-bar-label {
576
- font-size: 13px;
577
- font-weight: 600;
578
- margin-bottom: 4px;
763
+ .axis-tick {
764
+ stroke: var(--tl-axis-tick);
765
+ stroke-width: 1;
766
+ shape-rendering: crispEdges;
579
767
  }
580
-
581
- .pipeline-timing-bar {
582
- display: flex;
583
- height: 22px;
584
- border-radius: 6px;
585
- overflow: hidden;
586
- background: var(--surface);
768
+ .axis-label {
769
+ font-size: 11px;
770
+ fill: var(--tl-axis-label);
771
+ font-family: var(--sl-font-sans, system-ui, sans-serif);
772
+ font-variant-numeric: tabular-nums;
587
773
  }
588
774
 
589
- .timing-bar-segment {
775
+ /* Legend */
776
+ .timeline-legend {
590
777
  display: flex;
591
778
  align-items: center;
592
- justify-content: center;
593
- min-width: 0;
594
- transition: opacity 0.15s;
595
- cursor: default;
779
+ gap: 18px;
780
+ padding: 14px 0 4px;
781
+ margin-top: 8px;
782
+ border-top: 1px solid var(--border-subtle, rgba(226, 232, 240, 0.6));
783
+ flex-wrap: wrap;
596
784
  }
597
-
598
- .timing-bar-segment:hover {
599
- opacity: 0.85;
600
- }
601
-
602
- .timing-bar-thinking {
603
- background: var(--status-blocked, #f59e0b);
785
+ .legend-item {
786
+ display: inline-flex;
787
+ align-items: center;
788
+ gap: 6px;
789
+ font-size: 11px;
790
+ color: var(--tl-text-strong);
604
791
  }
605
-
606
- .timing-bar-tools {
607
- background: var(--status-in-progress, #3b82f6);
792
+ .legend-swatch {
793
+ display: inline-block;
794
+ width: 12px;
795
+ height: 12px;
796
+ border-radius: 3px;
797
+ background: var(--muted);
608
798
  }
609
-
610
- .timing-bar-rest {
611
- background: var(--muted, #94a3b8);
612
- opacity: 0.4;
799
+ .legend-swatch--gap {
800
+ background:
801
+ radial-gradient(circle, var(--timeline-gap-dot) 0.6px, transparent 1.2px),
802
+ var(--timeline-gap-fill);
803
+ background-size: 5px 5px;
804
+ border: 1px solid var(--tl-row-divider);
613
805
  }
614
-
615
- .timing-bar-segment-text {
616
- font-size: 11px;
617
- font-weight: 600;
618
- color: #fff;
619
- white-space: nowrap;
620
- overflow: hidden;
621
- text-overflow: ellipsis;
622
- padding: 0 6px;
623
- text-shadow: 0 1px 2px rgba(0,0,0,0.3);
806
+ .legend-loopback {
807
+ /* Inline SVG arc + chevron; inherits color from the legend-item color, so
808
+ it tracks the rest of the legend chrome in both themes. */
809
+ color: var(--accent, #3b82f6);
810
+ flex-shrink: 0;
624
811
  }
625
812
 
626
- .pipeline-timing-bar-legend {
627
- display: flex;
628
- flex-wrap: wrap;
629
- gap: 4px 16px;
630
- margin-top: 6px;
813
+ /* Tooltip */
814
+ .timeline-tooltip {
815
+ position: fixed;
816
+ z-index: 1000;
817
+ background: var(--bg, #fff);
818
+ border: 1px solid var(--border, #e2e8f0);
819
+ border-radius: 8px;
820
+ box-shadow: 0 10px 28px rgba(15, 23, 42, 0.12), 0 2px 6px rgba(15, 23, 42, 0.08);
821
+ padding: 10px 12px;
822
+ pointer-events: none;
823
+ min-width: 200px;
824
+ max-width: 280px;
631
825
  font-size: 12px;
826
+ line-height: 1.55;
827
+ color: var(--fg, #0f172a);
632
828
  }
633
-
634
- .timing-bar-legend-item {
829
+ .tooltip-header {
635
830
  display: flex;
636
831
  align-items: center;
637
- gap: 4px;
832
+ gap: 6px;
833
+ font-weight: 600;
834
+ margin-bottom: 6px;
835
+ padding-bottom: 6px;
836
+ border-bottom: 1px solid var(--border-subtle, rgba(226, 232, 240, 0.6));
638
837
  }
639
-
640
- .timing-bar-legend-swatch {
641
- width: 10px;
642
- height: 10px;
643
- border-radius: 2px;
838
+ .tooltip-hue-dot {
839
+ display: inline-block;
840
+ width: 8px;
841
+ height: 8px;
842
+ border-radius: 50%;
843
+ flex-shrink: 0;
644
844
  }
645
-
646
- .timing-bar-legend-label {
647
- color: var(--fg);
845
+ .tooltip-header-sub {
846
+ font-weight: 400;
847
+ color: var(--tl-text-strong);
848
+ font-size: 11px;
849
+ }
850
+ .tooltip-bead-sub {
851
+ font-size: 11px;
852
+ color: var(--tl-text-strong);
853
+ margin-top: -2px;
854
+ margin-bottom: 4px;
855
+ line-height: 1.35;
856
+ }
857
+ .tooltip-bead-id {
858
+ font-family: var(--sl-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
859
+ font-size: 10.5px;
860
+ background: var(--tl-row-alt, rgba(148, 163, 184, 0.12));
861
+ padding: 1px 5px;
862
+ border-radius: 3px;
863
+ margin-right: 4px;
864
+ }
865
+ .tooltip-row {
866
+ display: flex;
867
+ justify-content: space-between;
868
+ gap: 14px;
869
+ }
870
+ .tooltip-label {
871
+ color: var(--tl-text-strong);
648
872
  font-weight: 500;
649
873
  }
650
-
651
- .timing-bar-legend-value {
652
- color: var(--muted);
874
+ .tooltip-value {
875
+ font-family: var(--sl-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
876
+ font-variant-numeric: tabular-nums;
877
+ color: var(--fg, #0f172a);
653
878
  }
879
+ .tooltip-status {
880
+ text-transform: capitalize;
881
+ }
882
+ .tooltip-status.status-completed { color: var(--status-completed); }
883
+ .tooltip-status.status-running, .tooltip-status.status-in_progress { color: var(--status-running); }
884
+ .tooltip-status.status-failed { color: var(--status-failed); }
885
+ .tooltip-status.status-paused { color: var(--status-paused); }
886
+ .tooltip-status.status-interrupted { color: var(--status-interrupted); }
654
887
 
655
- .stage-totals-strip {
888
+ /* --- Iteration drawer --- */
889
+ .iteration-drawer::part(panel) {
890
+ width: 420px;
891
+ max-width: 90vw;
892
+ }
893
+ .iteration-drawer::part(header) {
894
+ border-bottom: 1px solid var(--border-subtle, rgba(226, 232, 240, 0.6));
895
+ }
896
+ .drawer-body {
656
897
  display: flex;
657
- gap: 20px;
658
- padding: 6px 0 2px;
898
+ flex-direction: column;
899
+ gap: 14px;
659
900
  font-size: 13px;
901
+ color: var(--fg, #0f172a);
902
+ }
903
+ .drawer-title {
904
+ display: flex;
905
+ align-items: center;
906
+ gap: 8px;
907
+ margin: 0 0 4px;
908
+ font-size: 16px;
660
909
  font-weight: 600;
661
- color: var(--fg);
910
+ color: var(--fg, #0f172a);
911
+ outline: none;
662
912
  }
663
-
664
- .stage-totals-item {
913
+ .drawer-hue-dot {
914
+ display: inline-block;
915
+ width: 10px;
916
+ height: 10px;
917
+ border-radius: 50%;
918
+ }
919
+ .drawer-title-sub {
920
+ font-weight: 400;
921
+ color: var(--tl-text-strong);
922
+ font-size: 13px;
923
+ }
924
+ .drawer-status-row {
665
925
  display: inline-flex;
666
926
  align-items: center;
667
- gap: 4px;
927
+ gap: 8px;
928
+ padding: 6px 12px;
929
+ border-radius: 999px;
930
+ background: var(--bg-secondary, #f8fafc);
931
+ align-self: flex-start;
668
932
  }
669
-
670
- .stage-info-strip {
933
+ .drawer-status-pill {
934
+ display: inline-block;
935
+ width: 8px;
936
+ height: 8px;
937
+ border-radius: 50%;
938
+ }
939
+ .drawer-status-text {
940
+ font-size: 12px;
941
+ font-weight: 600;
942
+ text-transform: capitalize;
943
+ }
944
+ .drawer-status-text.status-completed { color: var(--status-completed); }
945
+ .drawer-status-text.status-running, .drawer-status-text.status-in_progress { color: var(--status-running); }
946
+ .drawer-status-text.status-failed { color: var(--status-failed); }
947
+ .drawer-fields {
948
+ display: grid;
949
+ grid-template-columns: max-content 1fr;
950
+ gap: 8px 18px;
951
+ margin: 0;
952
+ }
953
+ .drawer-label {
954
+ color: var(--tl-text-strong);
955
+ font-weight: 500;
956
+ font-size: 12px;
957
+ text-transform: uppercase;
958
+ letter-spacing: 0.04em;
959
+ align-self: center;
960
+ }
961
+ .drawer-value {
962
+ margin: 0;
963
+ font-family: var(--sl-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
964
+ font-variant-numeric: tabular-nums;
965
+ color: var(--fg, #0f172a);
966
+ }
967
+ .drawer-bead {
968
+ font-family: inherit;
671
969
  display: flex;
970
+ align-items: baseline;
971
+ gap: 6px;
672
972
  flex-wrap: wrap;
673
- gap: 4px 20px;
973
+ }
974
+ .drawer-bead-id {
975
+ font-family: var(--sl-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
976
+ font-size: 11px;
977
+ background: var(--tl-row-alt, rgba(148, 163, 184, 0.12));
978
+ padding: 1px 6px;
979
+ border-radius: 3px;
980
+ }
981
+ .drawer-raw-json {
982
+ margin-top: 4px;
983
+ }
984
+ .drawer-raw-json summary {
985
+ cursor: pointer;
986
+ color: var(--tl-text-strong);
987
+ font-size: 12px;
988
+ user-select: none;
989
+ }
990
+ .drawer-raw-json pre {
991
+ font-size: 11px;
992
+ font-family: var(--sl-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
993
+ background: var(--bg-secondary, #f8fafc);
994
+ border: 1px solid var(--border, #e2e8f0);
995
+ border-radius: 6px;
996
+ padding: 10px;
997
+ overflow-x: auto;
998
+ white-space: pre;
999
+ margin-top: 6px;
1000
+ max-height: 280px;
1001
+ }
1002
+ .drawer-run-detail-link {
1003
+ color: var(--accent, #3b82f6);
1004
+ text-decoration: none;
674
1005
  font-size: 13px;
675
- color: var(--muted);
676
- padding: 4px 0;
1006
+ font-weight: 500;
677
1007
  }
678
-
679
- .stage-info-item {
680
- display: inline-flex;
681
- align-items: center;
682
- gap: 4px;
683
- white-space: nowrap;
1008
+ .drawer-run-detail-link:hover {
1009
+ text-decoration: underline;
684
1010
  }
685
1011
 
686
- .text-muted {
687
- color: var(--muted);
688
- opacity: 0.7;
1012
+ @media (prefers-reduced-motion: reduce) {
1013
+ .timeline-bar,
1014
+ .loopback {
1015
+ transition: none;
1016
+ }
689
1017
  }
690
1018
 
691
- .iteration-detail .timing-strip {
692
- margin-bottom: 8px;
693
- padding-bottom: 8px;
694
- border-bottom: 1px solid var(--border);
1019
+ .action-btn:disabled:hover {
1020
+ background: var(--bg-secondary);
1021
+ color: inherit;
695
1022
  }
696
1023
 
697
- /* --- 11. Stage Timeline --- */
698
- .stage-timeline {
1024
+ .error-dialog-body {
699
1025
  display: flex;
700
1026
  align-items: center;
701
- justify-content: safe center;
702
- padding: 28px 16px;
703
- gap: 0;
704
- overflow-x: auto;
1027
+ gap: 16px;
1028
+ padding: 8px 0;
1029
+ }
1030
+ .error-dialog-body p {
1031
+ margin: 0;
1032
+ font-size: 14px;
1033
+ line-height: 1.5;
1034
+ }
1035
+ .error-dialog-icon {
1036
+ color: var(--status-error);
1037
+ flex-shrink: 0;
705
1038
  }
706
1039
 
707
- .stage-node {
1040
+ /* --- 10. Run Header --- */
1041
+ .run-header {
708
1042
  display: flex;
709
- flex-direction: column;
710
- align-items: center;
711
- gap: 8px;
712
- position: relative;
713
- min-width: 90px;
1043
+ align-items: flex-start;
1044
+ justify-content: space-between;
1045
+ padding: 16px 0;
1046
+ margin-bottom: 16px;
1047
+ border-bottom: 1px solid var(--border-subtle);
714
1048
  }
715
1049
 
716
- .stage-icon {
717
- width: 52px;
718
- height: 52px;
719
- border-radius: 50%;
1050
+ .run-header-left {
720
1051
  display: flex;
721
1052
  align-items: center;
722
- justify-content: center;
723
- font-size: 18px;
724
- border: 3px solid var(--border);
725
- background: var(--bg);
726
- transition: border-color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
1053
+ gap: 12px;
727
1054
  }
728
1055
 
729
- .stage-icon svg {
730
- width: 22px;
731
- height: 22px;
1056
+ .run-title {
1057
+ font-size: 22px;
1058
+ font-weight: 600;
1059
+ color: var(--fg);
1060
+ letter-spacing: -0.01em;
732
1061
  }
733
1062
 
734
- .stage-node.status-pending .stage-icon {
735
- border-color: var(--status-pending);
1063
+ .run-header-right {
1064
+ display: flex;
1065
+ align-items: center;
1066
+ gap: 16px;
736
1067
  }
737
1068
 
738
- .stage-node.status-in-progress .stage-icon {
739
- border-color: var(--status-in-progress);
740
- box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.15);
1069
+ .run-meta {
1070
+ font-size: 13px;
1071
+ color: var(--muted);
741
1072
  }
742
1073
 
743
- .stage-node.status-completed .stage-icon {
744
- border-color: var(--status-completed);
745
- background: var(--status-completed);
746
- color: #ffffff;
747
- transform: scale(1.05);
1074
+ .meta-label {
1075
+ font-weight: 500;
1076
+ color: var(--fg);
1077
+ opacity: 0.7;
748
1078
  }
749
1079
 
750
- .stage-node.status-error .stage-icon {
751
- border-color: var(--status-error);
752
- box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.15);
1080
+ .meta-value {
1081
+ font-weight: 600;
1082
+ color: var(--fg);
753
1083
  }
754
1084
 
755
- .stage-node.status-interrupted .stage-icon {
756
- border-color: var(--status-interrupted);
1085
+ .run-pr-link {
1086
+ color: var(--accent);
1087
+ text-decoration: none;
1088
+ font-weight: 500;
757
1089
  }
758
1090
 
759
- .stage-label {
760
- font-size: 11px;
761
- font-weight: 500;
1091
+ .run-pr-link:hover {
1092
+ text-decoration: underline;
1093
+ }
1094
+
1095
+ .run-meta-grid {
1096
+ display: flex;
1097
+ flex-direction: column;
1098
+ gap: 6px;
1099
+ padding: 12px 16px;
1100
+ background: var(--bg-hover);
1101
+ border-radius: var(--radius-md);
1102
+ margin-bottom: 8px;
1103
+ font-size: 13px;
762
1104
  color: var(--muted);
763
- text-align: center;
764
- white-space: nowrap;
765
- text-transform: uppercase;
766
- letter-spacing: 0.04em;
1105
+ font-variant-numeric: tabular-nums;
767
1106
  }
768
1107
 
769
- /* --- 12. Spin Animation --- */
770
- .icon-spin {
771
- animation: icon-spin 1.5s linear infinite;
1108
+ .run-meta-row {
1109
+ display: flex;
1110
+ flex-wrap: wrap;
1111
+ gap: 4px 20px;
772
1112
  }
773
1113
 
774
- @keyframes icon-spin {
775
- from { transform: rotate(0deg); }
776
- to { transform: rotate(360deg); }
1114
+ .timing-strip {
1115
+ display: flex;
1116
+ flex-wrap: wrap;
1117
+ gap: 4px 20px;
1118
+ font-size: 13px;
1119
+ color: var(--muted);
1120
+ font-variant-numeric: tabular-nums;
777
1121
  }
778
1122
 
779
- .effort-zap-icon {
780
- width: 12px;
781
- height: 12px;
782
- vertical-align: -1px;
783
- margin-right: 2px;
1123
+ .timing-strip-item {
1124
+ white-space: nowrap;
784
1125
  }
785
1126
 
786
- /* --- 13. Stage Connector --- */
787
- .stage-connector {
788
- width: 36px;
789
- height: 4px;
790
- background: var(--border);
791
- border-radius: 2px;
792
- flex-shrink: 0;
793
- align-self: center;
794
- margin-bottom: 24px;
795
- transition: background var(--transition-fast);
1127
+ .run-card .timing-strip {
1128
+ font-size: 12px;
1129
+ gap: 6px 16px;
1130
+ padding-left: 26px;
796
1131
  }
797
1132
 
798
- .stage-connector.completed {
799
- background: var(--status-completed);
1133
+ .stage-detail .timing-strip {
1134
+ margin-bottom: 8px;
1135
+ padding-bottom: 8px;
1136
+ border-bottom: 1px solid var(--border);
800
1137
  }
801
1138
 
802
- /* --- 13b. Prompt Panel --- */
803
- .run-prompt-panel {
804
- margin-bottom: 16px;
1139
+ /* Pending stage: placeholder line shown until the stage starts (then replaced
1140
+ by the real Started/Finished/Duration strip). Keeps the body non-empty so
1141
+ the absolute Copy button aligns to content instead of the divider. */
1142
+ .timing-strip--pending .timing-strip-pending {
1143
+ font-size: 12px;
1144
+ font-style: italic;
1145
+ color: var(--fg-muted);
805
1146
  }
806
1147
 
807
- .run-prompt-summary {
1148
+ .run-info-section {
1149
+ padding: 12px 16px;
1150
+ background: var(--bg-hover);
1151
+ border-radius: var(--radius-md);
1152
+ margin-bottom: 8px;
1153
+ display: flex;
1154
+ flex-direction: column;
1155
+ gap: 6px;
1156
+ }
1157
+
1158
+ /* Project / Branch / Pipeline-Template / Worktree rows inside
1159
+ `.run-info-section` all share the same label-value typography so the
1160
+ block reads as a uniform stack. Mirror .run-group below it. */
1161
+ .run-project,
1162
+ .run-branch,
1163
+ .run-target-branch,
1164
+ .run-source,
1165
+ .run-template,
1166
+ .run-worktree {
1167
+ display: flex;
1168
+ align-items: center;
1169
+ gap: 6px;
808
1170
  font-size: 13px;
809
- font-weight: 500;
810
- color: var(--muted);
811
- text-transform: uppercase;
812
- letter-spacing: 0.04em;
813
1171
  }
814
1172
 
815
- .run-prompt-body {
1173
+ .pipeline-cost-strip {
1174
+ display: flex;
1175
+ flex-wrap: wrap;
1176
+ gap: 4px 20px;
816
1177
  font-size: 13px;
1178
+ font-weight: 600;
817
1179
  color: var(--fg);
818
- line-height: 1.6;
819
- white-space: pre-wrap;
820
- word-break: break-word;
821
- max-height: 400px;
822
- overflow-y: auto;
823
- padding: 8px 0;
824
1180
  }
825
1181
 
826
- /* --- 14. Stage Detail & Panel --- */
827
- .stage-panels {
1182
+ /* Pipeline timing bar */
1183
+ .pipeline-timing-bar-actions {
828
1184
  display: flex;
829
- flex-direction: column;
1185
+ justify-content: flex-end;
830
1186
  gap: 8px;
831
- margin-top: 16px;
1187
+ margin-bottom: 8px;
832
1188
  }
833
1189
 
834
- sl-details.stage-panel {
835
- --border-color: var(--border-subtle);
836
- --border-radius: var(--radius-lg);
1190
+ .pipeline-timing-bar-container {
1191
+ margin-top: 8px;
837
1192
  }
838
1193
 
839
- sl-details.stage-panel::part(base) {
840
- border: 1px solid var(--border-subtle);
841
- border-radius: var(--radius-lg);
842
- background: var(--bg-secondary);
843
- box-shadow: var(--shadow-sm);
1194
+ .pipeline-timing-bar-label {
1195
+ font-size: 13px;
1196
+ font-weight: 600;
1197
+ margin-bottom: 4px;
844
1198
  }
845
1199
 
846
- sl-details.stage-panel::part(header) {
847
- padding: 12px 16px;
1200
+ .pipeline-timing-bar {
1201
+ display: flex;
1202
+ height: 22px;
1203
+ border-radius: 6px;
1204
+ overflow: hidden;
1205
+ background: var(--surface);
848
1206
  }
849
1207
 
850
- sl-details.stage-panel::part(content) {
851
- padding: 0 16px 16px;
1208
+ .timing-bar-segment {
1209
+ display: flex;
1210
+ align-items: center;
1211
+ justify-content: center;
1212
+ min-width: 0;
1213
+ transition: opacity 0.15s;
1214
+ cursor: default;
852
1215
  }
853
1216
 
854
- .stage-content-wrapper {
855
- position: relative;
1217
+ .timing-bar-segment:hover {
1218
+ opacity: 0.85;
856
1219
  }
857
1220
 
858
- .stage-copy-btn {
859
- position: absolute;
860
- top: 0;
861
- right: 0;
862
- display: inline-flex;
863
- align-items: center;
864
- gap: 4px;
865
- padding: 2px 8px;
866
- font-size: 11px;
867
- font-family: inherit;
868
- color: var(--fg-muted);
869
- background: transparent;
870
- border: 1px solid var(--border-subtle);
871
- border-radius: var(--radius-sm);
872
- cursor: pointer;
873
- transition: color 0.15s, border-color 0.15s;
874
- z-index: 1;
1221
+ .timing-bar-thinking {
1222
+ background: var(--status-blocked, #f59e0b);
875
1223
  }
876
1224
 
877
- .stage-copy-btn:hover {
878
- color: var(--fg);
879
- border-color: var(--fg-muted);
1225
+ .timing-bar-tools {
1226
+ background: var(--status-in-progress, #3b82f6);
880
1227
  }
881
1228
 
882
- .stage-copy-btn svg {
883
- flex-shrink: 0;
1229
+ .timing-bar-rest {
1230
+ background: var(--muted, #94a3b8);
1231
+ opacity: 0.4;
884
1232
  }
885
1233
 
886
- .stage-panel-header {
1234
+ .timing-bar-segment-text {
1235
+ font-size: 11px;
1236
+ font-weight: 600;
1237
+ color: #fff;
1238
+ white-space: nowrap;
1239
+ overflow: hidden;
1240
+ text-overflow: ellipsis;
1241
+ padding: 0 6px;
1242
+ text-shadow: 0 1px 2px rgba(0,0,0,0.3);
1243
+ }
1244
+
1245
+ .pipeline-timing-bar-legend {
887
1246
  display: flex;
888
- align-items: center;
889
- gap: 10px;
890
- width: 100%;
1247
+ flex-wrap: wrap;
1248
+ gap: 4px 16px;
1249
+ margin-top: 6px;
1250
+ font-size: 12px;
891
1251
  }
892
1252
 
893
- .stage-panel-icon {
1253
+ .timing-bar-legend-item {
894
1254
  display: flex;
895
1255
  align-items: center;
1256
+ gap: 4px;
896
1257
  }
897
1258
 
898
- .stage-panel-icon svg {
899
- width: 16px;
900
- height: 16px;
1259
+ .timing-bar-legend-swatch {
1260
+ width: 10px;
1261
+ height: 10px;
1262
+ border-radius: 2px;
901
1263
  }
902
1264
 
903
- .stage-panel-label {
1265
+ .timing-bar-legend-label {
1266
+ color: var(--fg);
904
1267
  font-weight: 500;
905
- font-size: 14px;
906
1268
  }
907
1269
 
908
- .stage-panel-meta {
909
- display: flex;
910
- gap: 12px;
911
- margin-left: auto;
912
- margin-right: 8px;
913
- font-size: 12px;
1270
+ .timing-bar-legend-value {
914
1271
  color: var(--muted);
915
- font-variant-numeric: tabular-nums;
916
1272
  }
917
1273
 
918
- .stage-meta-item {
919
- display: inline-flex;
920
- align-items: center;
921
- gap: 4px;
922
- white-space: nowrap;
1274
+ .stage-totals-strip {
1275
+ display: flex;
1276
+ gap: 20px;
1277
+ padding: 6px 0 2px;
1278
+ font-size: 13px;
1279
+ font-weight: 600;
1280
+ color: var(--fg);
923
1281
  }
924
1282
 
925
- .stage-meta-icon {
1283
+ .stage-totals-item {
926
1284
  display: inline-flex;
927
- opacity: 0.6;
928
- }
929
-
930
- .stage-meta-iteration {
931
- color: var(--status-in-progress);
932
- font-weight: 600;
1285
+ align-items: center;
1286
+ gap: 4px;
933
1287
  }
934
1288
 
935
- .stage-detail {
1289
+ .stage-info-strip {
1290
+ display: flex;
1291
+ flex-wrap: wrap;
1292
+ gap: 4px 20px;
1293
+ font-size: 13px;
1294
+ color: var(--muted);
936
1295
  padding: 4px 0;
937
1296
  }
938
1297
 
939
- .detail-row {
940
- padding: 4px 0;
941
- font-size: 13px;
942
- color: var(--muted);
1298
+ .stage-info-item {
1299
+ display: inline-flex;
1300
+ align-items: center;
1301
+ gap: 4px;
1302
+ white-space: nowrap;
943
1303
  }
944
1304
 
945
- .detail-label {
946
- font-weight: 500;
947
- color: var(--fg);
1305
+ .text-muted {
1306
+ color: var(--muted);
948
1307
  opacity: 0.7;
949
- margin-right: 4px;
950
1308
  }
951
1309
 
952
- .detail-error {
953
- color: var(--status-error);
1310
+ .iteration-detail .timing-strip {
1311
+ margin-bottom: 8px;
1312
+ padding-bottom: 8px;
1313
+ border-bottom: 1px solid var(--border);
954
1314
  }
955
1315
 
956
- /* --- 15. Loop Indicator --- */
957
- .loop-indicator {
958
- position: absolute;
959
- top: -4px;
960
- right: 8px;
1316
+ /* --- 11. Stage Timeline --- */
1317
+ .stage-timeline {
961
1318
  display: flex;
962
1319
  align-items: center;
963
- gap: 2px;
964
- font-size: 10px;
965
- font-weight: 600;
966
- background: var(--accent);
967
- color: #ffffff;
968
- padding: 2px 6px;
969
- border-radius: 10px;
970
- line-height: 1.3;
1320
+ justify-content: safe center;
1321
+ padding: 28px 16px;
1322
+ gap: 0;
1323
+ overflow-x: auto;
971
1324
  }
972
1325
 
973
- /* --- 16. Milestone Marker --- */
974
- .milestone-marker {
975
- position: absolute;
976
- bottom: -18px;
977
- left: 50%;
978
- transform: translateX(-50%);
979
- color: var(--status-in-progress);
1326
+ .stage-node {
1327
+ display: flex;
1328
+ flex-direction: column;
1329
+ align-items: center;
1330
+ gap: 8px;
1331
+ position: relative;
1332
+ min-width: 90px;
980
1333
  }
981
1334
 
982
- /* --- 17. Log Viewer (Log History) --- */
983
- .log-history-container {
984
- margin-top: 20px;
1335
+ .stage-icon {
1336
+ width: 52px;
1337
+ height: 52px;
1338
+ border-radius: 50%;
1339
+ display: flex;
1340
+ align-items: center;
1341
+ justify-content: center;
1342
+ font-size: 18px;
1343
+ border: 3px solid var(--border);
1344
+ background: var(--bg);
1345
+ transition: border-color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
985
1346
  }
986
1347
 
987
- sl-details.log-history-panel::part(base) {
988
- border: 1px solid var(--border-subtle);
989
- border-radius: var(--radius-lg);
990
- background: var(--bg-secondary);
991
- box-shadow: var(--shadow-sm);
1348
+ .stage-icon svg {
1349
+ width: 22px;
1350
+ height: 22px;
992
1351
  }
993
1352
 
994
- sl-details.log-history-panel::part(header) {
995
- padding: 12px 16px;
1353
+ .stage-node.status-pending .stage-icon {
1354
+ border-color: var(--status-pending);
996
1355
  }
997
1356
 
998
- sl-details.log-history-panel::part(content) {
999
- padding: 0;
1357
+ .stage-node.status-in-progress .stage-icon {
1358
+ border-color: var(--status-in-progress);
1359
+ box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.15);
1000
1360
  }
1001
1361
 
1002
- .log-history-header {
1003
- display: flex;
1004
- align-items: center;
1005
- gap: 10px;
1006
- width: 100%;
1362
+ .stage-node.status-completed .stage-icon {
1363
+ border-color: var(--status-completed);
1364
+ background: var(--status-completed);
1365
+ color: #ffffff;
1366
+ transform: scale(1.05);
1007
1367
  }
1008
1368
 
1009
- .log-history-icon {
1010
- display: flex;
1011
- align-items: center;
1012
- color: var(--muted);
1369
+ .stage-node.status-error .stage-icon {
1370
+ border-color: var(--status-error);
1371
+ box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.15);
1013
1372
  }
1014
1373
 
1015
- .log-history-title {
1016
- font-weight: 600;
1017
- font-size: 14px;
1018
- color: var(--fg);
1374
+ .stage-node.status-interrupted .stage-icon {
1375
+ border-color: var(--status-interrupted);
1376
+ }
1377
+
1378
+ .stage-label {
1379
+ font-size: 11px;
1380
+ font-weight: 500;
1381
+ color: var(--muted);
1382
+ text-align: center;
1383
+ white-space: nowrap;
1019
1384
  text-transform: uppercase;
1020
1385
  letter-spacing: 0.04em;
1021
1386
  }
1022
1387
 
1023
- .log-history-body {
1024
- border-top: 1px solid var(--border-subtle);
1025
- padding: 0 16px 16px;
1388
+ /* --- 12. Spin Animation --- */
1389
+ .icon-spin {
1390
+ animation: icon-spin 1.5s linear infinite;
1026
1391
  }
1027
1392
 
1028
- .log-history-empty {
1029
- display: flex;
1030
- flex-direction: column;
1031
- align-items: center;
1032
- justify-content: center;
1033
- padding: 40px 24px;
1034
- color: var(--muted);
1035
- text-align: center;
1036
- gap: 12px;
1393
+ @keyframes icon-spin {
1394
+ from { transform: rotate(0deg); }
1395
+ to { transform: rotate(360deg); }
1037
1396
  }
1038
1397
 
1039
- .log-history-empty-icon {
1040
- display: flex;
1041
- align-items: center;
1042
- opacity: 0.4;
1398
+ .effort-zap-icon {
1399
+ width: 12px;
1400
+ height: 12px;
1401
+ vertical-align: -1px;
1402
+ margin-right: 2px;
1043
1403
  }
1044
1404
 
1045
- .log-history-empty p {
1046
- margin: 0;
1047
- font-size: 13px;
1048
- line-height: 1.5;
1405
+ /* --- 13. Stage Connector --- */
1406
+ .stage-connector {
1407
+ width: 36px;
1408
+ height: 4px;
1409
+ background: var(--border);
1410
+ border-radius: 2px;
1411
+ flex-shrink: 0;
1412
+ align-self: center;
1413
+ margin-bottom: 24px;
1414
+ transition: background var(--transition-fast);
1049
1415
  }
1050
1416
 
1051
- .log-controls {
1052
- display: flex;
1053
- align-items: center;
1054
- gap: 10px;
1055
- padding: 10px 0;
1417
+ .stage-connector.completed {
1418
+ background: var(--status-completed);
1056
1419
  }
1057
1420
 
1058
- .log-controls sl-select {
1059
- min-width: 160px;
1421
+ /* --- 13b. Prompt Panel --- */
1422
+ .run-prompt-panel {
1423
+ margin-bottom: 16px;
1060
1424
  }
1061
1425
 
1062
- .log-controls .terminal-copy-btn {
1063
- margin-left: auto;
1426
+ .run-prompt-summary {
1427
+ font-size: 13px;
1428
+ font-weight: 500;
1429
+ color: var(--muted);
1430
+ text-transform: uppercase;
1431
+ letter-spacing: 0.04em;
1064
1432
  }
1065
1433
 
1066
- .log-controls sl-input {
1067
- flex: 1;
1068
- min-width: 140px;
1434
+ .run-prompt-body {
1435
+ font-size: 13px;
1436
+ color: var(--fg);
1437
+ line-height: 1.6;
1438
+ white-space: pre-wrap;
1439
+ word-break: break-word;
1440
+ max-height: 400px;
1441
+ overflow-y: auto;
1442
+ padding: 8px 0;
1069
1443
  }
1070
1444
 
1071
- /* Prefix-slot icon centering. Inline SVGs default to baseline alignment,
1072
- which sits them at the top of an sl-input. Flex-center the slot wrapper
1073
- so any iconSvg(...) we drop into a prefix lines up with the placeholder
1074
- / value text. Generic rule covers every sl-input; .log-controls keeps
1075
- the extra left padding it always had. */
1076
- sl-input [slot="prefix"] {
1445
+ /* --- 14. Stage Detail & Panel --- */
1446
+ .stage-panels {
1077
1447
  display: flex;
1078
- align-items: center;
1448
+ flex-direction: column;
1449
+ gap: 8px;
1450
+ margin-top: 16px;
1079
1451
  }
1080
1452
 
1081
- .log-controls sl-input [slot="prefix"] {
1082
- padding-left: 4px;
1453
+ sl-details.stage-panel {
1454
+ --border-color: var(--border-subtle);
1455
+ --border-radius: var(--radius-lg);
1083
1456
  }
1084
1457
 
1085
- .log-terminal-wrapper {
1458
+ sl-details.stage-panel::part(base) {
1459
+ border: 1px solid var(--border-subtle);
1086
1460
  border-radius: var(--radius-lg);
1087
- overflow: hidden;
1088
- border: 1px solid var(--border);
1089
- box-shadow: var(--shadow-md);
1461
+ background: var(--bg-secondary);
1462
+ box-shadow: var(--shadow-sm);
1090
1463
  }
1091
1464
 
1092
- .log-terminal {
1093
- height: 420px;
1094
- background: var(--log-bg);
1465
+ sl-details.stage-panel::part(header) {
1466
+ padding: 12px 16px;
1095
1467
  }
1096
1468
 
1097
- /* xterm.js overrides */
1098
- .log-terminal .xterm-viewport::-webkit-scrollbar {
1099
- width: 8px;
1469
+ sl-details.stage-panel::part(content) {
1470
+ padding: 0 16px 16px;
1100
1471
  }
1101
1472
 
1102
- .log-terminal .xterm-viewport::-webkit-scrollbar-track {
1473
+ .stage-content-wrapper {
1474
+ position: relative;
1475
+ }
1476
+
1477
+ .stage-copy-btn {
1478
+ position: absolute;
1479
+ top: 0;
1480
+ right: 0;
1481
+ display: inline-flex;
1482
+ align-items: center;
1483
+ gap: 4px;
1484
+ padding: 2px 8px;
1485
+ font-size: 11px;
1486
+ font-family: inherit;
1487
+ color: var(--fg-muted);
1103
1488
  background: transparent;
1489
+ border: 1px solid var(--border-subtle);
1490
+ border-radius: var(--radius-sm);
1491
+ cursor: pointer;
1492
+ transition: color 0.15s, border-color 0.15s;
1493
+ z-index: 1;
1104
1494
  }
1105
1495
 
1106
- .log-terminal .xterm-viewport::-webkit-scrollbar-thumb {
1107
- background: #334155;
1108
- border-radius: 4px;
1496
+ .stage-copy-btn:hover {
1497
+ color: var(--fg);
1498
+ border-color: var(--fg-muted);
1109
1499
  }
1110
1500
 
1111
- .log-terminal .xterm-viewport::-webkit-scrollbar-thumb:hover {
1112
- background: #475569;
1501
+ .stage-copy-btn svg {
1502
+ flex-shrink: 0;
1113
1503
  }
1114
1504
 
1115
- /* --- 18. Status Badge --- */
1505
+ .stage-panel-header {
1506
+ display: flex;
1507
+ align-items: center;
1508
+ gap: 10px;
1509
+ width: 100%;
1510
+ }
1511
+
1512
+ .stage-panel-icon {
1513
+ display: flex;
1514
+ align-items: center;
1515
+ }
1516
+
1517
+ .stage-panel-icon svg {
1518
+ width: 16px;
1519
+ height: 16px;
1520
+ }
1521
+
1522
+ .stage-panel-label {
1523
+ font-weight: 500;
1524
+ font-size: 14px;
1525
+ }
1526
+
1527
+ .stage-panel-meta {
1528
+ display: flex;
1529
+ gap: 12px;
1530
+ margin-left: auto;
1531
+ margin-right: 8px;
1532
+ font-size: 12px;
1533
+ color: var(--muted);
1534
+ font-variant-numeric: tabular-nums;
1535
+ }
1536
+
1537
+ .stage-meta-item {
1538
+ display: inline-flex;
1539
+ align-items: center;
1540
+ gap: 4px;
1541
+ white-space: nowrap;
1542
+ }
1543
+
1544
+ .stage-meta-icon {
1545
+ display: inline-flex;
1546
+ opacity: 0.6;
1547
+ }
1548
+
1549
+ .stage-meta-iteration {
1550
+ color: var(--status-in-progress);
1551
+ font-weight: 600;
1552
+ }
1553
+
1554
+ .stage-detail {
1555
+ padding: 4px 0;
1556
+ }
1557
+
1558
+ .detail-row {
1559
+ padding: 4px 0;
1560
+ font-size: 13px;
1561
+ color: var(--muted);
1562
+ }
1563
+
1564
+ .detail-label {
1565
+ font-weight: 500;
1566
+ color: var(--fg);
1567
+ opacity: 0.7;
1568
+ margin-right: 4px;
1569
+ }
1570
+
1571
+ .detail-error {
1572
+ color: var(--status-error);
1573
+ }
1574
+
1575
+ /* --- 15. Loop Indicator --- */
1576
+ .loop-indicator {
1577
+ position: absolute;
1578
+ top: -4px;
1579
+ right: 8px;
1580
+ display: flex;
1581
+ align-items: center;
1582
+ gap: 2px;
1583
+ font-size: 10px;
1584
+ font-weight: 600;
1585
+ background: var(--accent);
1586
+ color: #ffffff;
1587
+ padding: 2px 6px;
1588
+ border-radius: 10px;
1589
+ line-height: 1.3;
1590
+ }
1591
+
1592
+ /* --- 16. Milestone Marker --- */
1593
+ .milestone-marker {
1594
+ position: absolute;
1595
+ bottom: -18px;
1596
+ left: 50%;
1597
+ transform: translateX(-50%);
1598
+ color: var(--status-in-progress);
1599
+ }
1600
+
1601
+ /* --- 17. Log Viewer (Log History) --- */
1602
+ .log-history-container {
1603
+ margin-top: 20px;
1604
+ }
1605
+
1606
+ sl-details.log-history-panel::part(base) {
1607
+ border: 1px solid var(--border-subtle);
1608
+ border-radius: var(--radius-lg);
1609
+ background: var(--bg-secondary);
1610
+ box-shadow: var(--shadow-sm);
1611
+ }
1612
+
1613
+ sl-details.log-history-panel::part(header) {
1614
+ padding: 12px 16px;
1615
+ }
1616
+
1617
+ sl-details.log-history-panel::part(content) {
1618
+ padding: 0;
1619
+ }
1620
+
1621
+ .log-history-header {
1622
+ display: flex;
1623
+ align-items: center;
1624
+ gap: 10px;
1625
+ width: 100%;
1626
+ }
1627
+
1628
+ .log-history-icon {
1629
+ display: flex;
1630
+ align-items: center;
1631
+ color: var(--muted);
1632
+ }
1633
+
1634
+ .log-history-title {
1635
+ font-weight: 600;
1636
+ font-size: 14px;
1637
+ color: var(--fg);
1638
+ text-transform: uppercase;
1639
+ letter-spacing: 0.04em;
1640
+ }
1641
+
1642
+ .log-history-body {
1643
+ border-top: 1px solid var(--border-subtle);
1644
+ padding: 0 16px 16px;
1645
+ }
1646
+
1647
+ .log-history-empty {
1648
+ display: flex;
1649
+ flex-direction: column;
1650
+ align-items: center;
1651
+ justify-content: center;
1652
+ padding: 40px 24px;
1653
+ color: var(--muted);
1654
+ text-align: center;
1655
+ gap: 12px;
1656
+ }
1657
+
1658
+ .log-history-empty-icon {
1659
+ display: flex;
1660
+ align-items: center;
1661
+ opacity: 0.4;
1662
+ }
1663
+
1664
+ .log-history-empty p {
1665
+ margin: 0;
1666
+ font-size: 13px;
1667
+ line-height: 1.5;
1668
+ }
1669
+
1670
+ .log-controls {
1671
+ display: flex;
1672
+ align-items: center;
1673
+ gap: 10px;
1674
+ padding: 10px 0;
1675
+ }
1676
+
1677
+ .log-controls sl-select {
1678
+ min-width: 160px;
1679
+ }
1680
+
1681
+ .log-controls .terminal-copy-btn {
1682
+ margin-left: auto;
1683
+ }
1684
+
1685
+ .log-controls sl-input {
1686
+ flex: 1;
1687
+ min-width: 140px;
1688
+ }
1689
+
1690
+ /* Prefix-slot icon centering. Inline SVGs default to baseline alignment,
1691
+ which sits them at the top of an sl-input. Flex-center the slot wrapper
1692
+ so any iconSvg(...) we drop into a prefix lines up with the placeholder
1693
+ / value text. Generic rule covers every sl-input; .log-controls keeps
1694
+ the extra left padding it always had. */
1695
+ sl-input [slot="prefix"] {
1696
+ display: flex;
1697
+ align-items: center;
1698
+ }
1699
+
1700
+ .log-controls sl-input [slot="prefix"] {
1701
+ padding-left: 4px;
1702
+ }
1703
+
1704
+ .log-terminal-wrapper {
1705
+ border-radius: var(--radius-lg);
1706
+ overflow: hidden;
1707
+ border: 1px solid var(--border);
1708
+ box-shadow: var(--shadow-md);
1709
+ }
1710
+
1711
+ .log-terminal {
1712
+ height: 420px;
1713
+ background: var(--log-bg);
1714
+ }
1715
+
1716
+ /* xterm.js overrides */
1717
+ .log-terminal .xterm-viewport::-webkit-scrollbar {
1718
+ width: 8px;
1719
+ }
1720
+
1721
+ .log-terminal .xterm-viewport::-webkit-scrollbar-track {
1722
+ background: transparent;
1723
+ }
1724
+
1725
+ .log-terminal .xterm-viewport::-webkit-scrollbar-thumb {
1726
+ background: #334155;
1727
+ border-radius: 4px;
1728
+ }
1729
+
1730
+ .log-terminal .xterm-viewport::-webkit-scrollbar-thumb:hover {
1731
+ background: #475569;
1732
+ }
1733
+
1734
+ /* --- 18. Status Badge --- */
1116
1735
  .status-badge {
1117
1736
  display: inline-flex;
1118
1737
  align-items: center;
@@ -1340,6 +1959,12 @@ sl-input [slot="prefix"] {
1340
1959
  color: var(--muted);
1341
1960
  }
1342
1961
 
1962
+ /* Align the "Revising PR #N" badge with the meta rows above/below it
1963
+ (which carry the same 26px left indent past the status icon). */
1964
+ .run-card-revises-pr {
1965
+ padding-left: 26px;
1966
+ }
1967
+
1343
1968
  .run-card-stages {
1344
1969
  display: flex;
1345
1970
  flex-wrap: wrap;
@@ -1746,6 +2371,28 @@ sl-input [slot="prefix"] {
1746
2371
  margin-top: 2px;
1747
2372
  }
1748
2373
 
2374
+ /* Export-mode picker (standalone vs delta): roomy rows, with each option's
2375
+ description on its own line aligned under the option title (not the radio). */
2376
+ .export-mode-group sl-radio::part(base) {
2377
+ align-items: flex-start;
2378
+ }
2379
+ .export-mode-group sl-radio:not(:last-of-type) {
2380
+ margin-block-end: 16px;
2381
+ }
2382
+ .export-mode-option {
2383
+ display: flex;
2384
+ flex-direction: column;
2385
+ gap: 4px;
2386
+ }
2387
+ .export-mode-title {
2388
+ line-height: 1.3;
2389
+ }
2390
+ .export-mode-hint {
2391
+ font-size: 12px;
2392
+ color: var(--muted);
2393
+ line-height: 1.45;
2394
+ }
2395
+
1749
2396
  .settings-grid {
1750
2397
  display: grid;
1751
2398
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
@@ -3133,6 +3780,9 @@ sl-option.template-grouped:focus::part(suffix) {
3133
3780
 
3134
3781
  .sidebar.collapsed .sidebar-new-run-btn-primary {
3135
3782
  padding: 8px;
3783
+ /* Chevron half is hidden — drop the divider so the button reads as a
3784
+ single icon control, not a button with a stray edge. */
3785
+ border-right: 0;
3136
3786
  }
3137
3787
 
3138
3788
  /* Stage restart button */
@@ -4011,11 +4661,6 @@ sl-details.learnings-panel::part(content) {
4011
4661
  margin-top: 10px;
4012
4662
  }
4013
4663
 
4014
- .preflight-summary {
4015
- font-size: 0.8rem;
4016
- color: var(--muted);
4017
- margin-bottom: 8px;
4018
- }
4019
4664
 
4020
4665
  .preflight-table {
4021
4666
  width: 100%;
@@ -4049,6 +4694,12 @@ sl-details.learnings-panel::part(content) {
4049
4694
  color: var(--muted);
4050
4695
  }
4051
4696
 
4697
+ /* Secondary pill on the preflight params row (e.g. the Max Beads source:
4698
+ "explicit" / "template"). Same font as the value pill, visually subordinated. */
4699
+ .preflight-param-source-badge {
4700
+ opacity: 0.72;
4701
+ }
4702
+
4052
4703
  .circuit-breaker-banner {
4053
4704
  margin: 8px 0 4px;
4054
4705
  }
@@ -4951,12 +5602,50 @@ sl-tooltip.bead-tooltip::part(body) {
4951
5602
  }
4952
5603
 
4953
5604
  /* ─── Add Project / Worca Setup dialog shared styles ─────────────────── */
4954
- .dialog-meta-row {
5605
+ /* Gist-export dialog (template "Export (gist)" flow). */
5606
+ .gist-export-label {
4955
5607
  display: flex;
4956
5608
  align-items: center;
4957
5609
  gap: 0.5rem;
4958
- flex-wrap: wrap;
4959
- font-size: 0.85rem;
5610
+ }
5611
+
5612
+ .gist-export-spinner {
5613
+ font-size: 1rem;
5614
+ }
5615
+
5616
+ .gist-export-body {
5617
+ display: flex;
5618
+ flex-direction: column;
5619
+ gap: 0.4rem;
5620
+ }
5621
+
5622
+ .gist-export-url-row {
5623
+ display: flex;
5624
+ align-items: center;
5625
+ gap: 0.5rem;
5626
+ }
5627
+
5628
+ .gist-export-copy-btn {
5629
+ font-size: 1.15rem;
5630
+ flex: 0 0 auto;
5631
+ }
5632
+
5633
+ .gist-export-copy-btn.is-copied {
5634
+ color: var(--status-completed, var(--sl-color-success-600));
5635
+ }
5636
+
5637
+ .gist-export-footer {
5638
+ display: flex;
5639
+ justify-content: flex-end;
5640
+ width: 100%;
5641
+ }
5642
+
5643
+ .dialog-meta-row {
5644
+ display: flex;
5645
+ align-items: center;
5646
+ gap: 0.5rem;
5647
+ flex-wrap: wrap;
5648
+ font-size: 0.85rem;
4960
5649
  color: var(--sl-color-neutral-700);
4961
5650
  margin-bottom: 0.5rem;
4962
5651
  }
@@ -5341,7 +6030,14 @@ sl-tooltip.bead-tooltip::part(body) {
5341
6030
 
5342
6031
  /* ─── Models tab — model cards + env rows ──────────────────────────── */
5343
6032
  .models-cards {
5344
- grid-template-columns: repeat(auto-fill, minmax(440px, 1fr));
6033
+ /* Single column: a model card's action row carries six controls
6034
+ (Rename/Duplicate/Copy/Delete + Discard/Save) that need ~620px to sit on
6035
+ one line, so full-width cards stay roomy and never overflow. (Was a
6036
+ multi-column auto-fill grid at minmax(440px) — too narrow for the row.)
6037
+ For a capped two-column layout instead, use:
6038
+ repeat(auto-fill, minmax(640px, 1fr));
6039
+ .model-card-actions also wraps as a safety net for the dirty-state status. */
6040
+ grid-template-columns: 1fr;
5345
6041
  }
5346
6042
 
5347
6043
  .model-card {
@@ -5488,6 +6184,7 @@ sl-tooltip.bead-tooltip::part(body) {
5488
6184
  .model-card-actions {
5489
6185
  display: flex;
5490
6186
  align-items: center;
6187
+ flex-wrap: wrap;
5491
6188
  gap: 8px;
5492
6189
  margin-top: 14px;
5493
6190
  padding-top: 12px;
@@ -6982,6 +7679,25 @@ sl-dialog.markdown-dialog::part(body) {
6982
7679
  */
6983
7680
  .template-card .run-card-actions {
6984
7681
  margin-top: auto;
7682
+ /*
7683
+ * Left-align the action cluster (Duplicate + Export buttons) and push
7684
+ * Delete to the far right via `margin-left:auto` on the button itself
7685
+ * (see .template-card-delete-push). Scoped to template cards so run cards
7686
+ * keep the global flex-end alignment. nowrap keeps Delete on the same row
7687
+ * as the other buttons instead of wrapping it to its own line.
7688
+ */
7689
+ justify-content: flex-start;
7690
+ flex-wrap: nowrap;
7691
+ }
7692
+
7693
+ /*
7694
+ * Delete is always pinned to the far right of the template card's
7695
+ * action row, regardless of how many left-cluster buttons precede it
7696
+ * (count varies with has_overlays / builtin). `margin-left:auto`
7697
+ * absorbs the free space so it never relies on :last-child.
7698
+ */
7699
+ .template-card .run-card-actions .template-card-delete-push {
7700
+ margin-left: auto;
6985
7701
  }
6986
7702
 
6987
7703
  .template-tier-badge {
@@ -7320,6 +8036,28 @@ sl-dialog.markdown-dialog::part(body) {
7320
8036
  .editor-content--readonly .editor-section--json * {
7321
8037
  cursor: default !important;
7322
8038
  }
8039
+ /*
8040
+ * Exception: the Prompts tab is itself a read-only viewer, not an editor —
8041
+ * scrolling a prompt, expanding a stage's <sl-details>, and switching the
8042
+ * per-stage Agent/User sub-tabs are all read actions. The panel-wide
8043
+ * pointer-events:none + opacity:0.7 above would (a) swallow wheel events so
8044
+ * the inner 480px `.prompt-file-content` scroll pane can't be scrolled and
8045
+ * (b) bleach the prompt text, which is hard to read on a text-heavy surface.
8046
+ *
8047
+ * Exempt the Prompts panel entirely (it has no editable controls, so
8048
+ * re-enabling pointer-events can't allow edits). Both the outer panel and
8049
+ * the nested per-stage sub-tab panels are covered — the nested
8050
+ * `sl-tab-panel`s would otherwise re-match the base rule above. opacity is
8051
+ * reset on both levels because it compounds (0.7 × 0.7) and isn't inherited.
8052
+ */
8053
+ .editor-content--readonly sl-tab-panel[name="prompts"],
8054
+ .editor-content--readonly sl-tab-panel[name="prompts"] sl-tab-panel {
8055
+ pointer-events: auto;
8056
+ opacity: 1;
8057
+ }
8058
+ .editor-content--readonly sl-tab-panel[name="prompts"] * {
8059
+ cursor: auto !important;
8060
+ }
7323
8061
 
7324
8062
  /*
7325
8063
  * Editor uses the same .settings-tab-content / .settings-section-title /
@@ -7370,438 +8108,1890 @@ sl-dialog.markdown-dialog::part(body) {
7370
8108
  height: 14px;
7371
8109
  flex-shrink: 0;
7372
8110
  }
7373
- .editor-tab-group sl-tab-panel::part(base) {
7374
- padding: 16px 4px 0;
8111
+ .editor-tab-group sl-tab-panel::part(base) {
8112
+ padding: 16px 4px 0;
8113
+ }
8114
+
8115
+ /*
8116
+ * Pipeline tab holds three sections (Stage configuration, Loop
8117
+ * limits, Circuit breaker) on one panel — the same shape as the
8118
+ * Project Settings → Pipeline tab. Each section is its own
8119
+ * `.settings-tab-content` flex column with gap:20px between fields
8120
+ * but no margin above the section heading, so without an explicit
8121
+ * separator they jam right up against each other. Give the three
8122
+ * direct children real vertical breathing room.
8123
+ */
8124
+ .editor-pipeline-tab {
8125
+ display: flex;
8126
+ flex-direction: column;
8127
+ gap: 32px;
8128
+ }
8129
+ .editor-pipeline-tab > .settings-tab-content + .settings-tab-content {
8130
+ /* Visual separator on top of the gap so it reads as a fresh
8131
+ * section rather than a continuation of the previous one. */
8132
+ border-top: 1px solid var(--border-subtle, var(--border));
8133
+ padding-top: 24px;
8134
+ }
8135
+
8136
+ /*
8137
+ * Shared chrome for the template action dialogs (Create / Duplicate /
8138
+ * Rename / Import). Wraps the Settings-style form primitives so the
8139
+ * dialog body looks like a one-screen mini Settings tab.
8140
+ */
8141
+ .template-action-dialog::part(panel) {
8142
+ min-width: min(520px, 100vw - 32px);
8143
+ }
8144
+ .template-action-dialog .dialog-lead {
8145
+ margin: 0 0 14px;
8146
+ color: var(--fg-muted);
8147
+ font-size: 13px;
8148
+ line-height: 1.5;
8149
+ }
8150
+ .template-action-dialog .dialog-lead code {
8151
+ background: var(--bg-secondary);
8152
+ padding: 1px 5px;
8153
+ border-radius: 4px;
8154
+ font-size: 12px;
8155
+ }
8156
+ .template-action-dialog .settings-field {
8157
+ margin-bottom: 14px;
8158
+ }
8159
+ .template-action-dialog .dialog-error {
8160
+ margin-top: 8px;
8161
+ }
8162
+ .template-action-dialog .dialog-bundle-list {
8163
+ margin: 4px 0 0;
8164
+ padding-left: 18px;
8165
+ font-size: 13px;
8166
+ color: var(--fg-muted);
8167
+ }
8168
+ .template-action-dialog .dialog-bundle-list code {
8169
+ font-family: var(--sl-font-mono);
8170
+ color: var(--fg);
8171
+ }
8172
+
8173
+ .editor-content {
8174
+ flex: 1;
8175
+ overflow-y: auto;
8176
+ padding: 16px;
8177
+ display: flex;
8178
+ flex-direction: column;
8179
+ gap: 24px;
8180
+ }
8181
+
8182
+ /* Editor Sections */
8183
+
8184
+ .editor-section {
8185
+ max-width: 900px;
8186
+ }
8187
+
8188
+ .editor-section--json {
8189
+ max-width: 1000px;
8190
+ }
8191
+
8192
+ .section-header {
8193
+ display: flex;
8194
+ align-items: center;
8195
+ justify-content: space-between;
8196
+ margin-bottom: 12px;
8197
+ }
8198
+
8199
+ .section-title {
8200
+ font-size: 15px;
8201
+ font-weight: 600;
8202
+ margin: 0;
8203
+ color: var(--fg);
8204
+ }
8205
+
8206
+ /* Stages List */
8207
+
8208
+ .stages-list {
8209
+ display: flex;
8210
+ flex-direction: column;
8211
+ gap: 8px;
8212
+ }
8213
+
8214
+ .stage-row {
8215
+ display: flex;
8216
+ align-items: center;
8217
+ gap: 12px;
8218
+ padding: 12px;
8219
+ background: var(--bg-secondary);
8220
+ border: 1px solid var(--border);
8221
+ border-radius: var(--radius);
8222
+ transition: var(--transition-fast);
8223
+ }
8224
+
8225
+ .stage-row--disabled {
8226
+ opacity: 0.5;
8227
+ }
8228
+
8229
+ .stage-row-info {
8230
+ display: flex;
8231
+ align-items: center;
8232
+ gap: 8px;
8233
+ flex: 1;
8234
+ }
8235
+
8236
+ .stage-name {
8237
+ font-weight: 500;
8238
+ font-family: var(--sl-font-mono);
8239
+ }
8240
+
8241
+ .stage-row.disabled .stage-name {
8242
+ text-decoration: line-through;
8243
+ }
8244
+
8245
+ .stage-row-agent {
8246
+ width: 200px;
8247
+ }
8248
+
8249
+ /* Agents Matrix */
8250
+
8251
+ .agents-matrix {
8252
+ display: flex;
8253
+ flex-direction: column;
8254
+ gap: 8px;
8255
+ }
8256
+
8257
+ .agent-row {
8258
+ display: flex;
8259
+ align-items: center;
8260
+ gap: 12px;
8261
+ padding: 10px 12px;
8262
+ background: var(--bg-secondary);
8263
+ border: 1px solid var(--border);
8264
+ border-radius: var(--radius);
8265
+ }
8266
+
8267
+ .agent-name {
8268
+ flex: 0 0 100px;
8269
+ font-weight: 500;
8270
+ font-family: var(--sl-font-mono);
8271
+ }
8272
+
8273
+ .agent-fields {
8274
+ display: grid;
8275
+ grid-template-columns: 1fr 1fr 1fr;
8276
+ gap: 8px;
8277
+ flex: 1;
8278
+ }
8279
+
8280
+ .agent-field {
8281
+ display: flex;
8282
+ flex-direction: column;
8283
+ gap: 4px;
8284
+ }
8285
+
8286
+ /* Loops Grid */
8287
+
8288
+ .loops-grid {
8289
+ display: grid;
8290
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
8291
+ gap: 12px;
8292
+ }
8293
+
8294
+ .loop-field {
8295
+ display: flex;
8296
+ flex-direction: column;
8297
+ gap: 4px;
8298
+ }
8299
+
8300
+ /* Circuit Breaker Grid */
8301
+
8302
+ .circuit-breaker-grid {
8303
+ display: grid;
8304
+ grid-template-columns: 1fr 1fr;
8305
+ gap: 16px;
8306
+ }
8307
+
8308
+ .cb-field {
8309
+ display: flex;
8310
+ flex-direction: column;
8311
+ gap: 8px;
8312
+ }
8313
+
8314
+ .cb-field-row {
8315
+ display: flex;
8316
+ align-items: center;
8317
+ gap: 8px;
8318
+ }
8319
+
8320
+ /* Governance */
8321
+
8322
+ .governance-content {
8323
+ display: flex;
8324
+ flex-direction: column;
8325
+ gap: 24px;
8326
+ }
8327
+
8328
+ /* JSON Editor */
8329
+
8330
+ .json-editor-wrapper {
8331
+ background: var(--bg-secondary);
8332
+ border: 1px solid var(--border);
8333
+ border-radius: var(--radius);
8334
+ padding: 4px;
8335
+ }
8336
+
8337
+ .json-editor {
8338
+ font-family: var(--sl-font-mono);
8339
+ font-size: 13px;
8340
+ line-height: 1.5;
8341
+ min-height: 300px;
8342
+ resize: vertical;
8343
+ }
8344
+
8345
+ .json-editor-hint {
8346
+ font-size: 12px;
8347
+ color: var(--fg-muted);
8348
+ margin-top: 8px;
8349
+ }
8350
+
8351
+ /* Diff view styles */
8352
+ .diff-hint {
8353
+ font-size: 13px;
8354
+ color: var(--fg-muted);
8355
+ margin-bottom: 16px;
8356
+ line-height: 1.5;
8357
+ }
8358
+
8359
+ .diff-reset-icon {
8360
+ display: inline-block;
8361
+ vertical-align: middle;
8362
+ margin: 0 4px;
8363
+ color: var(--accent);
8364
+ }
8365
+
8366
+ .diff-no-changes {
8367
+ text-align: center;
8368
+ padding: 48px 24px;
8369
+ color: var(--status-completed);
8370
+ }
8371
+
8372
+ .diff-no-changes svg {
8373
+ margin-bottom: 16px;
8374
+ color: var(--status-completed);
8375
+ }
8376
+
8377
+ .diff-no-changes h3 {
8378
+ margin: 0 0 8px 0;
8379
+ font-size: 16px;
8380
+ font-weight: 600;
8381
+ }
8382
+
8383
+ .diff-no-changes p {
8384
+ margin: 0;
8385
+ color: var(--fg-muted);
8386
+ }
8387
+
8388
+ .diff-empty,
8389
+ .diff-loading {
8390
+ padding: 24px;
8391
+ text-align: center;
8392
+ color: var(--fg-muted);
8393
+ }
8394
+
8395
+ .diff-loading {
8396
+ display: flex;
8397
+ align-items: center;
8398
+ justify-content: center;
8399
+ gap: 12px;
8400
+ }
8401
+
8402
+ .diff-table-container {
8403
+ overflow-x: auto;
8404
+ border: 1px solid var(--border);
8405
+ border-radius: var(--radius);
8406
+ }
8407
+
8408
+ .diff-table {
8409
+ width: 100%;
8410
+ border-collapse: collapse;
8411
+ font-size: 13px;
8412
+ }
8413
+
8414
+ .diff-table th {
8415
+ text-align: left;
8416
+ padding: 10px 12px;
8417
+ background: var(--bg-secondary);
8418
+ border-bottom: 2px solid var(--border);
8419
+ font-weight: 600;
8420
+ color: var(--fg);
8421
+ position: sticky;
8422
+ top: 0;
8423
+ }
8424
+
8425
+ .diff-table td {
8426
+ padding: 10px 12px;
8427
+ border-bottom: 1px solid var(--border-subtle);
8428
+ vertical-align: top;
8429
+ }
8430
+
8431
+ .diff-row--changed {
8432
+ background: rgba(251, 191, 36, 0.05);
8433
+ }
8434
+
8435
+ .diff-row--changed .diff-path {
8436
+ font-weight: 600;
8437
+ }
8438
+
8439
+ .diff-path code {
8440
+ display: block;
8441
+ font-family: ui-monospace, 'SF Mono', 'Menlo', monospace;
8442
+ font-size: 11px;
8443
+ color: var(--fg-muted);
8444
+ margin-bottom: 4px;
8445
+ }
8446
+
8447
+ .diff-label {
8448
+ display: block;
8449
+ font-size: 12px;
8450
+ color: var(--fg);
8451
+ }
8452
+
8453
+ .diff-value {
8454
+ font-family: ui-monospace, 'SF Mono', 'Menlo', monospace;
8455
+ font-size: 12px;
8456
+ max-width: 300px;
8457
+ overflow-x: auto;
8458
+ white-space: pre-wrap;
8459
+ word-break: break-all;
8460
+ }
8461
+
8462
+ .diff-value--builtin {
8463
+ color: var(--fg-muted);
8464
+ background: var(--bg-tertiary);
8465
+ padding: 4px 8px;
8466
+ border-radius: 4px;
8467
+ }
8468
+
8469
+ .diff-value--current {
8470
+ color: var(--fg);
8471
+ background: rgba(59, 130, 246, 0.1);
8472
+ padding: 4px 8px;
8473
+ border-radius: 4px;
8474
+ }
8475
+
8476
+ .diff-actions {
8477
+ white-space: nowrap;
8478
+ }
8479
+
8480
+ /* Common field styles */
8481
+
8482
+ .field-label {
8483
+ font-size: 12px;
8484
+ font-weight: 500;
8485
+ color: var(--fg-muted);
8486
+ }
8487
+
8488
+ .field-hint {
8489
+ font-size: 12px;
8490
+ color: var(--fg-muted);
8491
+ }
8492
+
8493
+ /* Footer */
8494
+
8495
+ .editor-footer {
8496
+ display: flex;
8497
+ align-items: center;
8498
+ justify-content: flex-end;
8499
+ gap: 8px;
8500
+ padding: 12px 16px;
8501
+ border-top: 1px solid var(--border);
8502
+ background: var(--bg);
8503
+ position: sticky;
8504
+ bottom: 0;
8505
+ z-index: 10;
8506
+ }
8507
+
8508
+ /* Save alert */
8509
+
8510
+ .editor-save-alert {
8511
+ margin-bottom: 16px;
8512
+ }
8513
+
8514
+ .editor-validation-alert {
8515
+ margin-bottom: 16px;
8516
+ }
8517
+
8518
+ .validation-list {
8519
+ margin: 8px 0 0 16px;
8520
+ padding-left: 20px;
8521
+ font-size: 13px;
8522
+ }
8523
+
8524
+ .validation-list li {
8525
+ margin-bottom: 4px;
8526
+ }
8527
+
8528
+ .validation-list code {
8529
+ font-family: var(--sl-font-mono);
8530
+ background: var(--bg-tertiary);
8531
+ padding: 2px 4px;
8532
+ border-radius: 3px;
8533
+ }
8534
+
8535
+ /* Loading state */
8536
+
8537
+ .editor-loading {
8538
+ display: flex;
8539
+ align-items: center;
8540
+ justify-content: center;
8541
+ padding: 40px;
8542
+ font-size: 14px;
8543
+ color: var(--fg-muted);
8544
+ gap: 8px;
8545
+ }
8546
+
8547
+ /* ===========================================================================
8548
+ * Help mode (W-061 prototype, prototype/W-061-help-mode-toggle)
8549
+ *
8550
+ * Two concerns:
8551
+ * 1. The right-edge "Docs" tab (.help-edge-tab) — always visible at 75%
8552
+ * opacity, fully opaque on hover/active.
8553
+ * 2. Per-surface "?" badges (.help-badge) — hidden until body has the
8554
+ * .help-mode-active class.
8555
+ *
8556
+ * Colour: violet (~#7c3aed) — deliberately chosen so help mode reads as
8557
+ * "informational / secondary" and never competes with the blue used for
8558
+ * primary actions + running state, the green used for completed, the
8559
+ * orange used for caution, or the red used for failed.
8560
+ *
8561
+ * Animation: each badge radiates a slow sonar wave outward and fades to
8562
+ * transparent, like a discoverability signal. `prefers-reduced-motion`
8563
+ * collapses the wave to a static dim halo.
8564
+ * ===========================================================================
8565
+ */
8566
+
8567
+ /* --- Edge tab --------------------------------------------------------- */
8568
+
8569
+ .help-edge-tab-root {
8570
+ position: fixed;
8571
+ inset: 0;
8572
+ pointer-events: none;
8573
+ z-index: 1000;
8574
+ }
8575
+
8576
+ /* Vertical pill anchored ~100px from the top of the viewport (deliberately
8577
+ off-centre so it sits above the eye line and doesn't compete with
8578
+ sidebar/main content for the visual centre). */
8579
+ .help-edge-tab {
8580
+ position: fixed;
8581
+ right: 0;
8582
+ top: 100px;
8583
+ transform: translateX(0);
8584
+ transform-origin: right center;
8585
+ pointer-events: auto;
8586
+
8587
+ display: inline-flex;
8588
+ flex-direction: column;
8589
+ align-items: center;
8590
+ justify-content: center;
8591
+ /* Sized to wrap the rotated content (icon ~20px + 10px gap + "Docs"
8592
+ label ~38px ≈ 68px length, 20px max thickness). Height bumped +25%
8593
+ (84 → 105) per the user's request to give the rotated content more
8594
+ padding at the top and bottom of the tab. */
8595
+ width: 30px;
8596
+ height: 105px;
8597
+ padding: 0;
8598
+ border: 1px solid #c4b5fd; /* violet-300 */
8599
+ border-right: none;
8600
+ border-top-left-radius: 8px;
8601
+ border-bottom-left-radius: 8px;
8602
+ background: rgba(124, 58, 237, 0.1); /* violet-600 @ 10% */
8603
+ color: #5b21b6; /* violet-800 */
8604
+ font-size: 16px;
8605
+ font-weight: 600;
8606
+ letter-spacing: 0.04em;
8607
+ cursor: pointer;
8608
+ opacity: 0.75;
8609
+ box-shadow: -2px 0 8px rgba(0, 0, 0, 0.06);
8610
+ transition: opacity 160ms ease, background-color 120ms ease, color 120ms ease,
8611
+ transform 180ms ease, box-shadow 180ms ease;
8612
+ }
8613
+
8614
+ .help-edge-tab:hover,
8615
+ .help-edge-tab:focus-visible {
8616
+ opacity: 1;
8617
+ color: #4c1d95; /* violet-900 */
8618
+ background: rgba(124, 58, 237, 0.18);
8619
+ transform: translateX(-2px);
8620
+ box-shadow: -4px 0 12px rgba(0, 0, 0, 0.08);
8621
+ outline: none;
8622
+ }
8623
+
8624
+ .help-edge-tab:focus-visible {
8625
+ box-shadow: -4px 0 12px rgba(0, 0, 0, 0.08), 0 0 0 2px #7c3aed;
8626
+ }
8627
+
8628
+ .help-edge-tab--active {
8629
+ opacity: 1;
8630
+ background: #7c3aed; /* violet-600 */
8631
+ color: #fff;
8632
+ border-color: #6d28d9; /* violet-700 */
8633
+ }
8634
+
8635
+ .help-edge-tab--active:hover,
8636
+ .help-edge-tab--active:focus-visible {
8637
+ background: #6d28d9;
8638
+ color: #fff;
8639
+ }
8640
+
8641
+ /* Inner row is icon + "Docs". Rotating the entire row -90deg (counter-
8642
+ clockwise) makes both the icon and the label share the same rotation,
8643
+ reading bottom-to-top along the right edge (head tilted left). */
8644
+ .help-edge-tab__inner {
8645
+ display: inline-flex;
8646
+ flex-direction: row;
8647
+ align-items: center;
8648
+ gap: 10px;
8649
+ transform: rotate(-90deg);
8650
+ transform-origin: center center;
8651
+ white-space: nowrap;
8652
+ }
8653
+
8654
+ .help-edge-tab__icon {
8655
+ display: inline-flex;
8656
+ align-items: center;
8657
+ justify-content: center;
8658
+ }
8659
+
8660
+ .help-edge-tab__label {
8661
+ /* Matches the sidebar's WORCA wordmark (.logo-text) — JetBrains Mono
8662
+ family + bold weight + wide letter-spacing — so the affordance reads
8663
+ as part of the brand vocabulary rather than a generic side tab. */
8664
+ font-family: 'JetBrains Mono', 'SF Mono', 'Fira Code', monospace;
8665
+ font-weight: 700;
8666
+ letter-spacing: 0.08em;
8667
+ line-height: 1;
8668
+ }
8669
+
8670
+ /* --- Per-surface help badge ------------------------------------------- */
8671
+
8672
+ /* Hidden by default. Once help-mode-active flips on the body, every badge
8673
+ reveals at the top-right of its parent and emits a slow sonar wave that
8674
+ radiates outward then fades.
8675
+
8676
+ The badge is a real <a> — keyboard reachable when visible, opens the
8677
+ doc in a new tab, never depends on JS for click handling. */
8678
+ .help-badge {
8679
+ display: none;
8680
+ position: absolute;
8681
+ /* Vertically centred on the host's right edge — gives the sonar wave
8682
+ equal headroom above and below the badge so it doesn't overflow
8683
+ the host's bounding box. With disc 27px and wave max scale 1.5,
8684
+ max wave diameter is ~40px → fits inside any host ≥ 40px tall
8685
+ (typical sl-tab ~40px, panel headers larger). */
8686
+ top: 50%;
8687
+ right: 6px;
8688
+ transform: translateY(-50%);
8689
+ z-index: 5;
8690
+
8691
+ align-items: center;
8692
+ justify-content: center;
8693
+ /* Solid disc 27×27 — entire badge scaled up 50% (18 → 27). Icon, wave
8694
+ base, and clickable hit target all grow proportionally. */
8695
+ width: 27px;
8696
+ height: 27px;
8697
+ border-radius: 50%;
8698
+ /* Solid disc at 75% opacity — rgba on the background only so the
8699
+ ::after sonar wave's own opacity animation (0.55 → 0) isn't dimmed
8700
+ by parent inheritance. The white glyph stays fully visible. */
8701
+ background: rgba(124, 58, 237, 0.75); /* violet-600 @ 75% */
8702
+ color: #fff;
8703
+ text-decoration: none;
8704
+ transition: transform 120ms ease, background-color 120ms ease;
8705
+ }
8706
+
8707
+ /* Plain text "?" glyph — no container artifact (lucide's question-mark
8708
+ variants all wrap the ? in some outline shape). Sized + weighted to
8709
+ fill the 27px disc with a comfortable optical balance. */
8710
+ .help-badge__glyph {
8711
+ display: inline-flex;
8712
+ align-items: center;
8713
+ justify-content: center;
8714
+ font-family: var(--sl-font-sans, system-ui, sans-serif);
8715
+ font-size: 18px;
8716
+ font-weight: 700;
8717
+ line-height: 1;
8718
+ /* Most "?" glyphs sit slightly above the optical centre of their
8719
+ em-box because of the descender-free shape. Nudge down 1px so it
8720
+ reads centred in the disc. */
8721
+ margin-top: 1px;
8722
+ }
8723
+
8724
+ /* The sonar wave — a same-colour pseudo-element behind the badge that
8725
+ slowly grows outward and fades. Sits at z-index 0 (badge itself is
8726
+ at z-index 5) so it appears under the badge during expansion. */
8727
+ .help-badge::after {
8728
+ content: '';
8729
+ position: absolute;
8730
+ inset: 0;
8731
+ border-radius: 50%;
8732
+ background: #7c3aed;
8733
+ opacity: 0;
8734
+ z-index: -1;
8735
+ pointer-events: none;
8736
+ }
8737
+
8738
+ body.help-mode-active .help-badge {
8739
+ display: inline-flex;
8740
+ }
8741
+
8742
+ body.help-mode-active .help-badge::after {
8743
+ animation: help-badge-sonar 2.4s ease-out infinite;
8744
+ }
8745
+
8746
+ /* Auto-relative any direct parent of a badge so absolute positioning has
8747
+ a containing block. Modern browsers (Chrome 105+, Safari 15.4+,
8748
+ Firefox 121+) all support :has(). For sl-tab specifically, also force
8749
+ overflow: visible so the badge (and especially the sonar wave) isn't
8750
+ clipped against the tab strip's edge. */
8751
+ body.help-mode-active *:has(> .help-badge) {
8752
+ position: relative;
8753
+ }
8754
+
8755
+ body.help-mode-active sl-tab {
8756
+ overflow: visible;
8757
+ }
8758
+
8759
+ .help-badge:hover,
8760
+ .help-badge:focus-visible {
8761
+ /* Compose the hover lift with the vertical-centre translate so the
8762
+ badge doesn't jump when hovered. */
8763
+ transform: translateY(-50%) scale(1.1);
8764
+ /* Full opacity on hover so the affordance reads stronger. */
8765
+ background: #6d28d9; /* violet-700, opaque */
8766
+ outline: none;
8767
+ }
8768
+
8769
+ /* Sonar wave: scale 1 → 1.5 from the 27px badge → max diameter ~40px,
8770
+ centred on a badge that's vertically centred on the host. Wave fits
8771
+ the host's bounding box on any host ≥ 40px tall (typical sl-tab
8772
+ ~40px, panel headers larger; thin inline hosts may graze the edge). */
8773
+ @keyframes help-badge-sonar {
8774
+ 0% {
8775
+ transform: scale(1);
8776
+ opacity: 0.55;
8777
+ }
8778
+ 100% {
8779
+ transform: scale(1.5);
8780
+ opacity: 0;
8781
+ }
8782
+ }
8783
+
8784
+ @media (prefers-reduced-motion: reduce) {
8785
+ body.help-mode-active .help-badge::after {
8786
+ animation: none;
8787
+ opacity: 0.22;
8788
+ transform: scale(1.3);
8789
+ }
8790
+ .help-edge-tab {
8791
+ transition: none;
8792
+ }
8793
+ }
8794
+
8795
+ /* Dark-mode — violet stays violet, but we lift the idle background so it
8796
+ doesn't blend into dark panels. */
8797
+ :root[data-theme='dark'] .help-edge-tab,
8798
+ .sl-theme-dark .help-edge-tab {
8799
+ background: rgba(124, 58, 237, 0.22);
8800
+ color: #e9d5ff; /* violet-200 */
8801
+ border-color: #6d28d9;
8802
+ box-shadow: -2px 0 8px rgba(0, 0, 0, 0.4);
8803
+ }
8804
+
8805
+ :root[data-theme='dark'] .help-edge-tab:hover,
8806
+ :root[data-theme='dark'] .help-edge-tab:focus-visible,
8807
+ .sl-theme-dark .help-edge-tab:hover,
8808
+ .sl-theme-dark .help-edge-tab:focus-visible {
8809
+ background: rgba(124, 58, 237, 0.35);
8810
+ color: #f5f3ff;
8811
+ }
8812
+
8813
+ /* ── Overlays tab (pipelines-editor) ────────────────────────────────────── */
8814
+
8815
+ .overlay-stages {
8816
+ display: flex;
8817
+ flex-direction: column;
8818
+ gap: var(--sl-spacing-small);
8819
+ padding: var(--sl-spacing-medium);
8820
+ }
8821
+
8822
+ .overlay-stage-card {
8823
+ border-radius: var(--sl-border-radius-medium);
8824
+ }
8825
+
8826
+ .overlay-stage-card--disabled {
8827
+ padding: var(--sl-spacing-small) var(--sl-spacing-medium);
8828
+ border: 1px solid var(--sl-color-neutral-200);
8829
+ border-radius: var(--sl-border-radius-medium);
8830
+ opacity: 0.5;
8831
+ cursor: default;
8832
+ }
8833
+
8834
+ .overlay-stage-label {
8835
+ font-size: var(--sl-font-size-small);
8836
+ color: var(--sl-color-neutral-600);
8837
+ font-weight: var(--sl-font-weight-semibold);
8838
+ }
8839
+
8840
+ .overlay-file-label {
8841
+ font-size: var(--sl-font-size-x-small);
8842
+ color: var(--sl-color-neutral-500);
8843
+ margin-left: var(--sl-spacing-x-small);
8844
+ }
8845
+
8846
+ .overlay-stage-tabs {
8847
+ --track-color: transparent;
8848
+ }
8849
+
8850
+ .overlay-file-content.markdown-body {
8851
+ padding: var(--sl-spacing-medium);
8852
+ max-height: 480px;
8853
+ overflow-y: auto;
8854
+ font-size: var(--sl-font-size-small);
8855
+ }
8856
+
8857
+ .overlay-empty {
8858
+ color: var(--sl-color-neutral-500);
8859
+ font-size: var(--sl-font-size-small);
8860
+ padding: var(--sl-spacing-medium);
8861
+ }
8862
+
8863
+ /* ── Prompts tab (pipelines-editor-overlays.js) ─────────────────────────── */
8864
+
8865
+ .prompt-file-content.markdown-body {
8866
+ padding: var(--sl-spacing-medium);
8867
+ max-height: 480px;
8868
+ overflow-y: auto;
8869
+ font-size: var(--sl-font-size-small);
8870
+ }
8871
+
8872
+ .prompt-legend {
8873
+ display: flex;
8874
+ flex-wrap: wrap;
8875
+ align-items: center;
8876
+ gap: 6px;
8877
+ font-size: var(--sl-font-size-x-small);
8878
+ color: var(--sl-color-neutral-500);
8879
+ padding: 0 var(--sl-spacing-x-small) var(--sl-spacing-small);
8880
+ }
8881
+
8882
+ .prompt-source-badge {
8883
+ margin-left: var(--sl-spacing-x-small);
8884
+ }
8885
+
8886
+ .prompt-base-label,
8887
+ .prompt-customizations-label {
8888
+ font-size: var(--sl-font-size-x-small);
8889
+ font-weight: 600;
8890
+ text-transform: uppercase;
8891
+ letter-spacing: 0.04em;
8892
+ color: var(--sl-color-neutral-500);
8893
+ padding: var(--sl-spacing-small) var(--sl-spacing-medium) 0;
8894
+ }
8895
+
8896
+ .prompt-customizations-label {
8897
+ display: flex;
8898
+ align-items: center;
8899
+ gap: 4px;
8900
+ margin-top: var(--sl-spacing-small);
8901
+ }
8902
+
8903
+ .prompt-help-dot {
8904
+ display: inline-flex;
8905
+ align-items: center;
8906
+ justify-content: center;
8907
+ width: 14px;
8908
+ height: 14px;
8909
+ border-radius: 50%;
8910
+ background: var(--sl-color-neutral-300);
8911
+ color: var(--sl-color-neutral-700);
8912
+ font-size: 10px;
8913
+ font-weight: 700;
8914
+ cursor: help;
8915
+ }
8916
+
8917
+ /* Merge contributions: green = appended (additive), amber = overwrites a
8918
+ built-in section (caution). Follows the badge color language. */
8919
+ .prompt-merge-block {
8920
+ margin: var(--sl-spacing-x-small) var(--sl-spacing-medium);
8921
+ border-left: 3px solid var(--sl-color-neutral-300);
8922
+ border-radius: 0 var(--sl-border-radius-medium) var(--sl-border-radius-medium) 0;
8923
+ padding: var(--sl-spacing-x-small) var(--sl-spacing-small);
8924
+ }
8925
+
8926
+ .prompt-merge-block .prompt-file-content.markdown-body {
8927
+ padding: var(--sl-spacing-x-small) 0 0;
8928
+ max-height: none;
8929
+ }
8930
+
8931
+ .prompt-merge-append {
8932
+ background: var(--sl-color-success-50);
8933
+ border-left-color: var(--sl-color-success-500);
8934
+ }
8935
+
8936
+ .prompt-merge-overwrite {
8937
+ background: var(--sl-color-warning-50);
8938
+ border-left-color: var(--sl-color-warning-500);
8939
+ }
8940
+
8941
+ .prompt-merge-tag {
8942
+ font-size: var(--sl-font-size-x-small);
8943
+ color: var(--sl-color-neutral-600);
8944
+ }
8945
+
8946
+ .prompt-merge-tag code {
8947
+ font-size: var(--sl-font-size-x-small);
8948
+ }
8949
+
8950
+ .prompt-merge-verb {
8951
+ font-weight: 700;
8952
+ text-transform: uppercase;
8953
+ letter-spacing: 0.03em;
8954
+ cursor: help;
8955
+ }
8956
+
8957
+ /* ── File Access view (run-file-access.js) ──────────────────────────────── */
8958
+
8959
+ .run-file-access {
8960
+ --fa-file-col-width: 220px;
8961
+ --fa-cell-width: 80px;
8962
+ --fa-cell-height: 32px;
8963
+
8964
+ display: flex;
8965
+ flex-direction: column;
8966
+ gap: 16px;
8967
+ padding: 16px 20px;
8968
+ }
8969
+
8970
+ /* ── Loading / empty states ─────────────────────────────────────────────── */
8971
+
8972
+ .access-loading {
8973
+ color: var(--text-muted, #94a3b8);
8974
+ font-size: 13px;
8975
+ padding: 40px;
8976
+ text-align: center;
8977
+ }
8978
+
8979
+ .access-empty-state {
8980
+ padding: 40px;
8981
+ text-align: center;
8982
+ color: var(--fg, #0f172a);
8983
+ }
8984
+
8985
+ .access-empty-hint {
8986
+ font-size: 13px;
8987
+ color: var(--text-muted, #94a3b8);
8988
+ }
8989
+
8990
+ /* ── KPI strip ──────────────────────────────────────────────────────────── */
8991
+
8992
+ .access-kpi-strip {
8993
+ display: flex;
8994
+ flex-wrap: wrap;
8995
+ gap: 12px;
8996
+ }
8997
+
8998
+ .access-kpi-card {
8999
+ display: flex;
9000
+ flex-direction: column;
9001
+ gap: 2px;
9002
+ padding: 10px 16px;
9003
+ background: var(--bg-secondary, #f8fafc);
9004
+ border: 1px solid var(--border, #e2e8f0);
9005
+ border-radius: var(--radius, 6px);
9006
+ min-width: 100px;
9007
+ }
9008
+
9009
+ .access-kpi-card--amber {
9010
+ border-color: #f59e0b;
9011
+ background: rgba(245, 158, 11, 0.06);
9012
+ }
9013
+
9014
+ /* Read = green, Written = blue — same semantics as the matrix op pills. */
9015
+ .access-kpi-card--read {
9016
+ border-color: rgba(34, 197, 94, 0.4);
9017
+ background: rgba(34, 197, 94, 0.06);
9018
+ }
9019
+
9020
+ .access-kpi-card--read .access-kpi-label {
9021
+ color: #15803d;
9022
+ }
9023
+
9024
+ .access-kpi-card--write {
9025
+ border-color: rgba(59, 130, 246, 0.4);
9026
+ background: rgba(59, 130, 246, 0.06);
9027
+ }
9028
+
9029
+ .access-kpi-card--write .access-kpi-label {
9030
+ color: #1d4ed8;
9031
+ }
9032
+
9033
+ .access-kpi-label {
9034
+ font-size: 11px;
9035
+ text-transform: uppercase;
9036
+ letter-spacing: 0.04em;
9037
+ color: var(--text-muted, #94a3b8);
9038
+ font-weight: 500;
9039
+ }
9040
+
9041
+ .access-kpi-value {
9042
+ font-size: 15px;
9043
+ font-weight: 600;
9044
+ color: var(--fg, #0f172a);
9045
+ font-variant-numeric: tabular-nums;
9046
+ }
9047
+
9048
+ /* ── Controls bar ───────────────────────────────────────────────────────── */
9049
+
9050
+ .access-controls {
9051
+ display: flex;
9052
+ align-items: center;
9053
+ gap: 10px;
9054
+ flex-wrap: wrap;
9055
+ }
9056
+
9057
+ .access-heatmap-toggle {
9058
+ display: inline-flex;
9059
+ align-items: center;
9060
+ gap: 5px;
9061
+ padding: 4px 10px;
9062
+ border: 1px solid var(--border, #e2e8f0);
9063
+ border-radius: var(--radius, 6px);
9064
+ background: var(--bg-secondary, #f8fafc);
9065
+ color: var(--text-muted, #94a3b8);
9066
+ font-size: 12px;
9067
+ cursor: pointer;
9068
+ transition: background var(--transition-fast, 150ms ease),
9069
+ color var(--transition-fast, 150ms ease),
9070
+ border-color var(--transition-fast, 150ms ease);
9071
+ }
9072
+
9073
+ .access-heatmap-toggle--active {
9074
+ background: rgba(249, 115, 22, 0.12);
9075
+ border-color: #f97316;
9076
+ color: #c2410c;
9077
+ }
9078
+
9079
+ .access-chips {
9080
+ display: flex;
9081
+ gap: 6px;
9082
+ }
9083
+
9084
+ .access-chip {
9085
+ display: inline-flex;
9086
+ align-items: center;
9087
+ gap: 5px;
9088
+ padding: 4px 10px;
9089
+ border: 1px solid var(--border, #e2e8f0);
9090
+ border-radius: 20px;
9091
+ background: var(--bg-secondary, #f8fafc);
9092
+ color: var(--text-muted, #94a3b8);
9093
+ font-size: 12px;
9094
+ cursor: pointer;
9095
+ transition: background var(--transition-fast, 150ms ease),
9096
+ color var(--transition-fast, 150ms ease),
9097
+ border-color var(--transition-fast, 150ms ease);
9098
+ }
9099
+
9100
+ .access-chip--active.access-chip--reads {
9101
+ background: rgba(34, 197, 94, 0.1);
9102
+ border-color: #22c55e;
9103
+ color: #15803d;
9104
+ }
9105
+
9106
+ .access-chip--active.access-chip--writes {
9107
+ background: rgba(59, 130, 246, 0.1);
9108
+ border-color: #3b82f6;
9109
+ color: #3b82f6;
9110
+ }
9111
+
9112
+ .access-path-filter {
9113
+ flex: 1;
9114
+ min-width: 140px;
9115
+ max-width: 260px;
9116
+ padding: 4px 10px;
9117
+ border: 1px solid var(--border, #e2e8f0);
9118
+ border-radius: var(--radius, 6px);
9119
+ background: var(--bg, #fff);
9120
+ color: var(--fg, #0f172a);
9121
+ font-size: 12px;
9122
+ }
9123
+
9124
+ .access-path-filter:focus {
9125
+ outline: none;
9126
+ border-color: var(--accent, #3b82f6);
9127
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
9128
+ }
9129
+
9130
+ .access-sort-select {
9131
+ padding: 4px 8px;
9132
+ border: 1px solid var(--border, #e2e8f0);
9133
+ border-radius: var(--radius, 6px);
9134
+ background: var(--bg-secondary, #f8fafc);
9135
+ color: var(--fg, #0f172a);
9136
+ font-size: 12px;
9137
+ cursor: pointer;
9138
+ }
9139
+
9140
+ /* ── Treetable container ────────────────────────────────────────────────── */
9141
+
9142
+ .access-treetable {
9143
+ overflow-x: auto;
9144
+ overflow-y: auto;
9145
+ max-height: 540px;
9146
+ border: 1px solid var(--border, #e2e8f0);
9147
+ border-radius: var(--radius, 6px);
9148
+ background: var(--bg, #fff);
9149
+ font-size: 12px;
9150
+ }
9151
+
9152
+ /* ── Table header (sticky top) ──────────────────────────────────────────── */
9153
+
9154
+ .access-table-header {
9155
+ position: sticky;
9156
+ top: 0;
9157
+ z-index: 3;
9158
+ background: var(--bg-secondary, #f8fafc);
9159
+ border-bottom: 1px solid var(--border, #e2e8f0);
9160
+ }
9161
+
9162
+ /* Stage group label row — a grid that shares the table's column template so
9163
+ each stage label spans exactly its data columns. Empty spacers hold the
9164
+ file and Σ tracks. */
9165
+ .access-stage-groups {
9166
+ display: grid;
9167
+ grid-template-columns: var(--fa-grid);
9168
+ width: max-content;
9169
+ border-bottom: 1px solid var(--border, #e2e8f0);
9170
+ }
9171
+
9172
+ /* Empty spacer cells over the file and Σ columns of the stage-label row. */
9173
+ .access-stage-spacer {
9174
+ min-height: 0;
9175
+ }
9176
+
9177
+ .access-stage-group-header {
9178
+ display: inline-flex;
9179
+ align-items: center;
9180
+ justify-content: center;
9181
+ gap: 4px;
9182
+ min-width: 0;
9183
+ padding: 4px 8px;
9184
+ background: transparent;
9185
+ border: none;
9186
+ border-right: 1px solid var(--border, #e2e8f0);
9187
+ color: var(--fg, #0f172a);
9188
+ font-size: 11px;
9189
+ font-weight: 600;
9190
+ text-transform: uppercase;
9191
+ letter-spacing: 0.04em;
9192
+ cursor: pointer;
9193
+ white-space: nowrap;
9194
+ overflow: hidden;
9195
+ }
9196
+
9197
+ .access-stage-group-header .access-stage-name {
9198
+ overflow: hidden;
9199
+ text-overflow: ellipsis;
9200
+ }
9201
+
9202
+ .access-stage-group-header:hover {
9203
+ background: var(--border, #e2e8f0);
9204
+ }
9205
+
9206
+ .access-stage-group-header--collapsed {
9207
+ background: rgba(59, 130, 246, 0.06);
9208
+ color: #3b82f6;
9209
+ }
9210
+
9211
+ /* Column headers row — same grid template as the stage-label and body rows. */
9212
+ .access-col-headers {
9213
+ display: grid;
9214
+ grid-template-columns: var(--fa-grid);
9215
+ width: max-content;
9216
+ }
9217
+
9218
+ .access-col-header {
9219
+ min-width: 0;
9220
+ min-height: var(--fa-cell-height, 32px);
9221
+ padding: 4px 6px;
9222
+ display: flex;
9223
+ flex-direction: column;
9224
+ align-items: center;
9225
+ justify-content: center;
9226
+ font-size: 11px;
9227
+ color: var(--text-muted, #94a3b8);
9228
+ border-right: 1px solid rgba(226, 232, 240, 0.5);
9229
+ white-space: nowrap;
9230
+ overflow: hidden;
9231
+ text-overflow: ellipsis;
9232
+ }
9233
+
9234
+ .access-col-agent {
9235
+ max-width: 100%;
9236
+ overflow: hidden;
9237
+ text-overflow: ellipsis;
9238
+ }
9239
+
9240
+ .access-col-header:last-child {
9241
+ border-right: none;
9242
+ }
9243
+
9244
+ /* File column header — sticky left, wider than data cells */
9245
+ .access-col-file-header {
9246
+ position: sticky;
9247
+ left: 0;
9248
+ z-index: 4;
9249
+ width: var(--fa-file-col-width, 220px);
9250
+ background: var(--bg-secondary, #f8fafc);
9251
+ font-weight: 600;
9252
+ color: var(--fg, #0f172a);
9253
+ justify-content: flex-start;
9254
+ border-right: 2px solid var(--border, #e2e8f0);
9255
+ }
9256
+
9257
+ .access-col-header--collapsed {
9258
+ background: rgba(59, 130, 246, 0.06);
9259
+ color: #3b82f6;
9260
+ font-style: italic;
9261
+ }
9262
+
9263
+ .access-sigma-header {
9264
+ font-weight: 600;
9265
+ color: var(--fg, #0f172a);
9266
+ background: var(--bg-secondary, #f8fafc);
9267
+ }
9268
+
9269
+ .access-col-iter {
9270
+ font-size: 10px;
9271
+ color: var(--text-muted, #94a3b8);
9272
+ }
9273
+
9274
+ /* ── Table body rows ────────────────────────────────────────────────────── */
9275
+
9276
+ .access-table-body {
9277
+ display: flex;
9278
+ flex-direction: column;
9279
+ width: max-content;
9280
+ }
9281
+
9282
+ /* Each row is its own grid sharing the table column template, so cells line up
9283
+ with the header columns exactly (no per-stage width drift). */
9284
+ .access-row {
9285
+ display: grid;
9286
+ grid-template-columns: var(--fa-grid);
9287
+ width: max-content;
9288
+ align-items: stretch;
9289
+ min-height: var(--fa-cell-height, 32px);
9290
+ border-bottom: 1px solid rgba(226, 232, 240, 0.5);
9291
+ }
9292
+
9293
+ .access-row:last-child {
9294
+ border-bottom: none;
9295
+ }
9296
+
9297
+ .access-row--dir {
9298
+ background: var(--bg-secondary, #f8fafc);
9299
+ font-weight: 500;
9300
+ }
9301
+
9302
+ .access-row--file {
9303
+ background: var(--bg, #fff);
9304
+ }
9305
+
9306
+ .access-row--file:hover {
9307
+ background: rgba(59, 130, 246, 0.04);
9308
+ }
9309
+
9310
+ /* ── Cells ──────────────────────────────────────────────────────────────── */
9311
+
9312
+ .access-cell {
9313
+ min-width: 0;
9314
+ display: flex;
9315
+ align-items: center;
9316
+ justify-content: center;
9317
+ padding: 3px 6px;
9318
+ border-right: 1px solid rgba(226, 232, 240, 0.5);
9319
+ }
9320
+
9321
+ /* Aggregated Σ cell shown for a collapsed stage — holds the same op pills. */
9322
+ .access-cell--stage-agg {
9323
+ flex-wrap: wrap;
9324
+ gap: 3px;
9325
+ background: rgba(59, 130, 246, 0.04);
9326
+ }
9327
+
9328
+ .access-cell:last-child {
9329
+ border-right: none;
9330
+ }
9331
+
9332
+ /* Sticky file name column — left:0, inherits row background */
9333
+ .access-cell--file {
9334
+ position: sticky;
9335
+ left: 0;
9336
+ z-index: 1;
9337
+ width: var(--fa-file-col-width, 220px);
9338
+ justify-content: flex-start;
9339
+ gap: 6px;
9340
+ padding: 3px 8px;
9341
+ /* One indent step == a dir's [chevron 18px + gap 6px], so a child's content
9342
+ (file name, or sub-folder chevron) starts exactly under its parent's
9343
+ folder icon. */
9344
+ padding-left: calc(8px + var(--depth, 0) * 24px);
9345
+ background: inherit;
9346
+ border-right: 2px solid var(--border, #e2e8f0);
9347
+ }
9348
+
9349
+ .access-row--dir .access-cell--file {
9350
+ background: var(--bg-secondary, #f8fafc);
9351
+ }
9352
+
9353
+ .access-row--file .access-cell--file {
9354
+ background: var(--bg, #fff);
9355
+ }
9356
+
9357
+ .access-row--file:hover .access-cell--file {
9358
+ background: rgba(59, 130, 246, 0.04);
9359
+ }
9360
+
9361
+ .access-cell--empty {
9362
+ color: var(--text-muted, #94a3b8);
9363
+ font-size: 16px;
9364
+ line-height: 1;
9365
+ }
9366
+
9367
+ .access-cell--clickable {
9368
+ cursor: pointer;
9369
+ }
9370
+
9371
+ .access-cell--clickable:focus-visible {
9372
+ outline: 2px solid var(--sl-color-primary-600, #2563eb);
9373
+ outline-offset: -2px;
9374
+ border-radius: 2px;
9375
+ }
9376
+
9377
+ .access-cell--sigma {
9378
+ flex-wrap: wrap;
9379
+ gap: 3px;
9380
+ background: var(--bg-secondary, #f8fafc);
9381
+ }
9382
+
9383
+ /* ── Dir toggle button ──────────────────────────────────────────────────── */
9384
+
9385
+ .access-dir-toggle {
9386
+ display: inline-flex;
9387
+ align-items: center;
9388
+ justify-content: center;
9389
+ width: 18px;
9390
+ height: 18px;
9391
+ flex-shrink: 0;
9392
+ padding: 0;
9393
+ border: none;
9394
+ background: transparent;
9395
+ color: var(--text-muted, #94a3b8);
9396
+ cursor: pointer;
9397
+ border-radius: 3px;
9398
+ }
9399
+
9400
+ .access-dir-toggle:hover {
9401
+ background: var(--border, #e2e8f0);
9402
+ color: var(--fg, #0f172a);
9403
+ }
9404
+
9405
+ /* ── File name + category colors ────────────────────────────────────────── */
9406
+
9407
+ .access-file-name {
9408
+ font-size: 12px;
9409
+ overflow: hidden;
9410
+ text-overflow: ellipsis;
9411
+ white-space: nowrap;
9412
+ max-width: 100%;
9413
+ }
9414
+
9415
+ /* read → blue (informational, no change) */
9416
+ .access-file-name--read {
9417
+ color: #3b82f6;
7375
9418
  }
7376
9419
 
7377
- /*
7378
- * Pipeline tab holds three sections (Stage configuration, Loop
7379
- * limits, Circuit breaker) on one panel — the same shape as the
7380
- * Project Settings → Pipeline tab. Each section is its own
7381
- * `.settings-tab-content` flex column with gap:20px between fields
7382
- * but no margin above the section heading, so without an explicit
7383
- * separator they jam right up against each other. Give the three
7384
- * direct children real vertical breathing room.
7385
- */
7386
- .editor-pipeline-tab {
7387
- display: flex;
7388
- flex-direction: column;
7389
- gap: 32px;
9420
+ /* write → green (positive, modified) */
9421
+ .access-file-name--write {
9422
+ color: #22c55e;
7390
9423
  }
7391
- .editor-pipeline-tab > .settings-tab-content + .settings-tab-content {
7392
- /* Visual separator on top of the gap so it reads as a fresh
7393
- * section rather than a continuation of the previous one. */
7394
- border-top: 1px solid var(--border-subtle, var(--border));
7395
- padding-top: 24px;
9424
+
9425
+ /* leaked amber (caution, untracked write) */
9426
+ .access-file-name--leaked {
9427
+ color: #f59e0b;
7396
9428
  }
7397
9429
 
7398
- /*
7399
- * Shared chrome for the template action dialogs (Create / Duplicate /
7400
- * Rename / Import). Wraps the Settings-style form primitives so the
7401
- * dialog body looks like a one-screen mini Settings tab.
7402
- */
7403
- .template-action-dialog::part(panel) {
7404
- min-width: min(520px, 100vw - 32px);
9430
+ /* ✎ git-tracked write decoration */
9431
+ .access-tracked-icon {
9432
+ font-size: 11px;
9433
+ color: var(--text-muted, #94a3b8);
9434
+ margin-left: 3px;
9435
+ flex-shrink: 0;
7405
9436
  }
7406
- .template-action-dialog .dialog-lead {
7407
- margin: 0 0 14px;
7408
- color: var(--fg-muted);
7409
- font-size: 13px;
7410
- line-height: 1.5;
9437
+
9438
+ /* ── Heatmap shading ────────────────────────────────────────────────────── */
9439
+
9440
+ /* When heatmap mode is active, shade non-empty data cells by op-count density.
9441
+ --heat (0..1) is set per-cell by the view when _heatmap is true. */
9442
+ .access-treetable--heatmap
9443
+ .access-cell:not(.access-cell--empty):not(.access-cell--file):not(.access-cell--sigma):not(.access-cell--stage-agg) {
9444
+ background-color: rgba(249, 115, 22, calc(var(--heat, 0) * 0.28));
7411
9445
  }
7412
- .template-action-dialog .dialog-lead code {
7413
- background: var(--bg-secondary);
7414
- padding: 1px 5px;
9446
+
9447
+ /* ── Operation badges (R / W / RW) ─────────────────────────────────────── */
9448
+
9449
+ .access-badge {
9450
+ display: inline-flex;
9451
+ align-items: center;
9452
+ gap: 2px;
9453
+ padding: 1px 6px;
7415
9454
  border-radius: 4px;
7416
- font-size: 12px;
9455
+ font-size: 10px;
9456
+ font-weight: 700;
9457
+ letter-spacing: 0.02em;
9458
+ line-height: 1.4;
9459
+ white-space: nowrap;
9460
+ border: 1px solid transparent;
9461
+ font-variant-numeric: tabular-nums;
7417
9462
  }
7418
- .template-action-dialog .settings-field {
7419
- margin-bottom: 14px;
9463
+
9464
+ /* R = green (read) */
9465
+ .access-badge--read {
9466
+ background: rgba(34, 197, 94, 0.12);
9467
+ color: #15803d;
9468
+ border-color: rgba(34, 197, 94, 0.3);
7420
9469
  }
7421
- .template-action-dialog .dialog-error {
7422
- margin-top: 8px;
9470
+
9471
+ /* W = blue (write) */
9472
+ .access-badge--write {
9473
+ background: rgba(59, 130, 246, 0.12);
9474
+ color: #1d4ed8;
9475
+ border-color: rgba(59, 130, 246, 0.3);
7423
9476
  }
7424
- .template-action-dialog .dialog-bundle-list {
7425
- margin: 4px 0 0;
7426
- padding-left: 18px;
7427
- font-size: 13px;
7428
- color: var(--fg-muted);
9477
+
9478
+ /* broad scan — amber caution */
9479
+ .access-badge--broad {
9480
+ background: rgba(245, 158, 11, 0.12);
9481
+ color: #b45309;
9482
+ border-color: rgba(245, 158, 11, 0.3);
7429
9483
  }
7430
- .template-action-dialog .dialog-bundle-list code {
7431
- font-family: var(--sl-font-mono);
7432
- color: var(--fg);
9484
+
9485
+ /* zero-hit search — red */
9486
+ .access-badge--zero-hit {
9487
+ background: rgba(239, 68, 68, 0.1);
9488
+ color: #b91c1c;
9489
+ border-color: rgba(239, 68, 68, 0.3);
7433
9490
  }
7434
9491
 
7435
- .editor-content {
7436
- flex: 1;
7437
- overflow-y: auto;
7438
- padding: 16px;
7439
- display: flex;
7440
- flex-direction: column;
7441
- gap: 24px;
9492
+ .access-op-count {
9493
+ font-size: 8px;
9494
+ font-weight: 500;
9495
+ vertical-align: super;
9496
+ line-height: 1;
9497
+ opacity: 0.85;
7442
9498
  }
7443
9499
 
7444
- /* Editor Sections */
9500
+ /* ── Sigma (Σ) column ───────────────────────────────────────────────────── */
7445
9501
 
7446
- .editor-section {
7447
- max-width: 900px;
9502
+ .access-sigma-read {
9503
+ color: #1d4ed8;
9504
+ font-weight: 600;
9505
+ font-size: 11px;
7448
9506
  }
7449
9507
 
7450
- .editor-section--json {
7451
- max-width: 1000px;
9508
+ .access-sigma-write {
9509
+ color: #15803d;
9510
+ font-weight: 600;
9511
+ font-size: 11px;
7452
9512
  }
7453
9513
 
7454
- .section-header {
9514
+ /* ── Searches lane ──────────────────────────────────────────────────────── */
9515
+
9516
+ .access-searches {
7455
9517
  display: flex;
7456
- align-items: center;
7457
- justify-content: space-between;
7458
- margin-bottom: 12px;
9518
+ flex-direction: column;
9519
+ gap: 10px;
7459
9520
  }
7460
9521
 
7461
- .section-title {
7462
- font-size: 15px;
9522
+ .access-searches-title {
9523
+ font-size: 13px;
7463
9524
  font-weight: 600;
9525
+ color: var(--fg, #0f172a);
7464
9526
  margin: 0;
7465
- color: var(--fg);
7466
9527
  }
7467
9528
 
7468
- /* Stages List */
9529
+ .access-searches-empty {
9530
+ font-size: 13px;
9531
+ color: var(--text-muted, #94a3b8);
9532
+ margin: 0;
9533
+ }
7469
9534
 
7470
- .stages-list {
7471
- display: flex;
7472
- flex-direction: column;
7473
- gap: 8px;
9535
+ .access-searches-table {
9536
+ width: 100%;
9537
+ border-collapse: collapse;
9538
+ font-size: 12px;
9539
+ /* Fixed layout + explicit column widths so the per-stage grouped tables all
9540
+ line up with each other (and with the ungrouped table). Pattern is the one
9541
+ unsized column, so it absorbs the remaining width. */
9542
+ table-layout: fixed;
7474
9543
  }
7475
9544
 
7476
- .stage-row {
7477
- display: flex;
7478
- align-items: center;
7479
- gap: 12px;
7480
- padding: 12px;
7481
- background: var(--bg-secondary);
7482
- border: 1px solid var(--border);
7483
- border-radius: var(--radius);
7484
- transition: var(--transition-fast);
9545
+ .access-searches-table th:nth-child(1),
9546
+ .access-searches-table td:nth-child(1) {
9547
+ width: 130px;
7485
9548
  }
7486
9549
 
7487
- .stage-row--disabled {
7488
- opacity: 0.5;
9550
+ .access-searches-table th:nth-child(2),
9551
+ .access-searches-table td:nth-child(2) {
9552
+ width: 90px;
7489
9553
  }
7490
9554
 
7491
- .stage-row-info {
7492
- display: flex;
7493
- align-items: center;
7494
- gap: 8px;
7495
- flex: 1;
9555
+ .access-searches-table th:nth-child(4),
9556
+ .access-searches-table td:nth-child(4) {
9557
+ width: 200px;
7496
9558
  }
7497
9559
 
7498
- .stage-name {
9560
+ .access-searches-table th:nth-child(5),
9561
+ .access-searches-table td:nth-child(5) {
9562
+ width: 70px;
9563
+ }
9564
+
9565
+ .access-searches-table th:nth-child(6),
9566
+ .access-searches-table td:nth-child(6) {
9567
+ width: 150px;
9568
+ }
9569
+
9570
+ /* Long scope paths shouldn't break the fixed columns. */
9571
+ .access-searches-table td:nth-child(4) {
9572
+ overflow: hidden;
9573
+ text-overflow: ellipsis;
9574
+ white-space: nowrap;
9575
+ }
9576
+
9577
+ .access-searches-table th {
9578
+ text-align: left;
9579
+ padding: 6px 10px;
9580
+ font-size: 11px;
9581
+ text-transform: uppercase;
9582
+ letter-spacing: 0.04em;
9583
+ color: var(--text-muted, #94a3b8);
7499
9584
  font-weight: 500;
7500
- font-family: var(--sl-font-mono);
9585
+ border-bottom: 2px solid var(--border, #e2e8f0);
7501
9586
  }
7502
9587
 
7503
- .stage-row.disabled .stage-name {
7504
- text-decoration: line-through;
9588
+ .access-searches-table td {
9589
+ padding: 6px 10px;
9590
+ border-bottom: 1px solid rgba(226, 232, 240, 0.6);
9591
+ vertical-align: middle;
7505
9592
  }
7506
9593
 
7507
- .stage-row-agent {
7508
- width: 200px;
9594
+ .access-search-row:last-child td {
9595
+ border-bottom: none;
7509
9596
  }
7510
9597
 
7511
- /* Agents Matrix */
9598
+ .access-search-pattern {
9599
+ font-family: var(--sl-font-mono, monospace);
9600
+ font-size: 11px;
9601
+ color: var(--fg, #0f172a);
9602
+ overflow: hidden;
9603
+ text-overflow: ellipsis;
9604
+ white-space: nowrap;
9605
+ }
7512
9606
 
7513
- .agents-matrix {
7514
- display: flex;
7515
- flex-direction: column;
7516
- gap: 8px;
9607
+ /* ── Graph-queries lane (graphify / CRG) ────────────────────────────────── */
9608
+
9609
+ .access-graph-lane {
9610
+ margin-top: 18px;
7517
9611
  }
7518
9612
 
7519
- .agent-row {
7520
- display: flex;
9613
+ /* Graph table columns: Stage · Engine · Op · Query(flex). Only fields both
9614
+ engines reliably expose. Override the searches widths (higher specificity
9615
+ via the doubled class). */
9616
+ .access-searches-table.access-graph-table td:nth-child(3),
9617
+ .access-searches-table.access-graph-table th:nth-child(3) {
9618
+ width: 120px;
9619
+ }
9620
+
9621
+ .access-searches-table.access-graph-table td:nth-child(4),
9622
+ .access-searches-table.access-graph-table th:nth-child(4) {
9623
+ width: auto;
9624
+ }
9625
+
9626
+ .access-engine-badge {
9627
+ display: inline-flex;
7521
9628
  align-items: center;
7522
- gap: 12px;
7523
- padding: 10px 12px;
7524
- background: var(--bg-secondary);
7525
- border: 1px solid var(--border);
7526
- border-radius: var(--radius);
9629
+ padding: 1px 7px;
9630
+ border-radius: 4px;
9631
+ font-size: 10px;
9632
+ font-weight: 600;
9633
+ border: 1px solid transparent;
7527
9634
  }
7528
9635
 
7529
- .agent-name {
7530
- flex: 0 0 100px;
7531
- font-weight: 500;
7532
- font-family: var(--sl-font-mono);
9636
+ .access-engine-badge--graphify {
9637
+ background: rgba(8, 145, 178, 0.12);
9638
+ color: #0e7490;
9639
+ border-color: rgba(8, 145, 178, 0.3);
7533
9640
  }
7534
9641
 
7535
- .agent-fields {
7536
- display: grid;
7537
- grid-template-columns: 1fr 1fr 1fr;
7538
- gap: 8px;
7539
- flex: 1;
9642
+ .access-engine-badge--crg {
9643
+ background: rgba(99, 102, 241, 0.12);
9644
+ color: #4338ca;
9645
+ border-color: rgba(99, 102, 241, 0.3);
7540
9646
  }
7541
9647
 
7542
- .agent-field {
9648
+ .access-searches-header {
7543
9649
  display: flex;
7544
- flex-direction: column;
7545
- gap: 4px;
9650
+ align-items: center;
9651
+ gap: 10px;
7546
9652
  }
7547
9653
 
7548
- /* Loops Grid */
9654
+ .access-searches-group-toggle {
9655
+ padding: 2px 8px;
9656
+ font-size: 11px;
9657
+ border: 1px solid var(--border, #e2e8f0);
9658
+ border-radius: 4px;
9659
+ background: var(--bg-secondary, #f8fafc);
9660
+ color: var(--text-muted, #94a3b8);
9661
+ cursor: pointer;
9662
+ }
7549
9663
 
7550
- .loops-grid {
7551
- display: grid;
7552
- grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
9664
+ .access-searches-group-toggle--active {
9665
+ background: rgba(234, 179, 8, 0.12);
9666
+ border-color: rgba(234, 179, 8, 0.4);
9667
+ color: #854d0e;
9668
+ }
9669
+
9670
+ .access-searches-groups {
9671
+ display: flex;
9672
+ flex-direction: column;
7553
9673
  gap: 12px;
7554
9674
  }
7555
9675
 
7556
- .loop-field {
9676
+ .access-searches-stage-group {
7557
9677
  display: flex;
7558
9678
  flex-direction: column;
7559
9679
  gap: 4px;
7560
9680
  }
7561
9681
 
7562
- /* Circuit Breaker Grid */
7563
-
7564
- .circuit-breaker-grid {
7565
- display: grid;
7566
- grid-template-columns: 1fr 1fr;
7567
- gap: 16px;
9682
+ .access-searches-stage-header {
9683
+ font-size: 11px;
9684
+ font-weight: 600;
9685
+ text-transform: uppercase;
9686
+ letter-spacing: 0.05em;
9687
+ color: var(--text-muted, #94a3b8);
9688
+ padding: 4px 10px;
9689
+ background: var(--bg-secondary, #f8fafc);
9690
+ border-radius: 4px;
7568
9691
  }
7569
9692
 
7570
- .cb-field {
7571
- display: flex;
7572
- flex-direction: column;
7573
- gap: 8px;
9693
+ /* ── Scope-dot: yellow hint on dir rows that appear as a search scope ──── */
9694
+
9695
+ .access-scope-dot {
9696
+ display: inline-block;
9697
+ width: 6px;
9698
+ height: 6px;
9699
+ border-radius: 50%;
9700
+ background: #eab308;
9701
+ margin-left: 4px;
9702
+ flex-shrink: 0;
9703
+ vertical-align: middle;
7574
9704
  }
7575
9705
 
7576
- .cb-field-row {
9706
+ /* ── Capture integrity strip ────────────────────────────────────────────── */
9707
+
9708
+ .access-capture-strip {
7577
9709
  display: flex;
7578
9710
  align-items: center;
7579
- gap: 8px;
9711
+ gap: 16px;
9712
+ padding: 8px 14px;
9713
+ background: var(--bg-secondary, #f8fafc);
9714
+ border: 1px solid var(--border, #e2e8f0);
9715
+ border-radius: var(--radius, 6px);
9716
+ font-size: 12px;
9717
+ color: var(--text-muted, #94a3b8);
7580
9718
  }
7581
9719
 
7582
- /* Governance */
9720
+ .access-capture-strip--degraded {
9721
+ border-color: #f59e0b;
9722
+ background: rgba(245, 158, 11, 0.06);
9723
+ color: #b45309;
9724
+ }
7583
9725
 
7584
- .governance-content {
9726
+ .access-capture-label {
9727
+ font-weight: 600;
9728
+ text-transform: uppercase;
9729
+ letter-spacing: 0.04em;
9730
+ font-size: 11px;
9731
+ }
9732
+
9733
+ .access-capture-leakage {
9734
+ font-variant-numeric: tabular-nums;
9735
+ }
9736
+
9737
+ .access-capture-oracle {
7585
9738
  display: flex;
7586
- flex-direction: column;
7587
- gap: 24px;
9739
+ align-items: center;
9740
+ gap: 4px;
7588
9741
  }
7589
9742
 
7590
- /* JSON Editor */
9743
+ /* ── Dark mode ──────────────────────────────────────────────────────────── */
7591
9744
 
7592
- .json-editor-wrapper {
7593
- background: var(--bg-secondary);
7594
- border: 1px solid var(--border);
7595
- border-radius: var(--radius);
7596
- padding: 4px;
9745
+ [data-theme="dark"] .access-file-name--read {
9746
+ color: #93c5fd; /* blue-300 */
7597
9747
  }
7598
9748
 
7599
- .json-editor {
7600
- font-family: var(--sl-font-mono);
7601
- font-size: 13px;
7602
- line-height: 1.5;
7603
- min-height: 300px;
7604
- resize: vertical;
9749
+ [data-theme="dark"] .access-file-name--write {
9750
+ color: #86efac; /* green-300 */
7605
9751
  }
7606
9752
 
7607
- .json-editor-hint {
7608
- font-size: 12px;
7609
- color: var(--fg-muted);
7610
- margin-top: 8px;
9753
+ [data-theme="dark"] .access-file-name--leaked {
9754
+ color: #fcd34d; /* amber-300 */
7611
9755
  }
7612
9756
 
7613
- /* Diff view styles */
7614
- .diff-hint {
7615
- font-size: 13px;
7616
- color: var(--fg-muted);
7617
- margin-bottom: 16px;
7618
- line-height: 1.5;
9757
+ [data-theme="dark"] .access-badge--read {
9758
+ background: rgba(59, 130, 246, 0.2);
9759
+ color: #93c5fd;
9760
+ border-color: rgba(59, 130, 246, 0.4);
7619
9761
  }
7620
9762
 
7621
- .diff-reset-icon {
7622
- display: inline-block;
7623
- vertical-align: middle;
7624
- margin: 0 4px;
7625
- color: var(--accent);
9763
+ [data-theme="dark"] .access-badge--write {
9764
+ background: rgba(34, 197, 94, 0.2);
9765
+ color: #86efac;
9766
+ border-color: rgba(34, 197, 94, 0.4);
7626
9767
  }
7627
9768
 
7628
- .diff-no-changes {
7629
- text-align: center;
7630
- padding: 48px 24px;
7631
- color: var(--status-completed);
9769
+ [data-theme="dark"] .access-badge--rw {
9770
+ background: rgba(20, 184, 166, 0.2);
9771
+ color: #5eead4;
9772
+ border-color: rgba(20, 184, 166, 0.4);
7632
9773
  }
7633
9774
 
7634
- .diff-no-changes svg {
7635
- margin-bottom: 16px;
7636
- color: var(--status-completed);
9775
+ [data-theme="dark"] .access-sigma-read {
9776
+ color: #93c5fd;
7637
9777
  }
7638
9778
 
7639
- .diff-no-changes h3 {
7640
- margin: 0 0 8px 0;
7641
- font-size: 16px;
7642
- font-weight: 600;
9779
+ [data-theme="dark"] .access-sigma-write {
9780
+ color: #86efac;
7643
9781
  }
7644
9782
 
7645
- .diff-no-changes p {
7646
- margin: 0;
7647
- color: var(--fg-muted);
9783
+ /* ── File name button (reset) ────────────────────────────────────────────── */
9784
+
9785
+ .access-file-name-btn {
9786
+ appearance: none;
9787
+ -webkit-appearance: none;
9788
+ background: none;
9789
+ border: none;
9790
+ padding: 0;
9791
+ cursor: pointer;
9792
+ font: inherit;
9793
+ text-align: left;
9794
+ color: inherit;
7648
9795
  }
7649
9796
 
7650
- .diff-empty,
7651
- .diff-loading {
7652
- padding: 24px;
7653
- text-align: center;
7654
- color: var(--fg-muted);
9797
+
9798
+ /* ── Drawer panels (file-history / cell-detail) ─────────────────────────── */
9799
+
9800
+ .access-file-drawer,
9801
+ .access-cell-drawer {
9802
+ position: fixed;
9803
+ top: 0;
9804
+ right: 0;
9805
+ bottom: 0;
9806
+ width: 360px;
9807
+ display: flex;
9808
+ flex-direction: column;
9809
+ background: var(--surface);
9810
+ border-left: 1px solid var(--border);
9811
+ box-shadow: var(--shadow-lg), -2px 0 16px rgba(0, 0, 0, 0.08);
9812
+ z-index: 200;
9813
+ overflow: hidden;
7655
9814
  }
7656
9815
 
7657
- .diff-loading {
9816
+ .access-drawer-header {
7658
9817
  display: flex;
7659
9818
  align-items: center;
7660
- justify-content: center;
7661
9819
  gap: 12px;
9820
+ padding: 12px 16px;
9821
+ border-bottom: 1px solid var(--border);
9822
+ flex-shrink: 0;
7662
9823
  }
7663
9824
 
7664
- .diff-table-container {
7665
- overflow-x: auto;
7666
- border: 1px solid var(--border);
7667
- border-radius: var(--radius);
9825
+ .access-drawer-title {
9826
+ flex: 1;
9827
+ min-width: 0;
9828
+ font-size: 13px;
9829
+ font-weight: 600;
9830
+ color: var(--fg);
9831
+ overflow: hidden;
9832
+ text-overflow: ellipsis;
9833
+ white-space: nowrap;
7668
9834
  }
7669
9835
 
7670
- .diff-table {
7671
- width: 100%;
7672
- border-collapse: collapse;
7673
- font-size: 13px;
9836
+ .access-drawer-close {
9837
+ display: inline-flex;
9838
+ align-items: center;
9839
+ justify-content: center;
9840
+ flex-shrink: 0;
9841
+ width: 28px;
9842
+ height: 28px;
9843
+ border: none;
9844
+ background: transparent;
9845
+ color: var(--muted);
9846
+ cursor: pointer;
9847
+ border-radius: 4px;
9848
+ font-size: 14px;
9849
+ line-height: 1;
7674
9850
  }
7675
9851
 
7676
- .diff-table th {
7677
- text-align: left;
7678
- padding: 10px 12px;
9852
+ .access-drawer-close:hover {
7679
9853
  background: var(--bg-secondary);
7680
- border-bottom: 2px solid var(--border);
7681
- font-weight: 600;
7682
9854
  color: var(--fg);
7683
- position: sticky;
7684
- top: 0;
7685
9855
  }
7686
9856
 
7687
- .diff-table td {
7688
- padding: 10px 12px;
7689
- border-bottom: 1px solid var(--border-subtle);
7690
- vertical-align: top;
9857
+ .access-drawer-body {
9858
+ flex: 1;
9859
+ overflow-y: auto;
9860
+ padding: 16px;
9861
+ display: flex;
9862
+ flex-direction: column;
9863
+ gap: 12px;
7691
9864
  }
7692
9865
 
7693
- .diff-row--changed {
7694
- background: rgba(251, 191, 36, 0.05);
9866
+ .access-drawer-section-label {
9867
+ margin: 0 0 8px;
9868
+ font-size: 11px;
9869
+ font-weight: 600;
9870
+ text-transform: uppercase;
9871
+ letter-spacing: 0.05em;
9872
+ color: var(--muted);
7695
9873
  }
7696
9874
 
7697
- .diff-row--changed .diff-path {
7698
- font-weight: 600;
9875
+ .access-drawer-empty {
9876
+ margin: 0;
9877
+ font-size: 13px;
9878
+ color: var(--muted);
7699
9879
  }
7700
9880
 
7701
- .diff-path code {
7702
- display: block;
7703
- font-family: ui-monospace, 'SF Mono', 'Menlo', monospace;
7704
- font-size: 11px;
7705
- color: var(--fg-muted);
7706
- margin-bottom: 4px;
9881
+ /* ── File history list ───────────────────────────────────────────────────── */
9882
+
9883
+ .access-file-history-list {
9884
+ list-style: none;
9885
+ margin: 0;
9886
+ padding: 0;
9887
+ display: flex;
9888
+ flex-direction: column;
9889
+ gap: 6px;
7707
9890
  }
7708
9891
 
7709
- .diff-label {
7710
- display: block;
9892
+ .access-file-history-item {
9893
+ display: flex;
9894
+ flex-wrap: wrap;
9895
+ align-items: center;
9896
+ gap: 4px;
9897
+ padding: 8px 10px;
9898
+ border: 1px solid var(--border);
9899
+ border-radius: 6px;
9900
+ background: var(--bg-secondary);
7711
9901
  font-size: 12px;
7712
- color: var(--fg);
7713
9902
  }
7714
9903
 
7715
- .diff-value {
7716
- font-family: ui-monospace, 'SF Mono', 'Menlo', monospace;
7717
- font-size: 12px;
7718
- max-width: 300px;
7719
- overflow-x: auto;
7720
- white-space: pre-wrap;
7721
- word-break: break-all;
9904
+ .access-history-stage {
9905
+ font-weight: 600;
9906
+ color: var(--fg);
7722
9907
  }
7723
9908
 
7724
- .diff-value--builtin {
7725
- color: var(--fg-muted);
7726
- background: var(--bg-tertiary);
7727
- padding: 4px 8px;
7728
- border-radius: 4px;
9909
+ .access-history-iter {
9910
+ color: var(--muted);
7729
9911
  }
7730
9912
 
7731
- .diff-value--current {
7732
- color: var(--fg);
7733
- background: rgba(59, 130, 246, 0.1);
7734
- padding: 4px 8px;
7735
- border-radius: 4px;
9913
+ .access-history-bead {
9914
+ font-family: 'JetBrains Mono', 'SF Mono', 'Fira Code', monospace;
9915
+ font-size: 11px;
9916
+ padding: 1px 5px;
9917
+ border-radius: 3px;
9918
+ background: var(--bg-tertiary);
9919
+ color: var(--muted);
7736
9920
  }
7737
9921
 
7738
- .diff-actions {
9922
+ .access-history-agent {
9923
+ flex: 1;
9924
+ min-width: 0;
9925
+ overflow: hidden;
9926
+ text-overflow: ellipsis;
7739
9927
  white-space: nowrap;
9928
+ color: var(--fg);
7740
9929
  }
7741
9930
 
7742
- /* Common field styles */
7743
-
7744
- .field-label {
7745
- font-size: 12px;
7746
- font-weight: 500;
7747
- color: var(--fg-muted);
9931
+ .access-history-read {
9932
+ font-size: 11px;
9933
+ font-weight: 600;
9934
+ padding: 1px 5px;
9935
+ border-radius: 3px;
9936
+ background: rgba(59, 130, 246, 0.12);
9937
+ color: #1d4ed8;
7748
9938
  }
7749
9939
 
7750
- .field-hint {
7751
- font-size: 12px;
7752
- color: var(--fg-muted);
9940
+ .access-history-write {
9941
+ font-size: 11px;
9942
+ font-weight: 600;
9943
+ padding: 1px 5px;
9944
+ border-radius: 3px;
9945
+ background: rgba(34, 197, 94, 0.12);
9946
+ color: #15803d;
7753
9947
  }
7754
9948
 
7755
- /* Footer */
9949
+ /* ── Timeline link ──────────────────────────────────────────────────────── */
7756
9950
 
7757
- .editor-footer {
7758
- display: flex;
7759
- align-items: center;
7760
- justify-content: flex-end;
7761
- gap: 8px;
7762
- padding: 12px 16px;
7763
- border-top: 1px solid var(--border);
7764
- background: var(--bg);
7765
- position: sticky;
7766
- bottom: 0;
7767
- z-index: 10;
9951
+ .access-timeline-link {
9952
+ align-self: flex-start;
9953
+ border: none;
9954
+ background: transparent;
9955
+ padding: 0;
9956
+ font-size: 12px;
9957
+ color: var(--accent);
9958
+ cursor: pointer;
9959
+ text-decoration: underline;
9960
+ text-underline-offset: 2px;
7768
9961
  }
7769
9962
 
7770
- /* Save alert */
7771
-
7772
- .editor-save-alert {
7773
- margin-bottom: 16px;
9963
+ .access-timeline-link:hover {
9964
+ color: var(--accent-hover);
7774
9965
  }
7775
9966
 
7776
- .editor-validation-alert {
7777
- margin-bottom: 16px;
7778
- }
9967
+ /* ── Cell detail definition list ────────────────────────────────────────── */
7779
9968
 
7780
- .validation-list {
7781
- margin: 8px 0 0 16px;
7782
- padding-left: 20px;
9969
+ .access-cell-detail {
9970
+ display: grid;
9971
+ grid-template-columns: auto 1fr;
9972
+ gap: 4px 12px;
9973
+ margin: 0;
7783
9974
  font-size: 13px;
7784
9975
  }
7785
9976
 
7786
- .validation-list li {
7787
- margin-bottom: 4px;
9977
+ .access-cell-detail dt {
9978
+ font-weight: 600;
9979
+ color: var(--muted);
9980
+ white-space: nowrap;
7788
9981
  }
7789
9982
 
7790
- .validation-list code {
7791
- font-family: var(--sl-font-mono);
7792
- background: var(--bg-tertiary);
7793
- padding: 2px 4px;
7794
- border-radius: 3px;
9983
+ .access-cell-detail dd {
9984
+ margin: 0;
9985
+ color: var(--fg);
9986
+ word-break: break-all;
7795
9987
  }
7796
9988
 
7797
- /* Loading state */
9989
+ [data-theme="dark"] .access-history-read {
9990
+ background: rgba(59, 130, 246, 0.2);
9991
+ color: #93c5fd;
9992
+ }
7798
9993
 
7799
- .editor-loading {
7800
- display: flex;
7801
- align-items: center;
7802
- justify-content: center;
7803
- padding: 40px;
7804
- font-size: 14px;
7805
- color: var(--fg-muted);
7806
- gap: 8px;
9994
+ [data-theme="dark"] .access-history-write {
9995
+ background: rgba(34, 197, 94, 0.2);
9996
+ color: #86efac;
7807
9997
  }