@in-the-loop-labs/pair-review 3.5.2 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +4 -0
  2. package/package.json +1 -1
  3. package/plugin/.claude-plugin/plugin.json +1 -1
  4. package/plugin-code-critic/.claude-plugin/plugin.json +1 -1
  5. package/public/css/analysis-config.css +1807 -0
  6. package/public/css/pr.css +1029 -2169
  7. package/public/index.html +11 -0
  8. package/public/js/components/AIPanel.js +39 -23
  9. package/public/js/components/AdvancedConfigTab.js +56 -4
  10. package/public/js/components/AnalysisConfigModal.js +41 -25
  11. package/public/js/components/ChatPanel.js +163 -3
  12. package/public/js/components/KeyboardShortcuts.js +10 -26
  13. package/public/js/components/ReviewModal.js +135 -13
  14. package/public/js/components/TourBar.js +248 -0
  15. package/public/js/components/VoiceCentricConfigTab.js +36 -0
  16. package/public/js/index.js +175 -16
  17. package/public/js/local.js +64 -8
  18. package/public/js/modules/cancel-background-job.js +183 -0
  19. package/public/js/modules/hunk-summary-renderer.js +116 -0
  20. package/public/js/modules/storage-cleanup.js +16 -0
  21. package/public/js/modules/suggestion-manager.js +25 -1
  22. package/public/js/modules/tour-renderer.js +755 -0
  23. package/public/js/pr.js +1826 -56
  24. package/public/js/repo-links.js +328 -0
  25. package/public/js/utils/modal-detection.js +77 -0
  26. package/public/js/utils/provider-model.js +88 -0
  27. package/public/js/utils/storage-keys.js +50 -0
  28. package/public/local.html +24 -0
  29. package/public/pr.html +24 -0
  30. package/public/repo-settings.html +1 -0
  31. package/public/setup.html +2 -0
  32. package/src/ai/abort-signal-wiring.js +130 -0
  33. package/src/ai/analyzer.js +125 -18
  34. package/src/ai/background-queue.js +290 -0
  35. package/src/ai/claude-cli.js +1 -1
  36. package/src/ai/claude-provider.js +50 -7
  37. package/src/ai/codex-provider.js +28 -5
  38. package/src/ai/copilot-provider.js +22 -3
  39. package/src/ai/cursor-agent-provider.js +22 -6
  40. package/src/ai/executable-provider.js +4 -19
  41. package/src/ai/gemini-provider.js +22 -5
  42. package/src/ai/hunk-hashing.js +161 -0
  43. package/src/ai/index.js +2 -0
  44. package/src/ai/opencode-provider.js +21 -5
  45. package/src/ai/pi-provider.js +21 -5
  46. package/src/ai/prompts/hunk-summary.js +199 -0
  47. package/src/ai/prompts/tour.js +232 -0
  48. package/src/ai/provider.js +21 -1
  49. package/src/ai/summary-generator.js +469 -0
  50. package/src/ai/tour-generator.js +568 -0
  51. package/src/config.js +778 -10
  52. package/src/database.js +282 -1
  53. package/src/external/github-adapter.js +114 -25
  54. package/src/git/base-branch.js +11 -4
  55. package/src/github/client.js +482 -588
  56. package/src/github/errors.js +55 -0
  57. package/src/github/impl/graphql/pending-review-comments.js +230 -0
  58. package/src/github/impl/graphql/pending-review.js +153 -0
  59. package/src/github/impl/graphql/review-lifecycle.js +161 -0
  60. package/src/github/impl/graphql/stack-walker.js +210 -0
  61. package/src/github/impl/host/pending-review-comments.js +338 -0
  62. package/src/github/impl/rest/pending-review.js +251 -0
  63. package/src/github/impl/rest/review-lifecycle.js +226 -0
  64. package/src/github/impl/rest/stack-walker.js +309 -0
  65. package/src/github/operations/pending-review-comments.js +79 -0
  66. package/src/github/operations/pending-review.js +89 -0
  67. package/src/github/operations/review-lifecycle.js +126 -0
  68. package/src/github/operations/stack-walker.js +87 -0
  69. package/src/github/parser.js +230 -4
  70. package/src/github/stack-walker.js +14 -189
  71. package/src/links/repo-links.js +230 -0
  72. package/src/local-review.js +201 -172
  73. package/src/main.js +133 -30
  74. package/src/routes/analyses.js +30 -7
  75. package/src/routes/bulk-analysis-configs.js +295 -0
  76. package/src/routes/config.js +118 -3
  77. package/src/routes/context-files.js +2 -29
  78. package/src/routes/external-comments.js +20 -10
  79. package/src/routes/github-collections.js +3 -1
  80. package/src/routes/local.js +410 -13
  81. package/src/routes/mcp.js +47 -4
  82. package/src/routes/middleware/validate-review-id.js +53 -0
  83. package/src/routes/pr.js +556 -71
  84. package/src/routes/reviews.js +145 -29
  85. package/src/routes/setup.js +8 -3
  86. package/src/routes/stack-analysis.js +33 -9
  87. package/src/routes/worktrees.js +3 -2
  88. package/src/server.js +2 -0
  89. package/src/setup/pr-setup.js +37 -11
  90. package/src/setup/stack-setup.js +13 -3
  91. package/src/single-port.js +6 -3
  92. package/src/utils/diff-hunks.js +65 -0
  93. package/src/utils/json-extractor.js +5 -2
package/public/css/pr.css CHANGED
@@ -1445,7 +1445,8 @@
1445
1445
 
1446
1446
  /* File header comment button and file header chat button */
1447
1447
  .file-header-comment-btn,
1448
- .file-header-chat-btn {
1448
+ .file-header-chat-btn,
1449
+ .file-header-summary-toggle {
1449
1450
  display: flex;
1450
1451
  align-items: center;
1451
1452
  justify-content: center;
@@ -1459,38 +1460,66 @@
1459
1460
  color: var(--color-text-secondary, #656d76);
1460
1461
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
1461
1462
  flex-shrink: 0;
1463
+ position: relative;
1462
1464
  }
1463
1465
 
1464
1466
  .file-header-comment-btn:hover,
1465
- .file-header-chat-btn:hover {
1467
+ .file-header-chat-btn:hover,
1468
+ .file-header-summary-toggle:not([disabled]):hover {
1466
1469
  background-color: var(--color-accent-bg, rgba(9, 105, 218, 0.1));
1467
1470
  border-color: var(--color-accent-primary, #0969da);
1468
1471
  color: var(--color-accent-primary, #0969da);
1469
1472
  }
1470
1473
 
1471
1474
  .file-header-comment-btn:active,
1472
- .file-header-chat-btn:active {
1475
+ .file-header-chat-btn:active,
1476
+ .file-header-summary-toggle:not([disabled]):active {
1473
1477
  background-color: var(--color-accent-bg, rgba(9, 105, 218, 0.15));
1474
1478
  }
1475
1479
 
1476
1480
  .file-header-comment-btn svg,
1477
- .file-header-chat-btn svg {
1481
+ .file-header-chat-btn svg,
1482
+ .file-header-summary-toggle svg {
1478
1483
  width: 16px;
1479
1484
  height: 16px;
1480
1485
  }
1481
1486
 
1482
1487
  [data-theme="dark"] .file-header-comment-btn,
1483
- [data-theme="dark"] .file-header-chat-btn {
1488
+ [data-theme="dark"] .file-header-chat-btn,
1489
+ [data-theme="dark"] .file-header-summary-toggle {
1484
1490
  color: #8b949e;
1485
1491
  }
1486
1492
 
1487
1493
  [data-theme="dark"] .file-header-comment-btn:hover,
1488
- [data-theme="dark"] .file-header-chat-btn:hover {
1494
+ [data-theme="dark"] .file-header-chat-btn:hover,
1495
+ [data-theme="dark"] .file-header-summary-toggle:not([disabled]):hover {
1489
1496
  background-color: rgba(56, 139, 253, 0.15);
1490
1497
  border-color: #58a6ff;
1491
1498
  color: #58a6ff;
1492
1499
  }
1493
1500
 
1501
+ /* Disabled state — no summaries available for this file */
1502
+ .file-header-summary-toggle[disabled] {
1503
+ opacity: 0.4;
1504
+ cursor: not-allowed;
1505
+ }
1506
+
1507
+ /* Off state — summaries hidden for this file. Shows the same slash overlay
1508
+ used by the toolbar toggle so the on/off state is visually distinct. */
1509
+ .file-header-summary-toggle.summaries-off:not([disabled])::after {
1510
+ content: '';
1511
+ position: absolute;
1512
+ top: 50%;
1513
+ left: 18%;
1514
+ right: 18%;
1515
+ height: 2px;
1516
+ background-color: currentColor;
1517
+ transform: rotate(-25deg);
1518
+ transform-origin: center;
1519
+ pointer-events: none;
1520
+ border-radius: 1px;
1521
+ }
1522
+
1494
1523
  /* Has comments state - filled icon with accent color */
1495
1524
  .file-header-comment-btn.has-comments {
1496
1525
  color: var(--color-accent-primary, #0969da);
@@ -2657,164 +2686,6 @@ tr.newly-expanded .d2h-code-line-ctn {
2657
2686
  background-color: var(--color-bg-secondary);
2658
2687
  }
2659
2688
 
2660
- /* Modal Styles */
2661
- .modal-overlay {
2662
- position: fixed;
2663
- top: 0;
2664
- left: 0;
2665
- right: 0;
2666
- bottom: 0;
2667
- z-index: 1000;
2668
- display: flex;
2669
- align-items: center;
2670
- justify-content: center;
2671
- }
2672
-
2673
- .modal-backdrop {
2674
- position: absolute;
2675
- top: 0;
2676
- left: 0;
2677
- right: 0;
2678
- bottom: 0;
2679
- background: rgba(0, 0, 0, 0.5);
2680
- cursor: pointer;
2681
- }
2682
-
2683
- .modal-container {
2684
- position: relative;
2685
- width: min(960px, 90vw);
2686
- height: 520px; /* Increased from 420px to show all 4 levels without scrolling */
2687
- background: var(--color-bg-primary, #ffffff);
2688
- border-radius: 20px;
2689
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
2690
- display: flex;
2691
- flex-direction: column;
2692
- overflow: hidden;
2693
- border: 1px solid var(--color-border-default, #d1d9e0);
2694
- }
2695
-
2696
- .modal-header {
2697
- display: flex;
2698
- align-items: center;
2699
- justify-content: space-between;
2700
- padding: 24px 24px 16px 24px;
2701
- border-bottom: 1px solid var(--ai-border, rgba(217, 119, 6, 0.3));
2702
- background: linear-gradient(to right, var(--ai-subtle, rgba(217, 119, 6, 0.08)), transparent);
2703
- }
2704
-
2705
- .modal-header h3 {
2706
- font-size: 18px;
2707
- font-weight: 600;
2708
- color: var(--ai-primary, #d97706);
2709
- margin: 0;
2710
- }
2711
-
2712
- .modal-close-btn {
2713
- background: none;
2714
- border: none;
2715
- padding: 4px;
2716
- cursor: pointer;
2717
- border-radius: 4px;
2718
- color: var(--color-text-secondary, #656d76);
2719
- display: flex;
2720
- align-items: center;
2721
- justify-content: center;
2722
- }
2723
-
2724
- .modal-close-btn:hover {
2725
- background: var(--color-bg-tertiary, #f6f8fa);
2726
- color: var(--color-text-primary, #24292f);
2727
- }
2728
-
2729
- .modal-body {
2730
- padding: 16px 24px;
2731
- flex: 1;
2732
- overflow-y: auto;
2733
- }
2734
-
2735
- .modal-footer {
2736
- padding: 16px 24px 24px 24px;
2737
- display: flex;
2738
- gap: 8px;
2739
- justify-content: flex-end;
2740
- border-top: 1px solid var(--color-border-default, #d1d9e0);
2741
- }
2742
-
2743
- .modal-footer .btn {
2744
- padding: 8px 16px;
2745
- font-size: 14px;
2746
- }
2747
-
2748
- /* Confirm dialog buttons should be centered */
2749
- .confirm-dialog-container .modal-footer {
2750
- justify-content: center;
2751
- }
2752
-
2753
- /* When a secondary button is visible (3 buttons), widen and stack vertically.
2754
- column-reverse puts Confirm (primary) on top, Cancel on bottom. */
2755
- .confirm-dialog-container.has-secondary {
2756
- min-width: 440px;
2757
- }
2758
-
2759
- .confirm-dialog-container.has-secondary .modal-footer {
2760
- flex-direction: column-reverse;
2761
- align-items: stretch;
2762
- }
2763
-
2764
- .confirm-dialog-container.has-secondary .modal-footer .btn {
2765
- display: flex;
2766
- flex-direction: column;
2767
- align-items: center;
2768
- }
2769
-
2770
- /* Button description subtitles */
2771
- .modal-footer .btn .btn-label {
2772
- display: block;
2773
- }
2774
-
2775
- .modal-footer .btn .btn-desc {
2776
- display: block;
2777
- font-size: 12px;
2778
- font-weight: normal;
2779
- opacity: 0.7;
2780
- margin-top: 2px;
2781
- }
2782
-
2783
- /* Dialogs spawned from within other modals need higher z-index */
2784
- #text-input-dialog,
2785
- #confirm-dialog {
2786
- z-index: 10000; /* Must stack above analysis-config-overlay (1100) */
2787
- }
2788
-
2789
- .text-input-dialog-field {
2790
- display: flex;
2791
- flex-direction: column;
2792
- gap: 6px;
2793
- }
2794
-
2795
- .text-input-dialog-field label {
2796
- font-size: 13px;
2797
- font-weight: 600;
2798
- color: var(--color-fg-default, #1f2328);
2799
- }
2800
-
2801
- .text-input-dialog-field input {
2802
- padding: 8px 12px;
2803
- font-size: 14px;
2804
- border: 1px solid var(--color-border-default, #d1d9e0);
2805
- border-radius: 6px;
2806
- background: var(--color-bg-primary, #ffffff);
2807
- color: var(--color-fg-default, #1f2328);
2808
- outline: none;
2809
- width: 100%;
2810
- box-sizing: border-box;
2811
- }
2812
-
2813
- .text-input-dialog-field input:focus {
2814
- border-color: var(--color-accent-fg, #0969da);
2815
- box-shadow: 0 0 0 3px rgba(9, 105, 218, 0.3);
2816
- }
2817
-
2818
2689
  /* Status Indicator Styles */
2819
2690
  .status-indicator {
2820
2691
  display: none;
@@ -2892,43 +2763,6 @@ tr.newly-expanded .d2h-code-line-ctn {
2892
2763
  color: var(--color-text-secondary, #656d76);
2893
2764
  }
2894
2765
 
2895
- /* Dark theme adjustments for modal */
2896
- [data-theme="dark"] .modal-container {
2897
- background: var(--color-bg-primary);
2898
- border-color: var(--color-border-default);
2899
- }
2900
-
2901
- [data-theme="dark"] .modal-header {
2902
- border-color: var(--color-border-default);
2903
- }
2904
-
2905
- [data-theme="dark"] .modal-footer {
2906
- border-color: var(--color-border-default);
2907
- }
2908
-
2909
- [data-theme="dark"] .modal-close-btn:hover {
2910
- background: var(--color-bg-secondary);
2911
- }
2912
-
2913
- [data-theme="dark"] .modal-body {
2914
- color: var(--color-text-primary); /* Better contrast for dark mode */
2915
- }
2916
-
2917
- [data-theme="dark"] .text-input-dialog-field label {
2918
- color: var(--color-fg-default, #f0f6fc);
2919
- }
2920
-
2921
- [data-theme="dark"] .text-input-dialog-field input {
2922
- background: var(--color-bg-tertiary, #161b22);
2923
- border-color: var(--color-border-default, #30363d);
2924
- color: var(--color-fg-default, #f0f6fc);
2925
- }
2926
-
2927
- [data-theme="dark"] .text-input-dialog-field input:focus {
2928
- border-color: var(--color-accent-fg, #58a6ff);
2929
- box-shadow: 0 0 0 3px rgba(56, 139, 253, 0.3);
2930
- }
2931
-
2932
2766
  [data-theme="dark"] .status-indicator {
2933
2767
  background: var(--color-bg-primary);
2934
2768
  border-color: var(--color-border-primary);
@@ -9916,1668 +9750,126 @@ body.resizing * {
9916
9750
  background: var(--color-text-tertiary);
9917
9751
  }
9918
9752
 
9919
- /* ============================================
9920
- AI Analysis Configuration Modal
9921
- ============================================ */
9753
+ /* ==========================================================================
9754
+ File-Level Comments Zone
9755
+ Collapsible section between file header and diff content
9756
+ ========================================================================== */
9922
9757
 
9923
- .analysis-config-overlay {
9924
- z-index: 1100;
9758
+ /* CSS Variables for file-level comments */
9759
+ :root {
9760
+ --file-comment-bg: #f6f8fa;
9761
+ --file-comment-border: #d0d7de;
9762
+ --file-comment-accent: linear-gradient(135deg, #0969da 0%, #8250df 100%);
9763
+ --file-comment-header-bg: #eaeef2;
9925
9764
  }
9926
9765
 
9927
- .analysis-config-overlay.visible {
9928
- opacity: 1;
9766
+ [data-theme="dark"] {
9767
+ --file-comment-bg: #1c2128;
9768
+ --file-comment-border: #30363d;
9769
+ --file-comment-header-bg: #21262d;
9929
9770
  }
9930
9771
 
9931
- .analysis-config-overlay.visible .analysis-config-container {
9932
- transform: translateY(0) scale(1);
9933
- opacity: 1;
9772
+ /* File Comments Zone Container - always visible (no collapse)
9773
+ Zone is invisible when empty - styling only applied when has content via :has() */
9774
+
9775
+ /* Conditional styling - only show background/border when zone has actual content */
9776
+ .file-comments-zone:has(.file-comment-card),
9777
+ .file-comments-zone:has(.file-comment-form) {
9778
+ background: var(--file-comment-bg);
9779
+ border-bottom: 1px solid var(--file-comment-border);
9934
9780
  }
9935
9781
 
9936
- .analysis-config-container {
9937
- width: 90vw;
9938
- max-width: min(900px, calc(100vw - 32px));
9939
- height: auto; /* Override fixed height from .modal-container */
9940
- max-height: min(90vh, calc(100vh - 32px));
9782
+ /* Comments Container - only has padding when there's content */
9783
+ .file-comments-container {
9941
9784
  display: flex;
9942
9785
  flex-direction: column;
9943
- transform: translateY(8px) scale(0.98);
9944
- opacity: 0;
9945
- transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1),
9946
- opacity 0.2s ease-out;
9947
- border-radius: 12px;
9948
- overflow: hidden;
9949
- box-shadow:
9950
- 0 0 0 1px var(--color-border-primary),
9951
- 0 16px 70px -12px rgba(0, 0, 0, 0.35),
9952
- 0 4px 16px rgba(0, 0, 0, 0.1);
9953
- /* Ensure the dialog content is visible from the top */
9954
- margin: auto;
9786
+ gap: 12px;
9955
9787
  }
9956
9788
 
9957
- [data-theme="dark"] .analysis-config-container {
9958
- box-shadow:
9959
- 0 0 0 1px var(--color-border-primary),
9960
- 0 16px 70px -12px rgba(0, 0, 0, 0.6),
9961
- 0 4px 16px rgba(0, 0, 0, 0.25);
9789
+ /* Only add padding when container has visible content */
9790
+ .file-comments-container:has(.file-comment-card),
9791
+ .file-comments-container:has(.file-comment-form) {
9792
+ padding: 12px 16px;
9962
9793
  }
9963
9794
 
9964
- /* Header */
9965
- .analysis-config-header {
9966
- display: flex;
9795
+ /* ==========================================================================
9796
+ File Comment Badge - indicates file-level scope (like GitHub)
9797
+ ========================================================================== */
9798
+ .file-comment-badge {
9799
+ display: inline-flex;
9967
9800
  align-items: center;
9968
- justify-content: space-between;
9969
- padding: 16px 20px;
9970
- background: linear-gradient(135deg,
9971
- var(--color-bg-secondary) 0%,
9972
- var(--color-bg-tertiary) 100%);
9973
- border-bottom: 1px solid var(--color-border-primary);
9801
+ gap: 4px;
9802
+ padding: 2px 8px;
9803
+ border-radius: 12px;
9804
+ font-size: 11px;
9805
+ font-weight: 500;
9806
+ background: var(--color-bg-tertiary);
9807
+ color: var(--color-text-secondary);
9808
+ border: 1px solid var(--color-border-secondary);
9809
+ white-space: nowrap;
9810
+ }
9811
+
9812
+ /* Dark theme adjustments for file comment badge */
9813
+ [data-theme="dark"] .file-comment-badge {
9814
+ background: rgba(110, 118, 129, 0.2);
9815
+ border-color: rgba(110, 118, 129, 0.4);
9816
+ color: #8b949e;
9817
+ }
9818
+
9819
+
9820
+ /* ==========================================================================
9821
+ File-Level Comment Card
9822
+ ========================================================================== */
9823
+ .file-comment-card {
9824
+ background: var(--color-bg-primary);
9825
+ border: 1px solid var(--color-border-primary);
9826
+ border-radius: 6px;
9827
+ overflow: hidden;
9828
+ animation: fileCommentSlideIn 0.25s ease-out;
9829
+ }
9830
+
9831
+ @keyframes fileCommentSlideIn {
9832
+ from {
9833
+ opacity: 0;
9834
+ transform: translateY(-8px);
9835
+ }
9836
+ to {
9837
+ opacity: 1;
9838
+ transform: translateY(0);
9839
+ }
9974
9840
  }
9975
9841
 
9976
- .header-title-section {
9842
+ /* Comment Header */
9843
+ .file-comment-header {
9977
9844
  display: flex;
9978
9845
  align-items: center;
9979
9846
  gap: 12px;
9847
+ padding: 12px 16px;
9848
+ background: var(--color-bg-tertiary);
9849
+ border-bottom: 1px solid var(--color-border-secondary);
9980
9850
  }
9981
9851
 
9982
- .header-icon {
9983
- display: flex;
9852
+ /* Source Badge (AI vs User) */
9853
+ .comment-source-badge {
9854
+ display: inline-flex;
9984
9855
  align-items: center;
9985
- justify-content: center;
9986
- width: 40px;
9987
- height: 40px;
9988
- border-radius: 10px;
9989
- background: linear-gradient(135deg, var(--color-accent-ai-dark) 0%, #d97706 100%);
9856
+ gap: 4px;
9857
+ padding: 2px 8px;
9858
+ border-radius: 4px;
9859
+ font-size: 11px;
9860
+ font-weight: 600;
9861
+ text-transform: uppercase;
9862
+ letter-spacing: 0.02em;
9863
+ }
9864
+
9865
+ .comment-source-badge.ai {
9866
+ background: linear-gradient(135deg, var(--ai-primary) 0%, var(--ai-secondary) 100%);
9990
9867
  color: white;
9991
- box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);
9992
9868
  }
9993
9869
 
9994
- [data-theme="dark"] .header-icon {
9995
- background: linear-gradient(135deg, var(--color-accent-ai) 0%, var(--color-accent-ai-dark) 100%);
9996
- box-shadow: 0 2px 12px rgba(251, 191, 36, 0.25);
9997
- }
9998
-
9999
- .analysis-config-header h3 {
10000
- margin: 0;
10001
- font-size: 16px;
10002
- font-weight: 600;
10003
- color: var(--color-text-primary);
10004
- }
10005
-
10006
- .header-subtitle {
10007
- margin: 2px 0 0;
10008
- font-size: 12px;
10009
- color: var(--color-text-secondary);
10010
- }
10011
-
10012
- /* Body */
10013
- .analysis-config-body {
10014
- flex: 1;
10015
- overflow-y: auto;
10016
- padding: 20px;
10017
- background: var(--color-bg-primary);
10018
- position: relative;
10019
- }
10020
-
10021
- /* Loading overlay shown while providers are being fetched */
10022
- .config-loading-overlay {
10023
- position: absolute;
10024
- inset: 0;
10025
- display: flex;
10026
- flex-direction: column;
10027
- align-items: center;
10028
- justify-content: center;
10029
- gap: 12px;
10030
- background: var(--color-bg-primary);
10031
- z-index: 10;
10032
- color: var(--color-text-secondary);
10033
- font-size: 13px;
10034
- }
10035
-
10036
- .config-loading-spinner {
10037
- width: 24px;
10038
- height: 24px;
10039
- border: 2.5px solid var(--color-border-primary);
10040
- border-top-color: var(--color-text-link, #2f81f7);
10041
- border-radius: 50%;
10042
- animation: spin 0.8s linear infinite;
10043
- }
10044
-
10045
- /* Section styling */
10046
- .config-section {
10047
- margin-bottom: 20px;
10048
- }
10049
-
10050
- .config-section:last-child {
10051
- margin-bottom: 0;
10052
- }
10053
-
10054
- .section-title {
10055
- display: flex;
10056
- align-items: center;
10057
- gap: 8px;
10058
- margin: 0 0 10px;
10059
- font-size: 13px;
10060
- font-weight: 600;
10061
- color: var(--color-text-primary);
10062
- text-transform: uppercase;
10063
- letter-spacing: 0.03em;
10064
- }
10065
-
10066
- .section-hint {
10067
- font-weight: 400;
10068
- font-size: 11px;
10069
- color: var(--color-text-tertiary);
10070
- text-transform: none;
10071
- letter-spacing: 0;
10072
- }
10073
-
10074
- /* Provider Toggle */
10075
- .provider-toggle {
10076
- display: flex;
10077
- flex-wrap: wrap;
10078
- justify-content: center;
10079
- gap: 8px;
10080
- width: 100%;
10081
- max-width: 100%;
10082
- }
10083
-
10084
- .provider-btn {
10085
- display: inline-flex;
10086
- align-items: center;
10087
- gap: 6px;
10088
- padding: 10px 18px;
10089
- border: 2px solid var(--color-border-primary);
10090
- background: var(--color-bg-secondary);
10091
- color: var(--color-text-secondary);
10092
- font-size: 14px;
10093
- font-weight: 500;
10094
- border-radius: 10px;
10095
- cursor: pointer;
10096
- transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
10097
- white-space: nowrap;
10098
- }
10099
-
10100
- .provider-btn:hover {
10101
- border-color: var(--color-border-secondary);
10102
- background: var(--color-bg-tertiary);
10103
- color: var(--color-text-primary);
10104
- transform: translateY(-2px);
10105
- box-shadow: 0 4px 12px var(--color-shadow);
10106
- }
10107
-
10108
- .provider-btn.selected {
10109
- border-color: var(--color-accent-ai-dark);
10110
- background: rgba(245, 158, 11, 0.08);
10111
- color: var(--color-text-primary);
10112
- box-shadow:
10113
- 0 0 0 3px rgba(245, 158, 11, 0.15),
10114
- 0 4px 12px rgba(245, 158, 11, 0.1);
10115
- }
10116
-
10117
- [data-theme="dark"] .provider-btn.selected {
10118
- background: rgba(251, 191, 36, 0.1);
10119
- border-color: var(--color-accent-ai);
10120
- color: #fbbf24;
10121
- box-shadow:
10122
- 0 0 0 3px rgba(251, 191, 36, 0.15),
10123
- 0 4px 12px rgba(251, 191, 36, 0.08);
10124
- }
10125
-
10126
- /* No providers available message */
10127
- .no-providers-message {
10128
- font-size: 13px;
10129
- font-style: italic;
10130
- color: var(--color-text-muted);
10131
- padding: 8px 12px;
10132
- }
10133
-
10134
- /* Provider refresh button */
10135
- .provider-refresh-btn {
10136
- display: inline-flex;
10137
- align-items: center;
10138
- justify-content: center;
10139
- width: 22px;
10140
- height: 22px;
10141
- padding: 0;
10142
- margin-left: 4px;
10143
- border: none;
10144
- background: transparent;
10145
- color: var(--color-text-tertiary);
10146
- border-radius: 4px;
10147
- cursor: pointer;
10148
- transition: all 0.2s ease;
10149
- }
10150
-
10151
- .provider-refresh-btn:hover {
10152
- background: var(--color-bg-tertiary);
10153
- color: var(--color-text-secondary);
10154
- }
10155
-
10156
- .provider-refresh-btn:disabled {
10157
- cursor: not-allowed;
10158
- opacity: 0.5;
10159
- }
10160
-
10161
- .provider-refresh-btn.refreshing svg {
10162
- animation: spin 1s linear infinite;
10163
- }
10164
-
10165
- @keyframes spin {
10166
- from {
10167
- transform: rotate(0deg);
10168
- }
10169
- to {
10170
- transform: rotate(360deg);
10171
- }
10172
- }
10173
-
10174
- /* Model Cards */
10175
- .model-cards {
10176
- display: grid;
10177
- grid-template-columns: repeat(3, minmax(0, 220px));
10178
- gap: 12px;
10179
- justify-content: center;
10180
- }
10181
-
10182
- .model-card {
10183
- position: relative;
10184
- display: flex;
10185
- flex-direction: column;
10186
- align-items: center;
10187
- padding: 14px 10px;
10188
- background: var(--color-bg-secondary);
10189
- border: 2px solid var(--color-border-primary);
10190
- border-radius: 10px;
10191
- cursor: pointer;
10192
- transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
10193
- text-align: center;
10194
- aspect-ratio: 1.618 / 1;
10195
- overflow: hidden;
10196
- justify-content: center;
10197
- }
10198
-
10199
- .model-card:hover {
10200
- border-color: var(--color-border-secondary);
10201
- background: var(--color-bg-tertiary);
10202
- transform: translateY(-2px);
10203
- box-shadow: 0 4px 12px var(--color-shadow);
10204
- }
10205
-
10206
- .model-card.selected {
10207
- border-color: var(--color-accent-ai-dark);
10208
- background: rgba(245, 158, 11, 0.08);
10209
- box-shadow:
10210
- 0 0 0 3px rgba(245, 158, 11, 0.15),
10211
- 0 4px 12px rgba(245, 158, 11, 0.1);
10212
- }
10213
-
10214
- [data-theme="dark"] .model-card.selected {
10215
- background: rgba(251, 191, 36, 0.1);
10216
- border-color: var(--color-accent-ai);
10217
- box-shadow:
10218
- 0 0 0 3px rgba(251, 191, 36, 0.15),
10219
- 0 4px 12px rgba(251, 191, 36, 0.08);
10220
- }
10221
-
10222
- .model-badge {
10223
- position: absolute;
10224
- top: 8px;
10225
- right: 8px;
10226
- padding: 2px 8px;
10227
- font-size: 9px;
10228
- font-weight: 700;
10229
- text-transform: uppercase;
10230
- letter-spacing: 0.05em;
10231
- border-radius: 10px;
10232
- white-space: nowrap;
10233
- }
10234
-
10235
- .badge-speed {
10236
- background: linear-gradient(135deg, #06b6d4 0%, #0891b2 100%);
10237
- color: white;
10238
- }
10239
-
10240
- .badge-recommended {
10241
- background: linear-gradient(135deg, var(--color-accent-ai-dark) 0%, #d97706 100%);
10242
- color: white;
10243
- }
10244
-
10245
- .badge-power {
10246
- background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);
10247
- color: white;
10248
- }
10249
-
10250
- .badge-premium {
10251
- background: linear-gradient(135deg, #ec4899 0%, #db2777 100%);
10252
- color: white;
10253
- }
10254
-
10255
- .badge-balanced {
10256
- background: linear-gradient(135deg, var(--color-accent-ai-dark) 0%, #d97706 100%);
10257
- color: white;
10258
- }
10259
-
10260
- .model-icon {
10261
- font-size: 28px;
10262
- line-height: 1;
10263
- margin-bottom: 2px;
10264
- }
10265
-
10266
- .model-info {
10267
- display: flex;
10268
- flex-direction: column;
10269
- gap: 1px;
10270
- }
10271
-
10272
- .model-name {
10273
- font-size: 13px;
10274
- font-weight: 600;
10275
- color: var(--color-text-primary);
10276
- }
10277
-
10278
- .model-tagline {
10279
- font-size: 11px;
10280
- color: var(--color-text-secondary);
10281
- }
10282
-
10283
- .model-description {
10284
- margin: 4px 0 0;
10285
- font-size: 10px;
10286
- color: var(--color-text-tertiary);
10287
- line-height: 1.3;
10288
- }
10289
-
10290
- .model-selected-indicator {
10291
- position: absolute;
10292
- bottom: 8px;
10293
- right: 8px;
10294
- width: 20px;
10295
- height: 20px;
10296
- display: flex;
10297
- align-items: center;
10298
- justify-content: center;
10299
- background: var(--color-accent-ai-dark);
10300
- border-radius: 50%;
10301
- color: white;
10302
- opacity: 0;
10303
- transform: scale(0.5);
10304
- transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
10305
- }
10306
-
10307
- [data-theme="dark"] .model-selected-indicator {
10308
- background: var(--color-accent-ai);
10309
- color: #1a1a1a;
10310
- }
10311
-
10312
- .model-card.selected .model-selected-indicator {
10313
- opacity: 1;
10314
- transform: scale(1);
10315
- }
10316
-
10317
- /* Remember toggle */
10318
- .remember-toggle {
10319
- display: flex;
10320
- align-items: center;
10321
- gap: 10px;
10322
- margin-top: 12px;
10323
- cursor: pointer;
10324
- font-size: 12px;
10325
- color: var(--color-text-secondary);
10326
- user-select: none;
10327
- }
10328
-
10329
- .remember-toggle input {
10330
- display: none;
10331
- }
10332
-
10333
- .toggle-switch {
10334
- position: relative;
10335
- width: 36px;
10336
- height: 20px;
10337
- background: var(--color-border-primary);
10338
- border-radius: 10px;
10339
- transition: background 0.2s ease;
10340
- flex-shrink: 0;
10341
- }
10342
-
10343
- .toggle-switch::after {
10344
- content: '';
10345
- position: absolute;
10346
- top: 2px;
10347
- left: 2px;
10348
- width: 16px;
10349
- height: 16px;
10350
- background: white;
10351
- border-radius: 50%;
10352
- transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
10353
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
10354
- }
10355
-
10356
- .remember-toggle input:checked + .toggle-switch {
10357
- background: var(--color-accent-ai-dark);
10358
- }
10359
-
10360
- [data-theme="dark"] .remember-toggle input:checked + .toggle-switch {
10361
- background: var(--color-accent-ai);
10362
- }
10363
-
10364
- .remember-toggle input:checked + .toggle-switch::after {
10365
- transform: translateX(16px);
10366
- }
10367
-
10368
- .toggle-label {
10369
- line-height: 1.4;
10370
- }
10371
-
10372
- /* Skip Level 3 Info */
10373
- .skip-level3-info {
10374
- display: flex;
10375
- align-items: flex-start;
10376
- gap: 8px;
10377
- margin-bottom: 12px;
10378
- padding: 8px 12px;
10379
- background: var(--color-accent-light);
10380
- border-radius: 6px;
10381
- font-size: 12px;
10382
- color: var(--color-info);
10383
- line-height: 1.4;
10384
- }
10385
-
10386
- .skip-level3-info svg {
10387
- flex-shrink: 0;
10388
- margin-top: 1px;
10389
- color: var(--color-info);
10390
- }
10391
-
10392
- /* Preset Chips */
10393
- .preset-chips {
10394
- display: flex;
10395
- flex-wrap: wrap;
10396
- gap: 8px;
10397
- }
10398
-
10399
- .preset-chip {
10400
- display: inline-flex;
10401
- align-items: center;
10402
- gap: 6px;
10403
- padding: 8px 14px;
10404
- background: var(--color-bg-secondary);
10405
- border: 1px solid var(--color-border-primary);
10406
- border-radius: 20px;
10407
- font-size: 13px;
10408
- color: var(--color-text-secondary);
10409
- cursor: pointer;
10410
- transition: all var(--transition-fast);
10411
- user-select: none;
10412
- }
10413
-
10414
- .preset-chip:hover {
10415
- background: var(--color-bg-tertiary);
10416
- border-color: var(--color-border-secondary);
10417
- color: var(--color-text-primary);
10418
- }
10419
-
10420
- .preset-chip.active {
10421
- background: rgba(245, 158, 11, 0.12);
10422
- border-color: var(--color-accent-ai-dark);
10423
- color: #b45309;
10424
- }
10425
-
10426
- [data-theme="dark"] .preset-chip.active {
10427
- background: rgba(251, 191, 36, 0.12);
10428
- border-color: var(--color-accent-ai);
10429
- color: #fcd34d;
10430
- }
10431
-
10432
- .preset-label {
10433
- font-weight: 500;
10434
- }
10435
-
10436
- /* Instructions Container */
10437
- .instructions-container {
10438
- display: flex;
10439
- flex-direction: column;
10440
- gap: 4px;
10441
- }
10442
-
10443
- .repo-instructions-banner {
10444
- display: flex;
10445
- align-items: center;
10446
- gap: 10px;
10447
- padding: 10px 12px;
10448
- background: var(--color-bg-tertiary);
10449
- border: 1px solid var(--color-border-primary);
10450
- border-radius: 8px;
10451
- }
10452
-
10453
- .banner-icon {
10454
- display: flex;
10455
- align-items: center;
10456
- justify-content: center;
10457
- width: 24px;
10458
- height: 24px;
10459
- background: var(--color-accent-light);
10460
- border-radius: 6px;
10461
- color: var(--color-accent-primary);
10462
- flex-shrink: 0;
10463
- }
10464
-
10465
- .banner-content {
10466
- flex: 1;
10467
- display: flex;
10468
- align-items: center;
10469
- justify-content: space-between;
10470
- gap: 12px;
10471
- }
10472
-
10473
- .banner-label {
10474
- font-size: 12px;
10475
- color: var(--color-text-secondary);
10476
- }
10477
-
10478
- .banner-toggle {
10479
- display: inline-flex;
10480
- align-items: center;
10481
- gap: 4px;
10482
- padding: 4px 10px;
10483
- background: transparent;
10484
- border: 1px solid var(--color-border-primary);
10485
- border-radius: 6px;
10486
- font-size: 11px;
10487
- font-weight: 500;
10488
- color: var(--color-text-secondary);
10489
- cursor: pointer;
10490
- transition: all var(--transition-fast);
10491
- }
10492
-
10493
- .banner-toggle:hover {
10494
- background: var(--color-bg-secondary);
10495
- border-color: var(--color-border-secondary);
10496
- color: var(--color-text-primary);
10497
- }
10498
-
10499
- .repo-instructions-expanded {
10500
- background: var(--color-bg-tertiary);
10501
- border: 1px solid var(--color-border-primary);
10502
- border-radius: 8px;
10503
- overflow: hidden;
10504
- }
10505
-
10506
- .expanded-header {
10507
- display: flex;
10508
- align-items: center;
10509
- justify-content: space-between;
10510
- padding: 8px 12px;
10511
- background: var(--color-bg-secondary);
10512
- border-bottom: 1px solid var(--color-border-primary);
10513
- font-size: 11px;
10514
- font-weight: 600;
10515
- color: var(--color-text-secondary);
10516
- text-transform: uppercase;
10517
- letter-spacing: 0.03em;
10518
- }
10519
-
10520
- .collapse-btn {
10521
- display: flex;
10522
- align-items: center;
10523
- justify-content: center;
10524
- width: 24px;
10525
- height: 24px;
10526
- background: transparent;
10527
- border: none;
10528
- border-radius: 4px;
10529
- color: var(--color-text-tertiary);
10530
- cursor: pointer;
10531
- transition: all var(--transition-fast);
10532
- }
10533
-
10534
- .collapse-btn:hover {
10535
- background: var(--color-bg-tertiary);
10536
- color: var(--color-text-secondary);
10537
- }
10538
-
10539
- .expanded-content {
10540
- padding: 12px;
10541
- font-size: 13px;
10542
- color: var(--color-text-secondary);
10543
- line-height: 1.5;
10544
- white-space: pre-wrap;
10545
- }
10546
-
10547
- .instructions-textarea {
10548
- width: 100%;
10549
- padding: 12px;
10550
- background: var(--color-bg-secondary);
10551
- border: 1px solid var(--color-border-primary);
10552
- border-radius: 8px;
10553
- font-family: inherit;
10554
- font-size: 13px;
10555
- color: var(--color-text-primary);
10556
- resize: vertical;
10557
- min-height: 100px;
10558
- transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
10559
- }
10560
-
10561
- .instructions-textarea::placeholder {
10562
- color: var(--color-text-tertiary);
10563
- opacity: 0.8;
10564
- }
10565
-
10566
- .instructions-textarea:focus {
10567
- outline: none;
10568
- border-color: var(--color-accent-ai-dark);
10569
- box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.15);
10570
- }
10571
-
10572
- [data-theme="dark"] .instructions-textarea:focus {
10573
- border-color: var(--color-accent-ai);
10574
- box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.15);
10575
- }
10576
-
10577
- .instructions-footer {
10578
- display: flex;
10579
- justify-content: flex-end;
10580
- }
10581
-
10582
- .char-count {
10583
- font-size: 11px;
10584
- color: var(--color-text-muted);
10585
- transition: color 0.2s ease;
10586
- }
10587
-
10588
- .char-count-warning {
10589
- color: #d97706;
10590
- font-weight: 500;
10591
- }
10592
-
10593
- [data-theme="dark"] .char-count-warning {
10594
- color: var(--color-accent-ai);
10595
- }
10596
-
10597
- .char-count-error {
10598
- color: #dc2626;
10599
- font-weight: 600;
10600
- }
10601
-
10602
- [data-theme="dark"] .char-count-error {
10603
- color: #f87171;
10604
- }
10605
-
10606
- /* Textarea validation states */
10607
- .instructions-textarea.textarea-warning {
10608
- border-color: #d97706;
10609
- }
10610
-
10611
- [data-theme="dark"] .instructions-textarea.textarea-warning {
10612
- border-color: var(--color-accent-ai);
10613
- }
10614
-
10615
- .instructions-textarea.textarea-error {
10616
- border-color: #dc2626;
10617
- box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.15);
10618
- }
10619
-
10620
- [data-theme="dark"] .instructions-textarea.textarea-error {
10621
- border-color: #f87171;
10622
- box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.15);
10623
- }
10624
-
10625
- /* Disabled submit button state */
10626
- .btn-analyze:disabled {
10627
- background: linear-gradient(135deg, #9ca3af 0%, #6b7280 100%);
10628
- cursor: not-allowed;
10629
- box-shadow: none;
10630
- opacity: 0.7;
10631
- }
10632
-
10633
- .btn-analyze:disabled:hover {
10634
- background: linear-gradient(135deg, #9ca3af 0%, #6b7280 100%);
10635
- transform: none;
10636
- }
10637
-
10638
- /* Footer */
10639
- .analysis-config-footer {
10640
- display: flex;
10641
- justify-content: flex-end;
10642
- align-items: center;
10643
- gap: 10px;
10644
- padding: 16px 20px;
10645
- background: var(--color-bg-secondary);
10646
- border-top: 1px solid var(--color-border-primary);
10647
- }
10648
-
10649
- /* Unsaved council changes hint + footer save button container */
10650
- .council-footer-left {
10651
- display: flex;
10652
- align-items: center;
10653
- gap: 10px;
10654
- margin-right: auto;
10655
- }
10656
-
10657
- .council-dirty-hint {
10658
- font-size: 12px;
10659
- color: var(--color-accent-primary, #0969da);
10660
- font-style: italic;
10661
- }
10662
-
10663
- [data-theme="dark"] .council-dirty-hint {
10664
- color: var(--color-accent-primary, #58a6ff);
10665
- }
10666
-
10667
- /* Blue save button for council footer */
10668
- .btn-save-council {
10669
- background-color: var(--color-accent-primary, #0969da);
10670
- color: #ffffff;
10671
- border-color: var(--color-accent-primary, #0969da);
10672
- }
10673
-
10674
- .btn-save-council:hover {
10675
- background-color: #0860ca;
10676
- border-color: #0860ca;
10677
- }
10678
-
10679
- [data-theme="dark"] .btn-save-council {
10680
- background-color: var(--color-accent-primary, #58a6ff);
10681
- border-color: var(--color-accent-primary, #58a6ff);
10682
- color: #ffffff;
10683
- }
10684
-
10685
- [data-theme="dark"] .btn-save-council:hover {
10686
- background-color: #79b8ff;
10687
- border-color: #79b8ff;
10688
- }
10689
-
10690
- .btn-analyze {
10691
- display: inline-flex;
10692
- align-items: center;
10693
- gap: 8px;
10694
- padding: 10px 20px;
10695
- background: linear-gradient(135deg, var(--color-accent-ai-dark) 0%, #d97706 100%);
10696
- border: none;
10697
- border-radius: 8px;
10698
- font-size: 14px;
10699
- font-weight: 600;
10700
- color: white;
10701
- cursor: pointer;
10702
- transition: all 0.2s ease;
10703
- box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);
10704
- }
10705
-
10706
- .btn-analyze:hover {
10707
- background: linear-gradient(135deg, var(--color-accent-ai) 0%, var(--color-accent-ai-dark) 100%);
10708
- transform: translateY(-1px);
10709
- box-shadow: 0 4px 12px rgba(245, 158, 11, 0.35);
10710
- }
10711
-
10712
- .btn-analyze:active {
10713
- transform: translateY(0);
10714
- }
10715
-
10716
- [data-theme="dark"] .btn-analyze {
10717
- background: linear-gradient(135deg, var(--color-accent-ai) 0%, var(--color-accent-ai-dark) 100%);
10718
- color: #1a1a1a;
10719
- box-shadow: 0 2px 12px rgba(251, 191, 36, 0.25);
10720
- }
10721
-
10722
- [data-theme="dark"] .btn-analyze:hover {
10723
- box-shadow: 0 4px 16px rgba(251, 191, 36, 0.3);
10724
- }
10725
-
10726
- /* Responsive */
10727
- @media (max-width: 600px) {
10728
- .analysis-config-container {
10729
- width: 100%;
10730
- max-width: none;
10731
- max-height: 100vh;
10732
- border-radius: 0;
10733
- }
10734
-
10735
- .model-cards {
10736
- grid-template-columns: 1fr;
10737
- }
10738
-
10739
- .model-card {
10740
- flex-direction: row;
10741
- text-align: left;
10742
- padding: 12px 16px;
10743
- gap: 12px;
10744
- aspect-ratio: auto;
10745
- overflow: visible;
10746
- justify-content: flex-start;
10747
- }
10748
-
10749
- .model-icon {
10750
- font-size: 24px;
10751
- margin-bottom: 0;
10752
- }
10753
-
10754
- .model-info {
10755
- flex: 1;
10756
- }
10757
-
10758
- .model-description {
10759
- margin-top: 4px;
10760
- }
10761
-
10762
- .model-badge {
10763
- position: static;
10764
- align-self: flex-start;
10765
- margin-left: auto;
10766
- }
10767
-
10768
- .model-selected-indicator {
10769
- position: static;
10770
- margin-left: 8px;
10771
- }
10772
-
10773
- .preset-chips {
10774
- gap: 6px;
10775
- }
10776
-
10777
- .preset-chip {
10778
- padding: 6px 12px;
10779
- font-size: 12px;
10780
- }
10781
- }
10782
-
10783
- /* ==========================================================================
10784
- Review Council Tab
10785
- Multi-voice, multi-provider analysis configuration
10786
- ========================================================================== */
10787
-
10788
- .analysis-tab-bar {
10789
- display: flex;
10790
- gap: 0;
10791
- border-bottom: 1px solid var(--border-color, #d0d7de);
10792
- margin-bottom: 16px;
10793
- }
10794
-
10795
- .analysis-tab {
10796
- padding: 8px 16px;
10797
- border: none;
10798
- background: none;
10799
- cursor: pointer;
10800
- font-size: 13px;
10801
- font-weight: 500;
10802
- color: var(--fg-muted, #656d76);
10803
- border-bottom: 2px solid transparent;
10804
- transition: color 0.15s, border-color 0.15s;
10805
- }
10806
-
10807
- .analysis-tab:hover {
10808
- color: var(--fg-default, #1f2328);
10809
- }
10810
-
10811
- .analysis-tab.active {
10812
- color: var(--fg-default, #1f2328);
10813
- border-bottom-color: var(--accent-emphasis, #0969da);
10814
- }
10815
-
10816
- [data-theme="dark"] .analysis-tab {
10817
- color: #8b949e;
10818
- }
10819
-
10820
- [data-theme="dark"] .analysis-tab:hover {
10821
- color: #c9d1d9;
10822
- }
10823
-
10824
- [data-theme="dark"] .analysis-tab.active {
10825
- color: #c9d1d9;
10826
- border-bottom-color: #58a6ff;
10827
- }
10828
-
10829
- .beta-badge {
10830
- display: inline-block;
10831
- font-size: 10px;
10832
- font-weight: 600;
10833
- text-transform: uppercase;
10834
- letter-spacing: 0.5px;
10835
- padding: 1px 5px;
10836
- border-radius: 3px;
10837
- background-color: var(--accent-subtle, #ddf4ff);
10838
- color: var(--accent-fg, #0969da);
10839
- margin-left: 4px;
10840
- vertical-align: middle;
10841
- }
10842
-
10843
- [data-theme="dark"] .beta-badge {
10844
- background-color: transparent;
10845
- color: #8b949e;
10846
- border: 1px solid #30363d;
10847
- }
10848
-
10849
- .council-selector-row {
10850
- display: flex;
10851
- gap: 8px;
10852
- align-items: center;
10853
- }
10854
-
10855
- .council-select {
10856
- flex: 1;
10857
- padding: 6px 10px;
10858
- border: 1px solid var(--border-color, #d0d7de);
10859
- border-radius: 6px;
10860
- background: var(--bg-default, #fff);
10861
- color: var(--fg-default, #1f2328);
10862
- font-size: 13px;
10863
- }
10864
-
10865
- [data-theme="dark"] .council-select {
10866
- background: var(--bg-subtle, #161b22);
10867
- color: var(--fg-default, #e6edf3);
10868
- border-color: var(--border-color, #30363d);
10869
- }
10870
-
10871
- /* "New Council" option in council selector */
10872
- .council-option-new {
10873
- font-style: italic;
10874
- color: var(--fg-muted, #656d76);
10875
- }
10876
-
10877
- /* Style the select itself when "New Council" is the active selection */
10878
- .council-select.new-council-selected {
10879
- font-style: italic;
10880
- color: var(--fg-muted, #656d76);
10881
- }
10882
-
10883
- /* Council review divider - separates council config from per-review settings */
10884
- .council-review-divider {
10885
- margin: 24px 0 16px;
10886
- padding-top: 20px;
10887
- border-top: 1px solid var(--color-border-subtle, rgba(0, 0, 0, 0.06));
10888
- }
10889
-
10890
- [data-theme="dark"] .council-review-divider {
10891
- border-top-color: var(--color-border-subtle, rgba(255, 255, 255, 0.06));
10892
- }
10893
-
10894
- .divider-label {
10895
- font-size: 12px;
10896
- font-weight: 500;
10897
- color: var(--color-text-tertiary, #656d76);
10898
- text-transform: uppercase;
10899
- letter-spacing: 0.5px;
10900
- }
10901
-
10902
- [data-theme="dark"] .divider-label {
10903
- color: var(--color-text-tertiary, #6e7681);
10904
- }
10905
-
10906
- .council-level-section .section-title {
10907
- margin-bottom: 8px;
10908
- }
10909
-
10910
- .level-toggle {
10911
- font-weight: 600;
10912
- }
10913
-
10914
- .level-toggle .toggle-label {
10915
- font-weight: 600;
10916
- }
10917
-
10918
- .level-voices {
10919
- margin-left: 24px;
10920
- margin-top: 8px;
10921
- }
10922
-
10923
- .voice-list {
10924
- display: flex;
10925
- flex-direction: column;
10926
- gap: 6px;
10927
- }
10928
-
10929
- .voice-row {
10930
- display: flex;
10931
- gap: 8px;
10932
- align-items: center;
10933
- }
10934
-
10935
- .voice-provider,
10936
- .voice-model,
10937
- .voice-tier {
10938
- padding: 5px 8px;
10939
- border: 1px solid var(--border-color, #d0d7de);
10940
- border-radius: 6px;
10941
- background: var(--bg-default, #fff);
10942
- color: var(--fg-default, #1f2328);
10943
- font-size: 12px;
10944
- }
10945
-
10946
- [data-theme="dark"] .voice-provider,
10947
- [data-theme="dark"] .voice-model,
10948
- [data-theme="dark"] .voice-tier {
10949
- background: var(--bg-subtle, #161b22);
10950
- color: var(--fg-default, #e6edf3);
10951
- border-color: var(--border-color, #30363d);
10952
- }
10953
-
10954
- .voice-provider {
10955
- min-width: 100px;
10956
- }
10957
-
10958
- .voice-model {
10959
- min-width: 140px;
10960
- flex: 1;
10961
- }
10962
-
10963
- .voice-tier {
10964
- min-width: 90px;
10965
- }
10966
-
10967
- .executable-note {
10968
- font-size: 11px;
10969
- color: var(--fg-muted, #656d76);
10970
- font-style: italic;
10971
- white-space: nowrap;
10972
- }
10973
-
10974
- .vc-levels-disabled-note {
10975
- margin-top: 12px;
10976
- margin-bottom: 0;
10977
- }
10978
-
10979
- .btn-icon {
10980
- box-sizing: border-box;
10981
- width: 28px;
10982
- height: 28px;
10983
- padding: 0;
10984
- display: inline-flex;
10985
- align-items: center;
10986
- justify-content: center;
10987
- font-size: 16px;
10988
- line-height: 1;
10989
- border-radius: 6px;
10990
- border: 1px solid var(--border-color, #d0d7de);
10991
- background: var(--bg-default, #fff);
10992
- color: var(--fg-muted, #656d76);
10993
- cursor: pointer;
10994
- }
10995
-
10996
- .btn-icon:hover {
10997
- color: var(--color-text-primary);
10998
- border-color: var(--color-border-secondary);
10999
- }
11000
-
11001
- .btn-ghost {
11002
- background: none;
11003
- border: none;
11004
- color: var(--accent-fg, #0969da);
11005
- cursor: pointer;
11006
- font-size: 12px;
11007
- padding: 4px 8px;
11008
- }
11009
-
11010
- .btn-ghost:hover {
11011
- text-decoration: underline;
11012
- }
11013
-
11014
- .btn-sm {
11015
- font-size: 12px;
11016
- padding: 4px 10px;
11017
- }
11018
-
11019
- .add-voice-btn {
11020
- margin-top: 6px;
11021
- }
11022
-
11023
- .add-voice-btn:hover {
11024
- color: var(--color-accent-primary, #0969da);
11025
- border-color: var(--color-accent-primary, #0969da);
11026
- }
11027
-
11028
- .section-hint-text {
11029
- font-size: 12px;
11030
- color: var(--fg-muted, #656d76);
11031
- margin-bottom: 8px;
11032
- margin-top: -4px;
11033
- }
11034
-
11035
- .voice-instructions-area {
11036
- margin-left: 0;
11037
- margin-bottom: 4px;
11038
- }
11039
-
11040
- .voice-instructions-input {
11041
- width: 100%;
11042
- padding: 6px 8px;
11043
- border: 1px solid var(--border-color, #d0d7de);
11044
- border-radius: 6px;
11045
- background: var(--bg-default, #fff);
11046
- color: var(--fg-default, #1f2328);
11047
- font-size: 12px;
11048
- font-family: inherit;
11049
- resize: vertical;
11050
- }
11051
-
11052
- [data-theme="dark"] .voice-instructions-input {
11053
- background: var(--bg-subtle, #161b22);
11054
- color: var(--fg-default, #e6edf3);
11055
- border-color: var(--border-color, #30363d);
11056
- }
11057
-
11058
- /* Icon-only toggle for per-participant instructions */
11059
- .toggle-instructions-icon {
11060
- width: 24px;
11061
- height: 24px;
11062
- padding: 0;
11063
- display: inline-flex;
11064
- align-items: center;
11065
- justify-content: center;
11066
- background: none;
11067
- border: 1px solid transparent;
11068
- border-radius: 4px;
11069
- color: var(--color-text-tertiary, #6e7681);
11070
- cursor: pointer;
11071
- flex-shrink: 0;
11072
- transition: color 0.15s ease, border-color 0.15s ease;
11073
- }
11074
-
11075
- .toggle-instructions-icon:hover {
11076
- color: var(--color-accent-primary, #0969da);
11077
- border-color: var(--color-border-secondary, #d0d7de);
11078
- }
11079
-
11080
- .toggle-instructions-icon.has-instructions {
11081
- color: var(--color-accent-primary, #0969da);
11082
- }
11083
-
11084
- [data-theme="dark"] .toggle-instructions-icon {
11085
- color: var(--color-text-tertiary, #484f58);
11086
- }
11087
-
11088
- [data-theme="dark"] .toggle-instructions-icon:hover {
11089
- color: var(--color-accent-primary, #58a6ff);
11090
- border-color: var(--color-border-primary, #30363d);
11091
- }
11092
-
11093
- [data-theme="dark"] .toggle-instructions-icon.has-instructions {
11094
- color: var(--color-accent-primary, #58a6ff);
11095
- }
11096
-
11097
- /* Icon-only toggle for per-voice timeout (clock icon) */
11098
- .toggle-timeout-icon {
11099
- width: 24px;
11100
- height: 24px;
11101
- padding: 0;
11102
- display: inline-flex;
11103
- align-items: center;
11104
- justify-content: center;
11105
- background: none;
11106
- border: 1px solid transparent;
11107
- border-radius: 4px;
11108
- color: var(--color-text-tertiary, #6e7681);
11109
- cursor: pointer;
11110
- flex-shrink: 0;
11111
- transition: color 0.15s ease, border-color 0.15s ease;
11112
- }
11113
-
11114
- .toggle-timeout-icon:hover {
11115
- color: var(--color-accent-primary, #0969da);
11116
- border-color: var(--color-border-secondary, #d0d7de);
11117
- }
11118
-
11119
- .toggle-timeout-icon.has-custom-timeout {
11120
- color: var(--color-attention-fg, #9a6700);
11121
- }
11122
-
11123
- [data-theme="dark"] .toggle-timeout-icon {
11124
- color: var(--color-text-tertiary, #484f58);
11125
- }
11126
-
11127
- [data-theme="dark"] .toggle-timeout-icon:hover {
11128
- color: var(--color-accent-primary, #58a6ff);
11129
- border-color: var(--color-border-primary, #30363d);
11130
- }
11131
-
11132
- [data-theme="dark"] .toggle-timeout-icon.has-custom-timeout {
11133
- color: var(--color-attention-fg, #d29922);
11134
- }
11135
-
11136
- /* Custom timeout dropdown selector (replaces native <select> for timeouts) */
11137
- .timeout-select {
11138
- position: relative;
11139
- display: inline-flex;
11140
- flex-shrink: 0;
11141
- }
11142
-
11143
- .timeout-select-trigger {
11144
- display: inline-flex;
11145
- align-items: center;
11146
- gap: 4px;
11147
- padding: 4px 8px;
11148
- border: 1px solid var(--border-color, #d0d7de);
11149
- border-radius: 6px;
11150
- background: var(--bg-default, #fff);
11151
- color: var(--fg-default, #1f2328);
11152
- font-size: 12px;
11153
- font-family: inherit;
11154
- font-weight: 500;
11155
- cursor: pointer;
11156
- white-space: nowrap;
11157
- transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
11158
- min-width: 52px;
11159
- justify-content: center;
11160
- line-height: 1.4;
11161
- }
11162
-
11163
- .timeout-select-trigger:hover {
11164
- border-color: var(--color-accent-primary, #0969da);
11165
- background: var(--bg-subtle, #f6f8fa);
11166
- }
11167
-
11168
- .timeout-select.open .timeout-select-trigger {
11169
- border-color: var(--color-accent-primary, #0969da);
11170
- box-shadow: 0 0 0 2px rgba(9, 105, 218, 0.15);
11171
- }
11172
-
11173
- .timeout-select-label {
11174
- pointer-events: none;
11175
- }
11176
-
11177
- .timeout-select-caret {
11178
- flex-shrink: 0;
11179
- transition: transform 0.15s ease;
11180
- pointer-events: none;
11181
- }
11182
-
11183
- .timeout-select.open .timeout-select-caret {
11184
- transform: rotate(180deg);
11185
- }
11186
-
11187
- /* Dropdown menu */
11188
- .timeout-select-menu {
11189
- display: none;
11190
- position: absolute;
11191
- top: calc(100% + 4px);
11192
- left: 50%;
11193
- transform: translateX(-50%);
11194
- min-width: 64px;
11195
- background: var(--bg-default, #fff);
11196
- border: 1px solid var(--border-color, #d0d7de);
11197
- border-radius: 8px;
11198
- box-shadow: 0 4px 12px rgba(27, 31, 36, 0.12), 0 1px 3px rgba(27, 31, 36, 0.08);
11199
- z-index: 1100;
11200
- padding: 4px;
11201
- flex-direction: column;
11202
- }
11203
-
11204
- .timeout-select.open .timeout-select-menu {
11205
- display: flex;
11206
- }
11207
-
11208
- /* Individual option */
11209
- .timeout-select-option {
11210
- display: flex;
11211
- align-items: center;
11212
- justify-content: center;
11213
- padding: 5px 10px;
11214
- border: none;
11215
- border-radius: 5px;
11216
- background: transparent;
11217
- color: var(--fg-default, #1f2328);
11218
- font-size: 12px;
11219
- font-family: inherit;
11220
- font-weight: 500;
11221
- cursor: pointer;
11222
- white-space: nowrap;
11223
- transition: background 0.1s ease, color 0.1s ease;
11224
- }
11225
-
11226
- .timeout-select-option:hover,
11227
- .timeout-select-option.focused {
11228
- background: var(--bg-subtle, #f6f8fa);
11229
- }
11230
-
11231
- .timeout-select-option.selected {
11232
- color: var(--color-accent-primary, #0969da);
11233
- background: rgba(9, 105, 218, 0.08);
11234
- font-weight: 600;
11235
- }
11236
-
11237
- .timeout-select-option.selected:hover,
11238
- .timeout-select-option.selected.focused {
11239
- background: rgba(9, 105, 218, 0.14);
11240
- }
11241
-
11242
- /* Dark theme overrides */
11243
- [data-theme="dark"] .timeout-select-trigger {
11244
- background: var(--bg-subtle, #161b22);
11245
- color: var(--fg-default, #e6edf3);
11246
- border-color: var(--border-color, #30363d);
11247
- }
11248
-
11249
- [data-theme="dark"] .timeout-select-trigger:hover {
11250
- border-color: var(--color-accent-primary, #58a6ff);
11251
- background: var(--color-bg-tertiary, #1c2128);
11252
- }
11253
-
11254
- [data-theme="dark"] .timeout-select.open .timeout-select-trigger {
11255
- border-color: var(--color-accent-primary, #58a6ff);
11256
- box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.15);
11257
- }
11258
-
11259
- [data-theme="dark"] .timeout-select-menu {
11260
- background: var(--bg-subtle, #161b22);
11261
- border-color: var(--border-color, #30363d);
11262
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3), 0 1px 3px rgba(0, 0, 0, 0.2);
11263
- }
11264
-
11265
- [data-theme="dark"] .timeout-select-option {
11266
- color: var(--fg-default, #e6edf3);
11267
- }
11268
-
11269
- [data-theme="dark"] .timeout-select-option:hover,
11270
- [data-theme="dark"] .timeout-select-option.focused {
11271
- background: rgba(255, 255, 255, 0.06);
11272
- }
11273
-
11274
- [data-theme="dark"] .timeout-select-option.selected {
11275
- color: var(--color-accent-primary, #58a6ff);
11276
- background: rgba(88, 166, 255, 0.1);
11277
- }
11278
-
11279
- [data-theme="dark"] .timeout-select-option.selected:hover,
11280
- [data-theme="dark"] .timeout-select-option.selected.focused {
11281
- background: rgba(88, 166, 255, 0.16);
11282
- }
11283
-
11284
- /* Participant card layout (item 4) */
11285
- .participant-wrapper {
11286
- display: flex;
11287
- flex-direction: row;
11288
- gap: 8px;
11289
- align-items: flex-start;
11290
- }
11291
-
11292
- .participant-card {
11293
- flex: 1;
11294
- border: 1px solid var(--border-color, #d0d7de);
11295
- border-radius: 8px;
11296
- padding: 10px;
11297
- display: flex;
11298
- flex-direction: column;
11299
- gap: 6px;
11300
- background: var(--bg-default, #fff);
11301
- }
11302
-
11303
- [data-theme="dark"] .participant-card {
11304
- border-color: var(--border-color, #30363d);
11305
- background: var(--bg-subtle, #161b22);
11306
- }
11307
-
11308
- .participant-card .voice-row {
11309
- margin: 0;
11310
- }
11311
-
11312
- .participant-card .voice-instructions-area {
11313
- margin: 0;
11314
- }
11315
-
11316
- /* Orchestration/consolidation card — same styling as participant-card */
11317
- .orchestration-card {
11318
- border: 1px solid var(--border-color, #d0d7de);
11319
- border-radius: 8px;
11320
- padding: 10px;
11321
- display: flex;
11322
- flex-direction: column;
11323
- gap: 6px;
11324
- background: var(--bg-default, #fff);
11325
- }
11326
-
11327
- [data-theme="dark"] .orchestration-card {
11328
- border-color: var(--border-color, #30363d);
11329
- background: var(--bg-subtle, #161b22);
11330
- }
11331
-
11332
- .orchestration-card .voice-row {
11333
- margin: 0;
11334
- }
11335
-
11336
- .orchestration-card .voice-instructions-area {
11337
- margin: 0;
11338
- }
11339
-
11340
- .participant-wrapper > .remove-voice-btn {
11341
- flex-shrink: 0;
11342
- margin-top: 10px;
11343
- }
11344
-
11345
- /* Spacer to align consolidation row with level voice rows that have a remove button */
11346
- .participant-wrapper > .remove-voice-btn-spacer {
11347
- flex-shrink: 0;
11348
- width: 28px; /* matches .btn-icon width */
11349
- }
11350
-
11351
- /* Dark mode overrides for council +/- icon buttons */
11352
- [data-theme="dark"] .btn-icon {
11353
- background: var(--color-bg-tertiary, #1c2128);
11354
- border-color: var(--color-border-primary, #30363d);
11355
- color: var(--color-text-secondary, #8b949e);
11356
- }
11357
-
11358
- [data-theme="dark"] .btn-icon:hover {
11359
- background: var(--color-bg-elevated, #1e2329);
11360
- color: var(--color-text-primary, #e6edf3);
11361
- border-color: var(--color-border-secondary, #484f58);
11362
- }
11363
-
11364
- [data-theme="dark"] .add-voice-btn {
11365
- color: var(--color-text-secondary, #8b949e);
11366
- }
11367
-
11368
- [data-theme="dark"] .add-voice-btn:hover {
11369
- color: var(--color-accent-primary, #58a6ff);
11370
- border-color: var(--color-accent-primary, #58a6ff);
11371
- }
11372
-
11373
- /* Disabled button styles for council selector row (item 6) */
11374
- .council-selector-row .btn:disabled {
11375
- opacity: 0.5;
11376
- cursor: not-allowed;
11377
- }
11378
-
11379
- /* Icon-only danger button (e.g. delete council) */
11380
- .btn-icon-danger {
11381
- background: none;
11382
- border: 1px solid transparent;
11383
- color: var(--fg-muted, #656d76);
11384
- padding: 4px 6px;
11385
- border-radius: 6px;
11386
- cursor: pointer;
11387
- display: inline-flex;
11388
- align-items: center;
11389
- justify-content: center;
11390
- transition: color 0.15s, background 0.15s;
11391
- }
11392
-
11393
- .btn-icon-danger:hover:not(:disabled) {
11394
- color: var(--danger-fg, #d1242f);
11395
- background: var(--color-danger-subtle, rgba(255, 129, 130, 0.1));
11396
- }
11397
-
11398
- .btn-icon-danger:disabled {
11399
- opacity: 0.4;
11400
- cursor: not-allowed;
11401
- }
11402
-
11403
- [data-theme="dark"] .btn-icon-danger {
11404
- color: var(--color-text-secondary, #8b949e);
11405
- }
11406
-
11407
- [data-theme="dark"] .btn-icon-danger:hover:not(:disabled) {
11408
- color: var(--color-danger, #f85149);
11409
- background: rgba(248, 81, 73, 0.1);
11410
- }
11411
-
11412
- /* Info-tip toggle buttons (circled "i" icons next to section headers) */
11413
- .info-tip-toggle {
11414
- display: inline-flex;
11415
- align-items: center;
11416
- justify-content: center;
11417
- width: 18px;
11418
- height: 18px;
11419
- padding: 0;
11420
- border: none;
11421
- border-radius: 50%;
11422
- background: none;
11423
- color: var(--color-text-tertiary, #656d76);
11424
- cursor: pointer;
11425
- flex-shrink: 0;
11426
- transition: color 0.15s ease;
11427
- }
11428
-
11429
- .info-tip-toggle:hover {
11430
- color: var(--color-info, #0969da);
11431
- }
11432
-
11433
- .info-tip-toggle.active {
11434
- color: var(--color-info, #0969da);
11435
- }
11436
-
11437
- .info-tip-content {
11438
- background: var(--color-info-subtle, #ddf4ff);
11439
- border-radius: 6px;
11440
- padding: 8px 10px;
11441
- margin: 0 0 8px;
11442
- font-size: 12px;
11443
- line-height: 1.45;
11444
- color: var(--color-text-secondary, #424a53);
11445
- }
11446
-
11447
- [data-theme="dark"] .info-tip-toggle {
11448
- color: var(--color-text-tertiary, #484f58);
11449
- }
11450
-
11451
- [data-theme="dark"] .info-tip-toggle:hover,
11452
- [data-theme="dark"] .info-tip-toggle.active {
11453
- color: var(--color-info, #58a6ff);
11454
- }
11455
-
11456
- [data-theme="dark"] .info-tip-content {
11457
- background: rgba(56, 139, 253, 0.1);
11458
- color: var(--color-text-secondary, #8b949e);
11459
- }
11460
-
11461
- /* ==========================================================================
11462
- File-Level Comments Zone
11463
- Collapsible section between file header and diff content
11464
- ========================================================================== */
11465
-
11466
- /* CSS Variables for file-level comments */
11467
- :root {
11468
- --file-comment-bg: #f6f8fa;
11469
- --file-comment-border: #d0d7de;
11470
- --file-comment-accent: linear-gradient(135deg, #0969da 0%, #8250df 100%);
11471
- --file-comment-header-bg: #eaeef2;
11472
- }
11473
-
11474
- [data-theme="dark"] {
11475
- --file-comment-bg: #1c2128;
11476
- --file-comment-border: #30363d;
11477
- --file-comment-header-bg: #21262d;
11478
- }
11479
-
11480
- /* File Comments Zone Container - always visible (no collapse)
11481
- Zone is invisible when empty - styling only applied when has content via :has() */
11482
-
11483
- /* Conditional styling - only show background/border when zone has actual content */
11484
- .file-comments-zone:has(.file-comment-card),
11485
- .file-comments-zone:has(.file-comment-form) {
11486
- background: var(--file-comment-bg);
11487
- border-bottom: 1px solid var(--file-comment-border);
11488
- }
11489
-
11490
- /* Comments Container - only has padding when there's content */
11491
- .file-comments-container {
11492
- display: flex;
11493
- flex-direction: column;
11494
- gap: 12px;
11495
- }
11496
-
11497
- /* Only add padding when container has visible content */
11498
- .file-comments-container:has(.file-comment-card),
11499
- .file-comments-container:has(.file-comment-form) {
11500
- padding: 12px 16px;
11501
- }
11502
-
11503
- /* ==========================================================================
11504
- File Comment Badge - indicates file-level scope (like GitHub)
11505
- ========================================================================== */
11506
- .file-comment-badge {
11507
- display: inline-flex;
11508
- align-items: center;
11509
- gap: 4px;
11510
- padding: 2px 8px;
11511
- border-radius: 12px;
11512
- font-size: 11px;
11513
- font-weight: 500;
11514
- background: var(--color-bg-tertiary);
11515
- color: var(--color-text-secondary);
11516
- border: 1px solid var(--color-border-secondary);
11517
- white-space: nowrap;
11518
- }
11519
-
11520
- /* Dark theme adjustments for file comment badge */
11521
- [data-theme="dark"] .file-comment-badge {
11522
- background: rgba(110, 118, 129, 0.2);
11523
- border-color: rgba(110, 118, 129, 0.4);
11524
- color: #8b949e;
11525
- }
11526
-
11527
-
11528
- /* ==========================================================================
11529
- File-Level Comment Card
11530
- ========================================================================== */
11531
- .file-comment-card {
11532
- background: var(--color-bg-primary);
11533
- border: 1px solid var(--color-border-primary);
11534
- border-radius: 6px;
11535
- overflow: hidden;
11536
- animation: fileCommentSlideIn 0.25s ease-out;
11537
- }
11538
-
11539
- @keyframes fileCommentSlideIn {
11540
- from {
11541
- opacity: 0;
11542
- transform: translateY(-8px);
11543
- }
11544
- to {
11545
- opacity: 1;
11546
- transform: translateY(0);
11547
- }
11548
- }
11549
-
11550
- /* Comment Header */
11551
- .file-comment-header {
11552
- display: flex;
11553
- align-items: center;
11554
- gap: 12px;
11555
- padding: 12px 16px;
11556
- background: var(--color-bg-tertiary);
11557
- border-bottom: 1px solid var(--color-border-secondary);
11558
- }
11559
-
11560
- /* Source Badge (AI vs User) */
11561
- .comment-source-badge {
11562
- display: inline-flex;
11563
- align-items: center;
11564
- gap: 4px;
11565
- padding: 2px 8px;
11566
- border-radius: 4px;
11567
- font-size: 11px;
11568
- font-weight: 600;
11569
- text-transform: uppercase;
11570
- letter-spacing: 0.02em;
11571
- }
11572
-
11573
- .comment-source-badge.ai {
11574
- background: linear-gradient(135deg, var(--ai-primary) 0%, var(--ai-secondary) 100%);
11575
- color: white;
11576
- }
11577
-
11578
- .comment-source-badge.ai svg {
11579
- width: 12px;
11580
- height: 12px;
9870
+ .comment-source-badge.ai svg {
9871
+ width: 12px;
9872
+ height: 12px;
11581
9873
  }
11582
9874
 
11583
9875
  .comment-source-badge.user {
@@ -14149,74 +12441,366 @@ body.resizing * {
14149
12441
  font-variant-numeric: tabular-nums;
14150
12442
  }
14151
12443
 
14152
- .stack-nav-title {
12444
+ .stack-nav-title {
12445
+ overflow: hidden;
12446
+ text-overflow: ellipsis;
12447
+ white-space: nowrap;
12448
+ font-weight: 600;
12449
+ font-size: 14px;
12450
+ color: var(--color-text-primary, #1f2328);
12451
+ }
12452
+
12453
+ /* Secondary row: branch name */
12454
+ .stack-nav-branch {
12455
+ display: flex;
12456
+ align-items: center;
12457
+ gap: 4px;
12458
+ font-size: 12px;
12459
+ color: var(--color-text-tertiary, #656d76);
12460
+ overflow: hidden;
12461
+ }
12462
+
12463
+ .stack-nav-branch span {
12464
+ overflow: hidden;
12465
+ text-overflow: ellipsis;
12466
+ white-space: nowrap;
12467
+ }
12468
+
12469
+ .stack-nav-branch-icon {
12470
+ flex-shrink: 0;
12471
+ width: 12px;
12472
+ height: 12px;
12473
+ fill: currentColor;
12474
+ opacity: 0.7;
12475
+ }
12476
+
12477
+ [data-theme="dark"] .stack-nav-menu {
12478
+ background: var(--color-bg-elevated, #1e2329);
12479
+ border-color: var(--color-border-primary, #30363d);
12480
+ box-shadow: 0 4px 16px var(--color-shadow-large, rgba(0, 0, 0, 0.5));
12481
+ }
12482
+
12483
+ [data-theme="dark"] .stack-nav-item {
12484
+ color: var(--color-text-primary, #c9d1d9);
12485
+ }
12486
+
12487
+ [data-theme="dark"] .stack-nav-item:hover {
12488
+ background: var(--color-accent-lighter, rgba(88, 166, 255, 0.08));
12489
+ }
12490
+
12491
+ [data-theme="dark"] .stack-nav-item.current {
12492
+ background: var(--color-accent-lighter, rgba(88, 166, 255, 0.08));
12493
+ }
12494
+
12495
+ [data-theme="dark"] .stack-nav-title {
12496
+ color: var(--color-text-primary, #c9d1d9);
12497
+ }
12498
+
12499
+ [data-theme="dark"] .stack-nav-chevron {
12500
+ color: var(--color-text-tertiary, #6e7681);
12501
+ }
12502
+
12503
+ [data-theme="dark"] .stack-nav-branch {
12504
+ color: var(--color-text-tertiary, #6e7681);
12505
+ }
12506
+
12507
+ /* ============================================
12508
+ Stack Review — Stack Analysis Dialog
12509
+ ============================================ */
12510
+
12511
+ .stack-dialog-overlay {
12512
+ position: fixed;
12513
+ inset: 0;
12514
+ background: var(--color-bg-overlay, rgba(0, 0, 0, 0.5));
12515
+ display: flex;
12516
+ align-items: center;
12517
+ justify-content: center;
12518
+ z-index: 1000;
12519
+ }
12520
+
12521
+ .stack-dialog-backdrop {
12522
+ position: absolute;
12523
+ inset: 0;
12524
+ }
12525
+
12526
+ .stack-dialog {
12527
+ position: relative;
12528
+ z-index: 1;
12529
+ background: var(--color-bg-elevated, #fff);
12530
+ border: 1px solid var(--color-border-primary, #d1d9e0);
12531
+ border-radius: 12px;
12532
+ box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.2));
12533
+ width: 680px;
12534
+ max-width: 90vw;
12535
+ max-height: 80vh;
12536
+ display: flex;
12537
+ flex-direction: column;
12538
+ overflow: hidden;
12539
+ }
12540
+
12541
+ .stack-dialog-header {
12542
+ display: flex;
12543
+ align-items: center;
12544
+ justify-content: space-between;
12545
+ padding: 16px 20px;
12546
+ border-bottom: 1px solid var(--color-border-primary, #d1d9e0);
12547
+ font-size: 15px;
12548
+ font-weight: 600;
12549
+ color: var(--color-text-primary, #1f2328);
12550
+ }
12551
+
12552
+ .stack-dialog-header button {
12553
+ background: none;
12554
+ border: none;
12555
+ color: var(--color-text-tertiary, #656d76);
12556
+ cursor: pointer;
12557
+ padding: 4px;
12558
+ border-radius: 4px;
12559
+ transition: color 0.15s ease;
12560
+ }
12561
+
12562
+ .stack-dialog-header button:hover {
12563
+ color: var(--color-text-primary, #1f2328);
12564
+ }
12565
+
12566
+ .stack-dialog-body {
12567
+ flex: 1;
12568
+ overflow-y: auto;
12569
+ padding: 16px 20px;
12570
+ }
12571
+
12572
+ .stack-dialog-footer {
12573
+ display: flex;
12574
+ align-items: center;
12575
+ justify-content: flex-end;
12576
+ gap: 8px;
12577
+ padding: 12px 20px;
12578
+ border-top: 1px solid var(--color-border-primary, #d1d9e0);
12579
+ }
12580
+
12581
+ .stack-dialog-pr-item {
12582
+ display: flex;
12583
+ align-items: flex-start;
12584
+ gap: 10px;
12585
+ padding: 10px 4px;
12586
+ border-bottom: 1px solid var(--color-border-subtle, rgba(0, 0, 0, 0.06));
12587
+ font-size: 13px;
12588
+ color: var(--color-text-primary, #1f2328);
12589
+ }
12590
+
12591
+ .stack-dialog-pr-item:last-child {
12592
+ border-bottom: none;
12593
+ }
12594
+
12595
+ .stack-dialog-pr-checkbox {
12596
+ flex-shrink: 0;
12597
+ width: 16px;
12598
+ height: 16px;
12599
+ accent-color: var(--color-accent-primary, #0969da);
12600
+ cursor: pointer;
12601
+ }
12602
+
12603
+ .stack-dialog-pr-current {
12604
+ font-weight: 600;
12605
+ }
12606
+
12607
+ .stack-dialog-current-badge {
12608
+ flex-shrink: 0;
12609
+ width: 16px;
12610
+ text-align: center;
12611
+ color: var(--color-accent-ai, #f59e0b);
12612
+ font-size: 14px;
12613
+ }
12614
+
12615
+ .stack-dialog-pr-info {
12616
+ flex: 1;
12617
+ min-width: 0;
12618
+ display: flex;
12619
+ flex-direction: column;
12620
+ gap: 2px;
12621
+ }
12622
+
12623
+ .stack-dialog-pr-title-row {
12624
+ display: flex;
12625
+ align-items: center;
12626
+ gap: 8px;
12627
+ min-width: 0;
12628
+ }
12629
+
12630
+ .stack-dialog-loading {
12631
+ display: flex;
12632
+ align-items: center;
12633
+ justify-content: center;
12634
+ padding: 32px 16px;
12635
+ color: var(--color-text-secondary, #656d76);
12636
+ font-size: 13px;
12637
+ gap: 8px;
12638
+ }
12639
+
12640
+ .stack-dialog-loading .loading-spinner {
12641
+ width: 18px;
12642
+ height: 18px;
12643
+ margin-bottom: 0;
12644
+ }
12645
+
12646
+ .stack-dialog-pr-list {
12647
+ max-height: 50vh;
12648
+ overflow-y: auto;
12649
+ }
12650
+
12651
+ .stack-dialog-pr-number {
12652
+ flex-shrink: 0;
12653
+ font-family: var(--font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace);
12654
+ color: var(--color-text-secondary, #656d76);
12655
+ }
12656
+
12657
+ .stack-dialog-pr-title {
12658
+ flex: 1;
12659
+ min-width: 0;
14153
12660
  overflow: hidden;
14154
12661
  text-overflow: ellipsis;
14155
12662
  white-space: nowrap;
14156
- font-weight: 600;
14157
- font-size: 14px;
14158
- color: var(--color-text-primary, #1f2328);
14159
12663
  }
14160
12664
 
14161
- /* Secondary row: branch name */
14162
- .stack-nav-branch {
12665
+ .stack-dialog-pr-branch {
14163
12666
  display: flex;
14164
12667
  align-items: center;
14165
12668
  gap: 4px;
12669
+ color: var(--color-text-secondary, #656d76);
14166
12670
  font-size: 12px;
14167
- color: var(--color-text-tertiary, #656d76);
14168
- overflow: hidden;
14169
12671
  }
14170
12672
 
14171
- .stack-nav-branch span {
12673
+ .stack-dialog-branch-name {
14172
12674
  overflow: hidden;
14173
12675
  text-overflow: ellipsis;
14174
12676
  white-space: nowrap;
12677
+ min-width: 0;
14175
12678
  }
14176
12679
 
14177
- .stack-nav-branch-icon {
12680
+ .stack-dialog-branch-icon {
14178
12681
  flex-shrink: 0;
14179
- width: 12px;
14180
- height: 12px;
14181
- fill: currentColor;
14182
12682
  opacity: 0.7;
14183
12683
  }
14184
12684
 
14185
- [data-theme="dark"] .stack-nav-menu {
12685
+ .stack-dialog-analyzed-badge {
12686
+ flex-shrink: 0;
12687
+ color: var(--color-accent-primary, #0969da);
12688
+ font-size: 11px;
12689
+ }
12690
+
12691
+ .stack-dialog-note {
12692
+ color: var(--color-text-secondary, #656d76);
12693
+ font-size: 12px;
12694
+ padding: 8px 16px;
12695
+ border-top: 1px solid var(--color-border-subtle, rgba(0, 0, 0, 0.06));
12696
+ display: flex;
12697
+ flex-direction: column;
12698
+ gap: 4px;
12699
+ }
12700
+
12701
+ .stack-dialog-note-info {
12702
+ display: flex;
12703
+ align-items: flex-start;
12704
+ gap: 4px;
12705
+ color: var(--color-text-tertiary, #8c959f);
12706
+ }
12707
+
12708
+ .stack-dialog-info-icon {
12709
+ flex-shrink: 0;
12710
+ margin-top: 2px;
12711
+ opacity: 0.7;
12712
+ }
12713
+
12714
+ .stack-dialog-error {
12715
+ padding: 16px;
12716
+ color: var(--color-danger, #cf222e);
12717
+ }
12718
+
12719
+ .stack-dialog-controls {
12720
+ display: flex;
12721
+ gap: 8px;
12722
+ margin-bottom: 12px;
12723
+ }
12724
+
12725
+ .stack-dialog-controls button {
12726
+ background: none;
12727
+ border: none;
12728
+ color: var(--color-accent-primary, #0969da);
12729
+ cursor: pointer;
12730
+ font-size: 12px;
12731
+ padding: 2px 4px;
12732
+ }
12733
+
12734
+ .stack-dialog-controls button:hover {
12735
+ text-decoration: underline;
12736
+ }
12737
+
12738
+ [data-theme="dark"] .stack-dialog {
14186
12739
  background: var(--color-bg-elevated, #1e2329);
14187
12740
  border-color: var(--color-border-primary, #30363d);
14188
- box-shadow: 0 4px 16px var(--color-shadow-large, rgba(0, 0, 0, 0.5));
12741
+ box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.5));
14189
12742
  }
14190
12743
 
14191
- [data-theme="dark"] .stack-nav-item {
12744
+ [data-theme="dark"] .stack-dialog-header {
12745
+ border-color: var(--color-border-primary, #30363d);
14192
12746
  color: var(--color-text-primary, #c9d1d9);
14193
12747
  }
14194
12748
 
14195
- [data-theme="dark"] .stack-nav-item:hover {
14196
- background: var(--color-accent-lighter, rgba(88, 166, 255, 0.08));
12749
+ [data-theme="dark"] .stack-dialog-header button:hover {
12750
+ color: var(--color-text-primary, #c9d1d9);
14197
12751
  }
14198
12752
 
14199
- [data-theme="dark"] .stack-nav-item.current {
14200
- background: var(--color-accent-lighter, rgba(88, 166, 255, 0.08));
12753
+ [data-theme="dark"] .stack-dialog-body {
12754
+ color: var(--color-text-primary, #c9d1d9);
14201
12755
  }
14202
12756
 
14203
- [data-theme="dark"] .stack-nav-title {
12757
+ [data-theme="dark"] .stack-dialog-footer {
12758
+ border-color: var(--color-border-primary, #30363d);
12759
+ }
12760
+
12761
+ [data-theme="dark"] .stack-dialog-pr-item {
12762
+ border-color: var(--color-border-subtle, rgba(255, 255, 255, 0.06));
14204
12763
  color: var(--color-text-primary, #c9d1d9);
14205
12764
  }
14206
12765
 
14207
- [data-theme="dark"] .stack-nav-chevron {
14208
- color: var(--color-text-tertiary, #6e7681);
12766
+ [data-theme="dark"] .stack-dialog-loading {
12767
+ color: var(--color-text-secondary, #8b949e);
14209
12768
  }
14210
12769
 
14211
- [data-theme="dark"] .stack-nav-branch {
12770
+ [data-theme="dark"] .stack-dialog-controls button {
12771
+ color: var(--color-accent-primary, #58a6ff);
12772
+ }
12773
+
12774
+ [data-theme="dark"] .stack-dialog-pr-number {
12775
+ color: var(--color-text-secondary, #8b949e);
12776
+ }
12777
+
12778
+ [data-theme="dark"] .stack-dialog-pr-branch {
12779
+ color: var(--color-text-secondary, #8b949e);
12780
+ }
12781
+
12782
+ [data-theme="dark"] .stack-dialog-analyzed-badge {
12783
+ color: var(--color-accent-primary, #58a6ff);
12784
+ }
12785
+
12786
+ [data-theme="dark"] .stack-dialog-note {
12787
+ color: var(--color-text-secondary, #8b949e);
12788
+ border-color: var(--color-border-subtle, rgba(255, 255, 255, 0.06));
12789
+ }
12790
+
12791
+ [data-theme="dark"] .stack-dialog-note-info {
14212
12792
  color: var(--color-text-tertiary, #6e7681);
14213
12793
  }
14214
12794
 
12795
+ [data-theme="dark"] .stack-dialog-error {
12796
+ color: var(--color-danger, #f85149);
12797
+ }
12798
+
14215
12799
  /* ============================================
14216
- Stack Review — Stack Analysis Dialog
12800
+ Stack Review — Stack Progress Modal
14217
12801
  ============================================ */
14218
12802
 
14219
- .stack-dialog-overlay {
12803
+ .stack-progress-overlay {
14220
12804
  position: fixed;
14221
12805
  inset: 0;
14222
12806
  background: var(--color-bg-overlay, rgba(0, 0, 0, 0.5));
@@ -14226,19 +12810,17 @@ body.resizing * {
14226
12810
  z-index: 1000;
14227
12811
  }
14228
12812
 
14229
- .stack-dialog-backdrop {
12813
+ .stack-progress-backdrop {
14230
12814
  position: absolute;
14231
12815
  inset: 0;
14232
12816
  }
14233
12817
 
14234
- .stack-dialog {
14235
- position: relative;
14236
- z-index: 1;
12818
+ .stack-progress-modal {
14237
12819
  background: var(--color-bg-elevated, #fff);
14238
12820
  border: 1px solid var(--color-border-primary, #d1d9e0);
14239
12821
  border-radius: 12px;
14240
12822
  box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.2));
14241
- width: 680px;
12823
+ width: 520px;
14242
12824
  max-width: 90vw;
14243
12825
  max-height: 80vh;
14244
12826
  display: flex;
@@ -14246,7 +12828,7 @@ body.resizing * {
14246
12828
  overflow: hidden;
14247
12829
  }
14248
12830
 
14249
- .stack-dialog-header {
12831
+ .stack-progress-header {
14250
12832
  display: flex;
14251
12833
  align-items: center;
14252
12834
  justify-content: space-between;
@@ -14257,466 +12839,744 @@ body.resizing * {
14257
12839
  color: var(--color-text-primary, #1f2328);
14258
12840
  }
14259
12841
 
14260
- .stack-dialog-header button {
14261
- background: none;
14262
- border: none;
14263
- color: var(--color-text-tertiary, #656d76);
14264
- cursor: pointer;
14265
- padding: 4px;
14266
- border-radius: 4px;
14267
- transition: color 0.15s ease;
12842
+ .stack-progress-header button {
12843
+ background: none;
12844
+ border: none;
12845
+ color: var(--color-text-tertiary, #656d76);
12846
+ cursor: pointer;
12847
+ padding: 4px;
12848
+ border-radius: 4px;
12849
+ transition: color 0.15s ease;
12850
+ }
12851
+
12852
+ .stack-progress-header button:hover {
12853
+ color: var(--color-text-primary, #1f2328);
12854
+ }
12855
+
12856
+ .stack-progress-body {
12857
+ flex: 1;
12858
+ overflow-y: auto;
12859
+ padding: 16px 20px;
12860
+ }
12861
+
12862
+ .stack-progress-footer {
12863
+ display: flex;
12864
+ align-items: center;
12865
+ justify-content: flex-end;
12866
+ gap: 8px;
12867
+ padding: 12px 20px;
12868
+ border-top: 1px solid var(--color-border-primary, #d1d9e0);
12869
+ }
12870
+
12871
+ .stack-progress-pr-list {
12872
+ max-height: 320px;
12873
+ overflow-y: auto;
12874
+ }
12875
+
12876
+ .stack-progress-pr-row {
12877
+ display: flex;
12878
+ align-items: center;
12879
+ gap: 12px;
12880
+ padding: 10px 4px;
12881
+ border-bottom: 1px solid var(--color-border-subtle, rgba(0, 0, 0, 0.06));
12882
+ font-size: 13px;
12883
+ }
12884
+
12885
+ .stack-progress-pr-row:last-child {
12886
+ border-bottom: none;
12887
+ }
12888
+
12889
+ .stack-progress-status-icon {
12890
+ flex-shrink: 0;
12891
+ width: 20px;
12892
+ height: 20px;
12893
+ display: flex;
12894
+ align-items: center;
12895
+ justify-content: center;
12896
+ font-size: 14px;
12897
+ }
12898
+
12899
+ .stack-progress-pr-label {
12900
+ flex: 1;
12901
+ min-width: 0;
12902
+ overflow: hidden;
12903
+ text-overflow: ellipsis;
12904
+ white-space: nowrap;
12905
+ color: var(--color-text-primary, #1f2328);
12906
+ }
12907
+
12908
+ .stack-progress-pr-link {
12909
+ cursor: pointer;
12910
+ color: var(--color-accent-primary, #0969da);
12911
+ }
12912
+
12913
+ .stack-progress-pr-link:hover {
12914
+ text-decoration: underline;
12915
+ }
12916
+
12917
+ .stack-progress-pr-detail {
12918
+ flex-shrink: 0;
12919
+ color: var(--color-text-secondary, #656d76);
12920
+ }
12921
+
12922
+ .stack-progress-pr-detail a {
12923
+ color: var(--color-accent-primary, #0969da);
12924
+ text-decoration: none;
12925
+ }
12926
+
12927
+ .stack-progress-pr-detail a:hover {
12928
+ text-decoration: underline;
12929
+ }
12930
+
12931
+ .status-completed .stack-progress-status-icon {
12932
+ color: var(--color-accent-emphasis, #1a7f37);
12933
+ }
12934
+
12935
+ .status-running .stack-progress-status-icon {
12936
+ color: var(--color-accent-ai, #f59e0b);
12937
+ animation: pulse-dot 1.2s ease-in-out infinite;
12938
+ }
12939
+
12940
+ .status-setting_up .stack-progress-status-icon {
12941
+ color: var(--color-text-secondary, #656d76);
12942
+ animation: pulse-dot 1.2s ease-in-out infinite;
12943
+ }
12944
+
12945
+ .status-pending .stack-progress-status-icon {
12946
+ color: var(--color-text-muted, #d1d9e0);
12947
+ }
12948
+
12949
+ .status-failed .stack-progress-status-icon {
12950
+ color: var(--color-danger, #cf222e);
12951
+ }
12952
+
12953
+ [data-theme="dark"] .stack-progress-modal {
12954
+ background: var(--color-bg-elevated, #1e2329);
12955
+ border-color: var(--color-border-primary, #30363d);
12956
+ box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.5));
12957
+ }
12958
+
12959
+ [data-theme="dark"] .stack-progress-header {
12960
+ border-color: var(--color-border-primary, #30363d);
12961
+ color: var(--color-text-primary, #c9d1d9);
14268
12962
  }
14269
12963
 
14270
- .stack-dialog-header button:hover {
14271
- color: var(--color-text-primary, #1f2328);
12964
+ [data-theme="dark"] .stack-progress-header button:hover {
12965
+ color: var(--color-text-primary, #c9d1d9);
14272
12966
  }
14273
12967
 
14274
- .stack-dialog-body {
14275
- flex: 1;
14276
- overflow-y: auto;
14277
- padding: 16px 20px;
12968
+ [data-theme="dark"] .stack-progress-body {
12969
+ color: var(--color-text-primary, #c9d1d9);
14278
12970
  }
14279
12971
 
14280
- .stack-dialog-footer {
14281
- display: flex;
14282
- align-items: center;
14283
- justify-content: flex-end;
14284
- gap: 8px;
14285
- padding: 12px 20px;
14286
- border-top: 1px solid var(--color-border-primary, #d1d9e0);
12972
+ [data-theme="dark"] .stack-progress-footer {
12973
+ border-color: var(--color-border-primary, #30363d);
14287
12974
  }
14288
12975
 
14289
- .stack-dialog-pr-item {
14290
- display: flex;
14291
- align-items: flex-start;
14292
- gap: 10px;
14293
- padding: 10px 4px;
14294
- border-bottom: 1px solid var(--color-border-subtle, rgba(0, 0, 0, 0.06));
14295
- font-size: 13px;
14296
- color: var(--color-text-primary, #1f2328);
12976
+ [data-theme="dark"] .stack-progress-pr-row {
12977
+ border-color: var(--color-border-subtle, rgba(255, 255, 255, 0.06));
14297
12978
  }
14298
12979
 
14299
- .stack-dialog-pr-item:last-child {
14300
- border-bottom: none;
12980
+ [data-theme="dark"] .stack-progress-pr-label {
12981
+ color: var(--color-text-primary, #c9d1d9);
14301
12982
  }
14302
12983
 
14303
- .stack-dialog-pr-checkbox {
14304
- flex-shrink: 0;
14305
- width: 16px;
14306
- height: 16px;
14307
- accent-color: var(--color-accent-primary, #0969da);
14308
- cursor: pointer;
12984
+ [data-theme="dark"] .stack-progress-pr-link {
12985
+ color: var(--color-accent-primary, #58a6ff);
14309
12986
  }
14310
12987
 
14311
- .stack-dialog-pr-current {
14312
- font-weight: 600;
12988
+ [data-theme="dark"] .stack-progress-pr-detail {
12989
+ color: var(--color-text-secondary, #8b949e);
14313
12990
  }
14314
12991
 
14315
- .stack-dialog-current-badge {
14316
- flex-shrink: 0;
14317
- width: 16px;
14318
- text-align: center;
14319
- color: var(--color-accent-ai, #f59e0b);
14320
- font-size: 14px;
12992
+ [data-theme="dark"] .stack-progress-pr-detail a {
12993
+ color: var(--color-accent-primary, #58a6ff);
14321
12994
  }
14322
12995
 
14323
- .stack-dialog-pr-info {
14324
- flex: 1;
14325
- min-width: 0;
14326
- display: flex;
14327
- flex-direction: column;
14328
- gap: 2px;
12996
+ [data-theme="dark"] .status-completed .stack-progress-status-icon {
12997
+ color: var(--color-accent-emphasis-hover, #2ea043);
14329
12998
  }
14330
12999
 
14331
- .stack-dialog-pr-title-row {
14332
- display: flex;
14333
- align-items: center;
14334
- gap: 8px;
14335
- min-width: 0;
13000
+ [data-theme="dark"] .status-running .stack-progress-status-icon {
13001
+ color: var(--color-accent-ai-dark, #f59e0b);
14336
13002
  }
14337
13003
 
14338
- .stack-dialog-loading {
14339
- display: flex;
14340
- align-items: center;
14341
- justify-content: center;
14342
- padding: 32px 16px;
14343
- color: var(--color-text-secondary, #656d76);
14344
- font-size: 13px;
14345
- gap: 8px;
13004
+ [data-theme="dark"] .status-setting_up .stack-progress-status-icon {
13005
+ color: var(--color-text-secondary, #8b949e);
14346
13006
  }
14347
13007
 
14348
- .stack-dialog-loading .loading-spinner {
14349
- width: 18px;
14350
- height: 18px;
14351
- margin-bottom: 0;
13008
+ [data-theme="dark"] .status-pending .stack-progress-status-icon {
13009
+ color: var(--color-text-muted, #484f58);
14352
13010
  }
14353
13011
 
14354
- .stack-dialog-pr-list {
14355
- max-height: 50vh;
14356
- overflow-y: auto;
13012
+ [data-theme="dark"] .status-failed .stack-progress-status-icon {
13013
+ color: var(--color-danger, #f85149);
14357
13014
  }
14358
13015
 
14359
- .stack-dialog-pr-number {
14360
- flex-shrink: 0;
14361
- font-family: var(--font-mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace);
14362
- color: var(--color-text-secondary, #656d76);
13016
+ /* ==========================================================================
13017
+ Hunk Summary Annotations (Phase 5)
13018
+ ========================================================================== */
13019
+
13020
+ .hunk-summary-row {
13021
+ background: transparent;
14363
13022
  }
14364
13023
 
14365
- .stack-dialog-pr-title {
14366
- flex: 1;
14367
- min-width: 0;
14368
- overflow: hidden;
14369
- text-overflow: ellipsis;
14370
- white-space: nowrap;
13024
+ .hunk-summary-cell {
13025
+ padding: 4px 0;
13026
+ border: none;
14371
13027
  }
14372
13028
 
14373
- .stack-dialog-pr-branch {
13029
+ .hunk-summary-annotation {
14374
13030
  display: flex;
14375
- align-items: center;
14376
- gap: 4px;
14377
- color: var(--color-text-secondary, #656d76);
14378
- font-size: 12px;
13031
+ align-items: flex-start;
13032
+ gap: 10px;
13033
+ padding: 8px 12px;
13034
+ margin: 6px auto;
13035
+ font-size: 13px;
13036
+ line-height: 1.5;
13037
+ color: #0550ae;
13038
+ background: rgba(9, 105, 218, 0.06);
13039
+ border: 1px solid rgba(9, 105, 218, 0.18);
13040
+ border-left: 3px solid #0969da;
13041
+ border-radius: var(--radius-md, 6px);
13042
+ max-width: calc(100vw - var(--sidebar-width, 0px) - var(--right-panel-group-width, 0px) - 64px);
13043
+ box-sizing: border-box;
13044
+ word-break: break-word;
14379
13045
  }
14380
13046
 
14381
- .stack-dialog-branch-name {
14382
- overflow: hidden;
14383
- text-overflow: ellipsis;
14384
- white-space: nowrap;
14385
- min-width: 0;
13047
+ [data-theme="dark"] .hunk-summary-annotation {
13048
+ color: #79c0ff;
13049
+ background: rgba(56, 139, 253, 0.10);
13050
+ border-color: rgba(56, 139, 253, 0.25);
13051
+ border-left-color: #58a6ff;
14386
13052
  }
14387
13053
 
14388
- .stack-dialog-branch-icon {
13054
+ .hunk-summary-icon {
14389
13055
  flex-shrink: 0;
14390
- opacity: 0.7;
13056
+ display: inline-flex;
13057
+ align-items: center;
13058
+ justify-content: center;
13059
+ width: 16px;
13060
+ height: 16px;
13061
+ margin-top: 1px;
13062
+ opacity: 0.85;
14391
13063
  }
14392
13064
 
14393
- .stack-dialog-analyzed-badge {
14394
- flex-shrink: 0;
14395
- color: var(--color-accent-primary, #0969da);
14396
- font-size: 11px;
13065
+ .hunk-summary-text {
13066
+ flex: 1;
13067
+ min-width: 0;
14397
13068
  }
14398
13069
 
14399
- .stack-dialog-note {
14400
- color: var(--color-text-secondary, #656d76);
14401
- font-size: 12px;
14402
- padding: 8px 16px;
14403
- border-top: 1px solid var(--color-border-subtle, rgba(0, 0, 0, 0.06));
14404
- display: flex;
14405
- flex-direction: column;
14406
- gap: 4px;
13070
+ /* Review-level toggle hides every annotation row */
13071
+ body.summaries-hidden .hunk-summary-row,
13072
+ .d2h-file-wrapper.summaries-hidden-file .hunk-summary-row {
13073
+ display: none;
14407
13074
  }
14408
13075
 
14409
- .stack-dialog-note-info {
14410
- display: flex;
14411
- align-items: flex-start;
14412
- gap: 4px;
14413
- color: var(--color-text-tertiary, #8c959f);
13076
+ /* ---------- Toolbar toggle states ---------- */
13077
+ /* Default toolbar buttons inherit a transparent border; the toggle button
13078
+ uses a fixed neutral border so the on-state color swap is visible. */
13079
+ .btn-summary-toggle {
13080
+ position: relative;
13081
+ border: 1px solid var(--color-border-primary, #d1d9e0);
13082
+ color: var(--color-text-secondary, #57606a);
13083
+ transition: color var(--transition-fast, 0.1s ease),
13084
+ border-color var(--transition-fast, 0.1s ease),
13085
+ background-color var(--transition-fast, 0.1s ease);
14414
13086
  }
14415
13087
 
14416
- .stack-dialog-info-icon {
14417
- flex-shrink: 0;
14418
- margin-top: 2px;
14419
- opacity: 0.7;
13088
+ /* Summaries are visible (default state when feature is on). */
13089
+ .btn-summary-toggle.active {
13090
+ color: var(--color-accent-primary, #0969da);
13091
+ border-color: var(--color-accent-primary, #0969da);
13092
+ background-color: rgba(9, 105, 218, 0.08);
14420
13093
  }
14421
13094
 
14422
- .stack-dialog-error {
14423
- padding: 16px;
14424
- color: var(--color-danger, #cf222e);
13095
+ [data-theme="dark"] .btn-summary-toggle.active {
13096
+ color: var(--color-accent-primary, #58a6ff);
13097
+ border-color: var(--color-accent-primary, #58a6ff);
13098
+ background-color: rgba(56, 139, 253, 0.12);
14425
13099
  }
14426
13100
 
14427
- .stack-dialog-controls {
14428
- display: flex;
14429
- gap: 8px;
14430
- margin-bottom: 12px;
13101
+ /* Summaries hidden — the off state is just the base button styling
13102
+ (gray secondary color, no background). Matches the tour-toggle pattern
13103
+ so the two buttons read consistently when off. */
13104
+
13105
+ /* "Generating" pulse — applied while the background summary job is running. */
13106
+ .btn-summary-toggle.generating {
13107
+ animation: summaryPulse 1.6s ease-in-out infinite;
14431
13108
  }
14432
13109
 
14433
- .stack-dialog-controls button {
14434
- background: none;
14435
- border: none;
14436
- color: var(--color-accent-primary, #0969da);
14437
- cursor: pointer;
14438
- font-size: 12px;
14439
- padding: 2px 4px;
13110
+ @keyframes summaryPulse {
13111
+ 0%, 100% {
13112
+ box-shadow: 0 0 0 0 rgba(9, 105, 218, 0);
13113
+ }
13114
+ 50% {
13115
+ box-shadow: 0 0 0 4px rgba(9, 105, 218, 0.18);
13116
+ }
14440
13117
  }
14441
13118
 
14442
- .stack-dialog-controls button:hover {
14443
- text-decoration: underline;
13119
+ [data-theme="dark"] .btn-summary-toggle.generating {
13120
+ animation-name: summaryPulseDark;
14444
13121
  }
14445
13122
 
14446
- [data-theme="dark"] .stack-dialog {
14447
- background: var(--color-bg-elevated, #1e2329);
14448
- border-color: var(--color-border-primary, #30363d);
14449
- box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.5));
13123
+ @keyframes summaryPulseDark {
13124
+ 0%, 100% {
13125
+ box-shadow: 0 0 0 0 rgba(56, 139, 253, 0);
13126
+ }
13127
+ 50% {
13128
+ box-shadow: 0 0 0 4px rgba(56, 139, 253, 0.28);
13129
+ }
14450
13130
  }
14451
13131
 
14452
- [data-theme="dark"] .stack-dialog-header {
14453
- border-color: var(--color-border-primary, #30363d);
14454
- color: var(--color-text-primary, #c9d1d9);
13132
+ /* Custom hover label — shown alongside the native title in case the user's
13133
+ browser is suppressing native tooltips. Uses a `data-label` attr so the
13134
+ label tracks the on/off state. */
13135
+ .btn-summary-toggle[data-label]:hover::before {
13136
+ content: attr(data-label);
13137
+ position: absolute;
13138
+ top: calc(100% + 6px);
13139
+ right: 0;
13140
+ z-index: 200;
13141
+ padding: 4px 8px;
13142
+ font-size: 12px;
13143
+ line-height: 1.2;
13144
+ white-space: nowrap;
13145
+ color: var(--color-text-primary, #24292f);
13146
+ background: var(--color-bg-primary, #ffffff);
13147
+ border: 1px solid var(--color-border-primary, #d1d9e0);
13148
+ border-radius: var(--radius-sm, 4px);
13149
+ box-shadow: 0 2px 4px var(--color-shadow, rgba(27, 31, 36, 0.04));
13150
+ pointer-events: none;
14455
13151
  }
14456
13152
 
14457
- [data-theme="dark"] .stack-dialog-header button:hover {
13153
+ [data-theme="dark"] .btn-summary-toggle[data-label]:hover::before {
14458
13154
  color: var(--color-text-primary, #c9d1d9);
13155
+ background: var(--color-bg-primary, #0d1117);
13156
+ border-color: var(--color-border-primary, #30363d);
14459
13157
  }
14460
13158
 
14461
- [data-theme="dark"] .stack-dialog-body {
14462
- color: var(--color-text-primary, #c9d1d9);
13159
+ .file-header-summary-toggle.summaries-off {
13160
+ opacity: 0.45;
14463
13161
  }
14464
13162
 
14465
- [data-theme="dark"] .stack-dialog-footer {
14466
- border-color: var(--color-border-primary, #30363d);
13163
+ /* ==========================================================================
13164
+ Tour Annotations & Tour Bar (Phase 8)
13165
+ ========================================================================== */
13166
+
13167
+ /* The inline annotation row that is mounted above the anchor line for each
13168
+ stop. Pale-yellow palette to differentiate from info-blue summaries. */
13169
+ .tour-annotation-row {
13170
+ background: transparent;
14467
13171
  }
14468
13172
 
14469
- [data-theme="dark"] .stack-dialog-pr-item {
14470
- border-color: var(--color-border-subtle, rgba(255, 255, 255, 0.06));
14471
- color: var(--color-text-primary, #c9d1d9);
13173
+ .tour-annotation-cell {
13174
+ padding: 4px 0;
13175
+ border: none;
14472
13176
  }
14473
13177
 
14474
- [data-theme="dark"] .stack-dialog-loading {
14475
- color: var(--color-text-secondary, #8b949e);
13178
+ .tour-annotation {
13179
+ display: flex;
13180
+ flex-direction: column;
13181
+ gap: 6px;
13182
+ padding: 10px 14px;
13183
+ margin: 6px auto;
13184
+ font-size: 13px;
13185
+ line-height: 1.45;
13186
+ color: #7d5700;
13187
+ /* Brighter amber matching the .tour-bar gradient so stops read as part
13188
+ of the same tour surface, not a muted variant of it. */
13189
+ background: linear-gradient(180deg, #fff8e1 0%, #fef3c7 100%);
13190
+ border: 1px solid rgba(212, 167, 44, 0.55);
13191
+ border-left: 3px solid #d4a72c;
13192
+ border-radius: var(--radius-md, 6px);
13193
+ max-width: calc(100vw - var(--sidebar-width, 0px) - var(--right-panel-group-width, 0px) - 64px);
13194
+ box-sizing: border-box;
13195
+ word-break: break-word;
13196
+ transition: box-shadow var(--transition-fast, 0.1s ease),
13197
+ border-color var(--transition-fast, 0.1s ease);
14476
13198
  }
14477
13199
 
14478
- [data-theme="dark"] .stack-dialog-controls button {
14479
- color: var(--color-accent-primary, #58a6ff);
13200
+ [data-theme="dark"] .tour-annotation {
13201
+ color: #e3b341;
13202
+ /* Mirror the bar's dark-mode amber wash so light- and dark-mode tours
13203
+ share one visual language. */
13204
+ background: linear-gradient(180deg, rgba(187, 128, 9, 0.18) 0%, rgba(187, 128, 9, 0.28) 100%),
13205
+ var(--color-bg-primary, #0d1117);
13206
+ border-color: rgba(187, 128, 9, 0.55);
13207
+ border-left-color: #bb8009;
14480
13208
  }
14481
13209
 
14482
- [data-theme="dark"] .stack-dialog-pr-number {
14483
- color: var(--color-text-secondary, #8b949e);
13210
+ .tour-annotation-header {
13211
+ display: flex;
13212
+ align-items: center;
13213
+ justify-content: space-between;
13214
+ gap: 8px;
13215
+ font-weight: 600;
14484
13216
  }
14485
13217
 
14486
- [data-theme="dark"] .stack-dialog-pr-branch {
14487
- color: var(--color-text-secondary, #8b949e);
13218
+ .tour-stop-marker {
13219
+ display: inline-flex;
13220
+ align-items: center;
13221
+ gap: 4px;
13222
+ font-size: 12px;
13223
+ text-transform: uppercase;
13224
+ letter-spacing: 0.04em;
13225
+ opacity: 0.9;
14488
13226
  }
14489
13227
 
14490
- [data-theme="dark"] .stack-dialog-analyzed-badge {
14491
- color: var(--color-accent-primary, #58a6ff);
13228
+ .tour-stop-marker svg {
13229
+ width: 14px;
13230
+ height: 14px;
14492
13231
  }
14493
13232
 
14494
- [data-theme="dark"] .stack-dialog-note {
14495
- color: var(--color-text-secondary, #8b949e);
14496
- border-color: var(--color-border-subtle, rgba(255, 255, 255, 0.06));
13233
+ .tour-annotation-title {
13234
+ margin: 0;
13235
+ font-size: 14px;
13236
+ font-weight: 600;
13237
+ line-height: 1.3;
14497
13238
  }
14498
13239
 
14499
- [data-theme="dark"] .stack-dialog-note-info {
14500
- color: var(--color-text-tertiary, #6e7681);
13240
+ .tour-annotation-description {
13241
+ margin: 0;
13242
+ font-size: 13px;
13243
+ font-weight: 400;
13244
+ line-height: 1.45;
13245
+ opacity: 0.95;
13246
+ }
13247
+
13248
+ /* Wrap around the description <p>. Collapsed state uses the WebKit
13249
+ line-clamp triplet to cap visible content at ~3 lines; expanded state
13250
+ removes the clamp so the full description shows. The wrapper (not the
13251
+ inner <p>) carries the clamp so the JS overflow check has a stable
13252
+ element to measure (`scrollHeight > clientHeight`). */
13253
+ .tour-annotation-description-wrap {
13254
+ display: -webkit-box;
13255
+ -webkit-box-orient: vertical;
13256
+ -webkit-line-clamp: 3;
13257
+ line-clamp: 3;
13258
+ overflow: hidden;
14501
13259
  }
14502
13260
 
14503
- [data-theme="dark"] .stack-dialog-error {
14504
- color: var(--color-danger, #f85149);
13261
+ .tour-annotation-description-wrap.expanded {
13262
+ display: block;
13263
+ -webkit-line-clamp: unset;
13264
+ line-clamp: unset;
13265
+ overflow: visible;
14505
13266
  }
14506
13267
 
14507
- /* ============================================
14508
- Stack Review Stack Progress Modal
14509
- ============================================ */
14510
-
14511
- .stack-progress-overlay {
14512
- position: fixed;
14513
- inset: 0;
14514
- background: var(--color-bg-overlay, rgba(0, 0, 0, 0.5));
13268
+ /* Footer holds only the "Show more"/"Show less" toggle when the
13269
+ description overflows the line-clamp; otherwise it's an empty stub.
13270
+ Chat about lives in the header now. */
13271
+ .tour-annotation-footer {
14515
13272
  display: flex;
14516
13273
  align-items: center;
14517
- justify-content: center;
14518
- z-index: 1000;
13274
+ gap: 6px;
13275
+ margin-top: 4px;
14519
13276
  }
14520
13277
 
14521
- .stack-progress-backdrop {
14522
- position: absolute;
14523
- inset: 0;
13278
+ .tour-annotation-footer:empty {
13279
+ display: none;
14524
13280
  }
14525
13281
 
14526
- .stack-progress-modal {
14527
- background: var(--color-bg-elevated, #fff);
14528
- border: 1px solid var(--color-border-primary, #d1d9e0);
14529
- border-radius: 12px;
14530
- box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.2));
14531
- width: 520px;
14532
- max-width: 90vw;
14533
- max-height: 80vh;
14534
- display: flex;
14535
- flex-direction: column;
14536
- overflow: hidden;
13282
+ /* "Show more" / "Show less" toggle. Styled as a borderless amber link
13283
+ button so it reads as part of the tour annotation but doesn't compete
13284
+ with the primary Chat about action. */
13285
+ .tour-annotation-show-more-btn {
13286
+ appearance: none;
13287
+ background: none;
13288
+ border: 0;
13289
+ padding: 2px 4px;
13290
+ margin: 0;
13291
+ font: inherit;
13292
+ font-size: 12px;
13293
+ font-weight: 600;
13294
+ color: #7d5700;
13295
+ cursor: pointer;
13296
+ text-decoration: underline;
13297
+ text-underline-offset: 2px;
13298
+ border-radius: var(--radius-sm, 3px);
14537
13299
  }
14538
13300
 
14539
- .stack-progress-header {
14540
- display: flex;
14541
- align-items: center;
14542
- justify-content: space-between;
14543
- padding: 16px 20px;
14544
- border-bottom: 1px solid var(--color-border-primary, #d1d9e0);
14545
- font-size: 15px;
14546
- font-weight: 600;
14547
- color: var(--color-text-primary, #1f2328);
13301
+ .tour-annotation-show-more-btn:hover {
13302
+ color: #5b3f00;
13303
+ background: rgba(255, 255, 255, 0.45);
14548
13304
  }
14549
13305
 
14550
- .stack-progress-header button {
14551
- background: none;
14552
- border: none;
14553
- color: var(--color-text-tertiary, #656d76);
14554
- cursor: pointer;
14555
- padding: 4px;
14556
- border-radius: 4px;
14557
- transition: color 0.15s ease;
13306
+ .tour-annotation-show-more-btn:focus-visible {
13307
+ outline: 2px solid #d4a72c;
13308
+ outline-offset: 1px;
14558
13309
  }
14559
13310
 
14560
- .stack-progress-header button:hover {
14561
- color: var(--color-text-primary, #1f2328);
13311
+ [data-theme="dark"] .tour-annotation-show-more-btn {
13312
+ color: #e3b341;
14562
13313
  }
14563
13314
 
14564
- .stack-progress-body {
14565
- flex: 1;
14566
- overflow-y: auto;
14567
- padding: 16px 20px;
13315
+ [data-theme="dark"] .tour-annotation-show-more-btn:hover {
13316
+ color: #f3c861;
13317
+ background: rgba(187, 128, 9, 0.18);
14568
13318
  }
14569
13319
 
14570
- .stack-progress-footer {
14571
- display: flex;
13320
+ /* The chat button on a tour-stop annotation reuses .ai-action / .ai-action-chat
13321
+ so its idle and hover treatments stay in sync with the rest of the app. We
13322
+ override surface colors (so it reads on the amber background) AND collapse
13323
+ it to an icon-only square — the button sits in the header next to the
13324
+ stop marker, where a labelled button would crowd the title row. The title
13325
+ attribute / aria-label carry the meaning for accessibility + tooltip. */
13326
+ .tour-annotation .tour-annotation-chat-btn {
13327
+ background: rgba(255, 255, 255, 0.6);
13328
+ color: #7d5700;
13329
+ border: 1px solid rgba(212, 167, 44, 0.55);
13330
+ padding: 2px;
13331
+ width: 22px;
13332
+ height: 22px;
13333
+ display: inline-flex;
14572
13334
  align-items: center;
14573
- justify-content: flex-end;
14574
- gap: 8px;
14575
- padding: 12px 20px;
14576
- border-top: 1px solid var(--color-border-primary, #d1d9e0);
13335
+ justify-content: center;
13336
+ flex: 0 0 auto;
14577
13337
  }
14578
13338
 
14579
- .stack-progress-pr-list {
14580
- max-height: 320px;
14581
- overflow-y: auto;
13339
+ .tour-annotation .tour-annotation-chat-btn svg {
13340
+ width: 14px;
13341
+ height: 14px;
14582
13342
  }
14583
13343
 
14584
- .stack-progress-pr-row {
14585
- display: flex;
14586
- align-items: center;
14587
- gap: 12px;
14588
- padding: 10px 4px;
14589
- border-bottom: 1px solid var(--color-border-subtle, rgba(0, 0, 0, 0.06));
14590
- font-size: 13px;
13344
+ .tour-annotation .tour-annotation-chat-btn:hover {
13345
+ background: rgba(255, 255, 255, 0.9);
13346
+ color: #5b3f00;
13347
+ border-color: #d4a72c;
14591
13348
  }
14592
13349
 
14593
- .stack-progress-pr-row:last-child {
14594
- border-bottom: none;
13350
+ [data-theme="dark"] .tour-annotation .tour-annotation-chat-btn {
13351
+ background: rgba(187, 128, 9, 0.12);
13352
+ color: #e3b341;
13353
+ border-color: rgba(187, 128, 9, 0.55);
14595
13354
  }
14596
13355
 
14597
- .stack-progress-status-icon {
14598
- flex-shrink: 0;
14599
- width: 20px;
14600
- height: 20px;
14601
- display: flex;
14602
- align-items: center;
14603
- justify-content: center;
14604
- font-size: 14px;
13356
+ [data-theme="dark"] .tour-annotation .tour-annotation-chat-btn:hover {
13357
+ background: rgba(187, 128, 9, 0.25);
13358
+ color: #f3c861;
13359
+ border-color: #e3b341;
14605
13360
  }
14606
13361
 
14607
- .stack-progress-pr-label {
14608
- flex: 1;
14609
- min-width: 0;
14610
- overflow: hidden;
14611
- text-overflow: ellipsis;
14612
- white-space: nowrap;
14613
- color: var(--color-text-primary, #1f2328);
13362
+ /* Emphasize the currently-active stop annotation. */
13363
+ body.tour-active .tour-annotation-row.active-stop .tour-annotation {
13364
+ box-shadow: 0 0 0 2px rgba(212, 167, 44, 0.55),
13365
+ 0 2px 6px rgba(0, 0, 0, 0.08);
13366
+ border-color: #d4a72c;
14614
13367
  }
14615
13368
 
14616
- .stack-progress-pr-link {
14617
- cursor: pointer;
14618
- color: var(--color-accent-primary, #0969da);
13369
+ [data-theme="dark"] body.tour-active .tour-annotation-row.active-stop .tour-annotation {
13370
+ box-shadow: 0 0 0 2px rgba(187, 128, 9, 0.65),
13371
+ 0 2px 6px rgba(0, 0, 0, 0.30);
13372
+ border-color: #e3b341;
14619
13373
  }
14620
13374
 
14621
- .stack-progress-pr-link:hover {
14622
- text-decoration: underline;
13375
+ /* ---------- Sticky top tour bar ---------- */
13376
+ :root {
13377
+ /* Height assumed by the diff-toolbar / file-header offset rules below.
13378
+ Keep this in sync with the bar's computed height (icon + button row +
13379
+ vertical padding). The bar also sets `min-height: var(--tour-bar-height)`
13380
+ so its actual rendered height never drops below this value. */
13381
+ --tour-bar-height: 56px;
14623
13382
  }
14624
13383
 
14625
- .stack-progress-pr-detail {
13384
+ /* While a tour is active, push the sticky `.diff-toolbar` and the
13385
+ per-file `.d2h-file-header` down by the bar's height so they stack
13386
+ below it instead of overlapping. The bar itself is `position: sticky;
13387
+ top: 0` inside the same scroll container (.main-layout .diff-view),
13388
+ so all three pin in order: tour bar (top: 0), diff toolbar (top:
13389
+ --tour-bar-height), file header (top: --toolbar-height + --tour-bar-height). */
13390
+ body.tour-active .diff-toolbar {
13391
+ top: var(--tour-bar-height);
13392
+ }
13393
+
13394
+ body.tour-active .d2h-file-header {
13395
+ top: calc(var(--toolbar-height, 0px) + var(--tour-bar-height));
13396
+ }
13397
+
13398
+ .tour-bar {
13399
+ /* Sticky inside the diff-view scroll container so the bar spans the
13400
+ diff width only — the file-tree sidebar (and its hide/show toggle in
13401
+ the diff toolbar) stays visible and clickable. Mounted as the first
13402
+ child of .diff-view via TourBar.mount(parent). */
13403
+ position: sticky;
13404
+ top: 0;
13405
+ /* z-index must exceed .diff-toolbar (5) and .d2h-file-header (4) so the
13406
+ bar paints above them at the top of the scrollport. */
13407
+ z-index: 6;
13408
+ /* Lock the rendered height to the var so the sticky-top offsets on
13409
+ .diff-toolbar and .d2h-file-header line up exactly with the bar's
13410
+ bottom edge (no gap, no overlap). flex-shrink:0 prevents the parent
13411
+ flex column (.diff-view) from squashing the bar below min-height. */
13412
+ box-sizing: border-box;
14626
13413
  flex-shrink: 0;
14627
- color: var(--color-text-secondary, #656d76);
13414
+ min-height: var(--tour-bar-height);
13415
+ display: flex;
13416
+ align-items: center;
13417
+ justify-content: space-between;
13418
+ gap: 12px;
13419
+ padding: 10px 16px;
13420
+ /* Distinctive amber theme so the bar reads as a tour-mode chrome and
13421
+ not just another toolbar. Soft tinted background + a thicker amber
13422
+ bottom rule echo the per-stop annotation accent (#d4a72c). */
13423
+ background: linear-gradient(180deg, #fff8e1 0%, #fef3c7 100%);
13424
+ border-bottom: 2px solid #d4a72c;
13425
+ box-shadow: 0 2px 12px rgba(212, 167, 44, 0.18);
13426
+ font-size: 13px;
13427
+ color: #7d5700;
14628
13428
  }
14629
13429
 
14630
- .stack-progress-pr-detail a {
14631
- color: var(--color-accent-primary, #0969da);
14632
- text-decoration: none;
13430
+ [data-theme="dark"] .tour-bar {
13431
+ background: linear-gradient(180deg, rgba(187, 128, 9, 0.18) 0%, rgba(187, 128, 9, 0.28) 100%),
13432
+ var(--color-bg-primary, #0d1117);
13433
+ border-bottom-color: #bb8009;
13434
+ color: #e3b341;
13435
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.40);
14633
13436
  }
14634
13437
 
14635
- .stack-progress-pr-detail a:hover {
14636
- text-decoration: underline;
13438
+ .tour-bar__brand {
13439
+ display: inline-flex;
13440
+ align-items: center;
13441
+ gap: 8px;
13442
+ font-weight: 600;
13443
+ color: #7d5700;
14637
13444
  }
14638
13445
 
14639
- .status-completed .stack-progress-status-icon {
14640
- color: var(--color-accent-emphasis, #1a7f37);
13446
+ [data-theme="dark"] .tour-bar__brand {
13447
+ color: #e3b341;
14641
13448
  }
14642
13449
 
14643
- .status-running .stack-progress-status-icon {
14644
- color: var(--color-accent-ai, #f59e0b);
14645
- animation: pulse-dot 1.2s ease-in-out infinite;
13450
+ .tour-bar__brand svg {
13451
+ width: 16px;
13452
+ height: 16px;
14646
13453
  }
14647
13454
 
14648
- .status-setting_up .stack-progress-status-icon {
14649
- color: var(--color-text-secondary, #656d76);
14650
- animation: pulse-dot 1.2s ease-in-out infinite;
13455
+ .tour-bar__progress {
13456
+ flex: 1;
13457
+ text-align: center;
13458
+ font-variant-numeric: tabular-nums;
13459
+ font-weight: 500;
13460
+ color: #6b4500;
14651
13461
  }
14652
13462
 
14653
- .status-pending .stack-progress-status-icon {
14654
- color: var(--color-text-muted, #d1d9e0);
13463
+ [data-theme="dark"] .tour-bar__progress {
13464
+ color: #e3b341;
14655
13465
  }
14656
13466
 
14657
- .status-failed .stack-progress-status-icon {
14658
- color: var(--color-danger, #cf222e);
13467
+ .tour-bar__nav {
13468
+ display: inline-flex;
13469
+ align-items: center;
13470
+ gap: 6px;
14659
13471
  }
14660
13472
 
14661
- [data-theme="dark"] .stack-progress-modal {
14662
- background: var(--color-bg-elevated, #1e2329);
14663
- border-color: var(--color-border-primary, #30363d);
14664
- box-shadow: 0 8px 32px var(--color-shadow-large, rgba(0, 0, 0, 0.5));
13473
+ .tour-bar__nav button {
13474
+ display: inline-flex;
13475
+ align-items: center;
13476
+ gap: 4px;
13477
+ padding: 4px 10px;
13478
+ font-size: 12px;
13479
+ font-weight: 500;
13480
+ color: #7d5700;
13481
+ background: rgba(255, 255, 255, 0.65);
13482
+ border: 1px solid rgba(212, 167, 44, 0.55);
13483
+ border-radius: var(--radius-sm, 4px);
13484
+ cursor: pointer;
13485
+ transition: background-color var(--transition-fast, 0.1s ease),
13486
+ border-color var(--transition-fast, 0.1s ease);
14665
13487
  }
14666
13488
 
14667
- [data-theme="dark"] .stack-progress-header {
14668
- border-color: var(--color-border-primary, #30363d);
14669
- color: var(--color-text-primary, #c9d1d9);
13489
+ .tour-bar__nav button:hover:not(:disabled) {
13490
+ background: rgba(255, 255, 255, 0.95);
13491
+ border-color: #d4a72c;
14670
13492
  }
14671
13493
 
14672
- [data-theme="dark"] .stack-progress-header button:hover {
14673
- color: var(--color-text-primary, #c9d1d9);
13494
+ .tour-bar__nav button:disabled {
13495
+ opacity: 0.45;
13496
+ cursor: not-allowed;
14674
13497
  }
14675
13498
 
14676
- [data-theme="dark"] .stack-progress-body {
14677
- color: var(--color-text-primary, #c9d1d9);
13499
+ .tour-bar__nav button svg {
13500
+ width: 12px;
13501
+ height: 12px;
14678
13502
  }
14679
13503
 
14680
- [data-theme="dark"] .stack-progress-footer {
14681
- border-color: var(--color-border-primary, #30363d);
13504
+ [data-theme="dark"] .tour-bar__nav button {
13505
+ color: #e3b341;
13506
+ background: rgba(13, 17, 23, 0.55);
13507
+ border-color: rgba(187, 128, 9, 0.55);
14682
13508
  }
14683
13509
 
14684
- [data-theme="dark"] .stack-progress-pr-row {
14685
- border-color: var(--color-border-subtle, rgba(255, 255, 255, 0.06));
13510
+ [data-theme="dark"] .tour-bar__nav button:hover:not(:disabled) {
13511
+ background: rgba(13, 17, 23, 0.85);
13512
+ border-color: #e3b341;
14686
13513
  }
14687
13514
 
14688
- [data-theme="dark"] .stack-progress-pr-label {
14689
- color: var(--color-text-primary, #c9d1d9);
13515
+ /* ---------- Toolbar tour-toggle button states ---------- */
13516
+ .btn-tour-toggle {
13517
+ position: relative;
13518
+ border: 1px solid var(--color-border-primary, #d1d9e0);
13519
+ color: var(--color-text-secondary, #57606a);
13520
+ transition: color var(--transition-fast, 0.1s ease),
13521
+ border-color var(--transition-fast, 0.1s ease),
13522
+ background-color var(--transition-fast, 0.1s ease);
14690
13523
  }
14691
13524
 
14692
- [data-theme="dark"] .stack-progress-pr-link {
14693
- color: var(--color-accent-primary, #58a6ff);
13525
+ /* Tour active — pale-yellow highlight. */
13526
+ .btn-tour-toggle.active {
13527
+ color: #7d5700;
13528
+ border-color: #d4a72c;
13529
+ background-color: rgba(212, 167, 44, 0.12);
14694
13530
  }
14695
13531
 
14696
- [data-theme="dark"] .stack-progress-pr-detail {
14697
- color: var(--color-text-secondary, #8b949e);
13532
+ [data-theme="dark"] .btn-tour-toggle.active {
13533
+ color: #e3b341;
13534
+ border-color: #bb8009;
13535
+ background-color: rgba(187, 128, 9, 0.20);
14698
13536
  }
14699
13537
 
14700
- [data-theme="dark"] .stack-progress-pr-detail a {
14701
- color: var(--color-accent-primary, #58a6ff);
13538
+ /* Generating pulse while the background tour job is running. */
13539
+ .btn-tour-toggle.generating {
13540
+ animation: tourPulse 1.6s ease-in-out infinite;
14702
13541
  }
14703
13542
 
14704
- [data-theme="dark"] .status-completed .stack-progress-status-icon {
14705
- color: var(--color-accent-emphasis-hover, #2ea043);
13543
+ /* Subtle indicator that a newer tour is stashed and waiting for restart.
13544
+ Renders as a small dot in the corner of the toolbar button. */
13545
+ .btn-tour-toggle.tour-updated-pending::after {
13546
+ content: '';
13547
+ position: absolute;
13548
+ top: 4px;
13549
+ right: 4px;
13550
+ width: 6px;
13551
+ height: 6px;
13552
+ border-radius: 50%;
13553
+ background: #d4a72c;
13554
+ box-shadow: 0 0 0 2px var(--color-bg-primary, #ffffff);
14706
13555
  }
14707
13556
 
14708
- [data-theme="dark"] .status-running .stack-progress-status-icon {
14709
- color: var(--color-accent-ai-dark, #f59e0b);
13557
+ [data-theme="dark"] .btn-tour-toggle.tour-updated-pending::after {
13558
+ background: #e3b341;
13559
+ box-shadow: 0 0 0 2px var(--color-bg-primary, #0d1117);
14710
13560
  }
14711
13561
 
14712
- [data-theme="dark"] .status-setting_up .stack-progress-status-icon {
14713
- color: var(--color-text-secondary, #8b949e);
13562
+ @keyframes tourPulse {
13563
+ 0%, 100% {
13564
+ box-shadow: 0 0 0 0 rgba(212, 167, 44, 0);
13565
+ }
13566
+ 50% {
13567
+ box-shadow: 0 0 0 4px rgba(212, 167, 44, 0.28);
13568
+ }
14714
13569
  }
14715
13570
 
14716
- [data-theme="dark"] .status-pending .stack-progress-status-icon {
14717
- color: var(--color-text-muted, #484f58);
13571
+ [data-theme="dark"] .btn-tour-toggle.generating {
13572
+ animation-name: tourPulseDark;
14718
13573
  }
14719
13574
 
14720
- [data-theme="dark"] .status-failed .stack-progress-status-icon {
14721
- color: var(--color-danger, #f85149);
13575
+ @keyframes tourPulseDark {
13576
+ 0%, 100% {
13577
+ box-shadow: 0 0 0 0 rgba(187, 128, 9, 0);
13578
+ }
13579
+ 50% {
13580
+ box-shadow: 0 0 0 4px rgba(187, 128, 9, 0.40);
13581
+ }
14722
13582
  }