@carboncode/cli 0.1.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 (159) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES/DeepSeek-Reasonix-MIT.txt +21 -0
  3. package/README.md +109 -0
  4. package/README.zh-CN.md +91 -0
  5. package/THIRD_PARTY_NOTICES.md +14 -0
  6. package/dashboard/app.css +3233 -0
  7. package/dashboard/dist/app.js +30444 -0
  8. package/dashboard/dist/app.js.map +1 -0
  9. package/dashboard/dist/vendor-hljs.css +10 -0
  10. package/dashboard/dist/vendor-uplot.css +1 -0
  11. package/dashboard/index.html +19 -0
  12. package/data/deepseek-tokenizer.json.gz +0 -0
  13. package/dist/cli/acp-35C4ME6Y.js +711 -0
  14. package/dist/cli/acp-35C4ME6Y.js.map +1 -0
  15. package/dist/cli/chat-A6UJDPGV.js +51 -0
  16. package/dist/cli/chat-A6UJDPGV.js.map +1 -0
  17. package/dist/cli/chunk-2425HK6U.js +54 -0
  18. package/dist/cli/chunk-2425HK6U.js.map +1 -0
  19. package/dist/cli/chunk-25T6CVUP.js +172 -0
  20. package/dist/cli/chunk-25T6CVUP.js.map +1 -0
  21. package/dist/cli/chunk-2UQP6H6T.js +31 -0
  22. package/dist/cli/chunk-2UQP6H6T.js.map +1 -0
  23. package/dist/cli/chunk-3OAR6NVL.js +96 -0
  24. package/dist/cli/chunk-3OAR6NVL.js.map +1 -0
  25. package/dist/cli/chunk-3T6VBZCL.js +54 -0
  26. package/dist/cli/chunk-3T6VBZCL.js.map +1 -0
  27. package/dist/cli/chunk-4IBIPQVB.js +153 -0
  28. package/dist/cli/chunk-4IBIPQVB.js.map +1 -0
  29. package/dist/cli/chunk-4MQ3VURH.js +3106 -0
  30. package/dist/cli/chunk-4MQ3VURH.js.map +1 -0
  31. package/dist/cli/chunk-4TVNJWMA.js +11619 -0
  32. package/dist/cli/chunk-4TVNJWMA.js.map +1 -0
  33. package/dist/cli/chunk-4VR6XF4P.js +341 -0
  34. package/dist/cli/chunk-4VR6XF4P.js.map +1 -0
  35. package/dist/cli/chunk-5QCB62C4.js +25319 -0
  36. package/dist/cli/chunk-5QCB62C4.js.map +1 -0
  37. package/dist/cli/chunk-6OWJV3YW.js +390 -0
  38. package/dist/cli/chunk-6OWJV3YW.js.map +1 -0
  39. package/dist/cli/chunk-7EO27TB3.js +130 -0
  40. package/dist/cli/chunk-7EO27TB3.js.map +1 -0
  41. package/dist/cli/chunk-7L2WTRNU.js +308 -0
  42. package/dist/cli/chunk-7L2WTRNU.js.map +1 -0
  43. package/dist/cli/chunk-BHTZFEYE.js +47 -0
  44. package/dist/cli/chunk-BHTZFEYE.js.map +1 -0
  45. package/dist/cli/chunk-BSGCXZQN.js +343 -0
  46. package/dist/cli/chunk-BSGCXZQN.js.map +1 -0
  47. package/dist/cli/chunk-BSINVTTL.js +464 -0
  48. package/dist/cli/chunk-BSINVTTL.js.map +1 -0
  49. package/dist/cli/chunk-CPKCNHRR.js +323 -0
  50. package/dist/cli/chunk-CPKCNHRR.js.map +1 -0
  51. package/dist/cli/chunk-CXVWUPA3.js +96 -0
  52. package/dist/cli/chunk-CXVWUPA3.js.map +1 -0
  53. package/dist/cli/chunk-D5NFKRGO.js +160 -0
  54. package/dist/cli/chunk-D5NFKRGO.js.map +1 -0
  55. package/dist/cli/chunk-ECHSFYOY.js +109 -0
  56. package/dist/cli/chunk-ECHSFYOY.js.map +1 -0
  57. package/dist/cli/chunk-FEZK652I.js +3644 -0
  58. package/dist/cli/chunk-FEZK652I.js.map +1 -0
  59. package/dist/cli/chunk-GALC45Q2.js +696 -0
  60. package/dist/cli/chunk-GALC45Q2.js.map +1 -0
  61. package/dist/cli/chunk-IAUOP25G.js +2984 -0
  62. package/dist/cli/chunk-IAUOP25G.js.map +1 -0
  63. package/dist/cli/chunk-ILJOIQ5W.js +163 -0
  64. package/dist/cli/chunk-ILJOIQ5W.js.map +1 -0
  65. package/dist/cli/chunk-IX6XI2RG.js +225 -0
  66. package/dist/cli/chunk-IX6XI2RG.js.map +1 -0
  67. package/dist/cli/chunk-J5BYPUB5.js +62795 -0
  68. package/dist/cli/chunk-J5BYPUB5.js.map +1 -0
  69. package/dist/cli/chunk-J5XJHLWM.js +55 -0
  70. package/dist/cli/chunk-J5XJHLWM.js.map +1 -0
  71. package/dist/cli/chunk-JKGYMRX5.js +101 -0
  72. package/dist/cli/chunk-JKGYMRX5.js.map +1 -0
  73. package/dist/cli/chunk-JMBMLOBP.js +26 -0
  74. package/dist/cli/chunk-JMBMLOBP.js.map +1 -0
  75. package/dist/cli/chunk-LN3B5PMX.js +128 -0
  76. package/dist/cli/chunk-LN3B5PMX.js.map +1 -0
  77. package/dist/cli/chunk-M2UFZUX3.js +635 -0
  78. package/dist/cli/chunk-M2UFZUX3.js.map +1 -0
  79. package/dist/cli/chunk-PJS34556.js +809 -0
  80. package/dist/cli/chunk-PJS34556.js.map +1 -0
  81. package/dist/cli/chunk-QJG7OF27.js +655 -0
  82. package/dist/cli/chunk-QJG7OF27.js.map +1 -0
  83. package/dist/cli/chunk-QVC75MR3.js +232 -0
  84. package/dist/cli/chunk-QVC75MR3.js.map +1 -0
  85. package/dist/cli/chunk-S2KIUQKQ.js +378 -0
  86. package/dist/cli/chunk-S2KIUQKQ.js.map +1 -0
  87. package/dist/cli/chunk-S4XVGLRW.js +499 -0
  88. package/dist/cli/chunk-S4XVGLRW.js.map +1 -0
  89. package/dist/cli/chunk-T5TQ4NDT.js +190 -0
  90. package/dist/cli/chunk-T5TQ4NDT.js.map +1 -0
  91. package/dist/cli/chunk-TH756VLN.js +1924 -0
  92. package/dist/cli/chunk-TH756VLN.js.map +1 -0
  93. package/dist/cli/chunk-TUK7OWJA.js +51 -0
  94. package/dist/cli/chunk-TUK7OWJA.js.map +1 -0
  95. package/dist/cli/chunk-U4IJVG32.js +363 -0
  96. package/dist/cli/chunk-U4IJVG32.js.map +1 -0
  97. package/dist/cli/chunk-UI66BH6D.js +624 -0
  98. package/dist/cli/chunk-UI66BH6D.js.map +1 -0
  99. package/dist/cli/chunk-VPMBGAND.js +53 -0
  100. package/dist/cli/chunk-VPMBGAND.js.map +1 -0
  101. package/dist/cli/chunk-WLHH3OSR.js +522 -0
  102. package/dist/cli/chunk-WLHH3OSR.js.map +1 -0
  103. package/dist/cli/chunk-WRN65TRD.js +908 -0
  104. package/dist/cli/chunk-WRN65TRD.js.map +1 -0
  105. package/dist/cli/chunk-X53B3JIX.js +34320 -0
  106. package/dist/cli/chunk-X53B3JIX.js.map +1 -0
  107. package/dist/cli/chunk-XJ5SRLKK.js +50 -0
  108. package/dist/cli/chunk-XJ5SRLKK.js.map +1 -0
  109. package/dist/cli/chunk-YZSXRGFH.js +54 -0
  110. package/dist/cli/chunk-YZSXRGFH.js.map +1 -0
  111. package/dist/cli/code-4TUTAGO5.js +163 -0
  112. package/dist/cli/code-4TUTAGO5.js.map +1 -0
  113. package/dist/cli/commands-KMOZEYCF.js +356 -0
  114. package/dist/cli/commands-KMOZEYCF.js.map +1 -0
  115. package/dist/cli/commit-DTFA56VQ.js +292 -0
  116. package/dist/cli/commit-DTFA56VQ.js.map +1 -0
  117. package/dist/cli/desktop-7N3MHNBD.js +1274 -0
  118. package/dist/cli/desktop-7N3MHNBD.js.map +1 -0
  119. package/dist/cli/devtools-HW3WDT3Q.js +91 -0
  120. package/dist/cli/devtools-HW3WDT3Q.js.map +1 -0
  121. package/dist/cli/diff-E5OWTF4C.js +165 -0
  122. package/dist/cli/diff-E5OWTF4C.js.map +1 -0
  123. package/dist/cli/doctor-IEJQRJMN.js +27 -0
  124. package/dist/cli/doctor-IEJQRJMN.js.map +1 -0
  125. package/dist/cli/events-4625EGXI.js +340 -0
  126. package/dist/cli/events-4625EGXI.js.map +1 -0
  127. package/dist/cli/index.js +3536 -0
  128. package/dist/cli/index.js.map +1 -0
  129. package/dist/cli/mcp-PDI2PDLG.js +277 -0
  130. package/dist/cli/mcp-PDI2PDLG.js.map +1 -0
  131. package/dist/cli/mcp-browse-OSPXOFPZ.js +178 -0
  132. package/dist/cli/mcp-browse-OSPXOFPZ.js.map +1 -0
  133. package/dist/cli/mcp-inspect-QRFVTHMF.js +148 -0
  134. package/dist/cli/mcp-inspect-QRFVTHMF.js.map +1 -0
  135. package/dist/cli/package.json +3 -0
  136. package/dist/cli/prompt-3CDII3UO.js +16 -0
  137. package/dist/cli/prompt-3CDII3UO.js.map +1 -0
  138. package/dist/cli/prune-sessions-KZX4SXKW.js +44 -0
  139. package/dist/cli/prune-sessions-KZX4SXKW.js.map +1 -0
  140. package/dist/cli/replay-HYOSRQIV.js +291 -0
  141. package/dist/cli/replay-HYOSRQIV.js.map +1 -0
  142. package/dist/cli/run-2ZHADOUP.js +220 -0
  143. package/dist/cli/run-2ZHADOUP.js.map +1 -0
  144. package/dist/cli/server-X75PAZG5.js +3572 -0
  145. package/dist/cli/server-X75PAZG5.js.map +1 -0
  146. package/dist/cli/sessions-POOZA5CQ.js +120 -0
  147. package/dist/cli/sessions-POOZA5CQ.js.map +1 -0
  148. package/dist/cli/setup-YLPFI3OH.js +618 -0
  149. package/dist/cli/setup-YLPFI3OH.js.map +1 -0
  150. package/dist/cli/stats-NXJ3TO2D.js +16 -0
  151. package/dist/cli/stats-NXJ3TO2D.js.map +1 -0
  152. package/dist/cli/update-ZUO5MKQ6.js +15 -0
  153. package/dist/cli/update-ZUO5MKQ6.js.map +1 -0
  154. package/dist/cli/version-NXXWE3WN.js +33 -0
  155. package/dist/cli/version-NXXWE3WN.js.map +1 -0
  156. package/dist/index.d.ts +2523 -0
  157. package/dist/index.js +15408 -0
  158. package/dist/index.js.map +1 -0
  159. package/package.json +112 -0
@@ -0,0 +1,3233 @@
1
+ /* Carbon Code dashboard styles — anchored to docs/design/agent-dashboard.html.
2
+ * Re-import: extract the <style> block from the design mockup verbatim.
3
+ * Doc-chrome selectors (.page / .toc / .section / .subsec / .mock) are
4
+ * unused in the live dashboard but kept so the CSS stays in lockstep
5
+ * with the mockup; they cost nothing at runtime.
6
+ */
7
+ /* ============================================================================
8
+ Carbon Code Dashboard — design anchor for the web companion to the TUI.
9
+
10
+ Positioning: NOT a TUI mirror. Does what the TUI cannot:
11
+ - long-form session reading
12
+ - real charts (usage / cost / latency)
13
+ - multi-file editing
14
+ - browsing inventories (tools, MCP servers, skills, memory)
15
+
16
+ Aesthetic: TUI heritage (palette, glyph icons, sharp edges) + web fluency
17
+ (sans-serif body, real form controls, hover states, modal dialogs).
18
+ NOT slavish terminal mimicry — that's a portfolio gimmick, not a tool.
19
+ ============================================================================ */
20
+ :root {
21
+ /* Surfaces — same family as TUI, slightly lifted for screen comfort */
22
+ --bg: #0a0c10;
23
+ --bg-elev: #11141a;
24
+ --bg-elev-2: #161a22;
25
+ --bg-input: #0d1015;
26
+ --bg-code: #06080c;
27
+ --bg-hover: #1a1f29;
28
+
29
+ /* Text */
30
+ --fg-0: #e6edf3; /* primary */
31
+ --fg-1: #c9d1d9; /* body */
32
+ --fg-2: #8b949e; /* secondary */
33
+ --fg-3: #6e7681; /* dim */
34
+ --fg-4: #484f58; /* very dim, separators in text */
35
+
36
+ /* Accents — TUI lineage, unchanged */
37
+ --c-brand: #79c0ff; /* sky — in-progress, links */
38
+ --c-accent: #d2a8ff; /* purple — reasoning, plan */
39
+ --c-violet: #b395f5; /* violet — sub-agent */
40
+ --c-ok: #7ee787; /* green — success */
41
+ --c-warn: #f0b07d; /* amber — warning, approval */
42
+ --c-err: #ff8b81; /* coral — error */
43
+ --c-info: #79c0ff;
44
+
45
+ /* Chart spectrum — for series; 6-stop gradient that reads in dark mode */
46
+ --s1: #79c0ff; /* sky */
47
+ --s2: #56d4dd; /* teal */
48
+ --s3: #7ee787; /* mint */
49
+ --s4: #f0b07d; /* amber */
50
+ --s5: #ff8b81; /* coral */
51
+ --s6: #d2a8ff; /* purple */
52
+
53
+ /* Borders */
54
+ --bd: #1a1d24;
55
+ --bd-strong: #232831;
56
+
57
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
58
+ --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', 'Cascadia Code', Menlo, Consolas, monospace;
59
+
60
+ /* Spacing / radius — tiny radius (2px) keeps web feel without going SaaS */
61
+ --r: 2px;
62
+ --r-sm: 4px;
63
+ --r-md: 4px;
64
+
65
+ /* Inline elevation step above --bg-elev-2 for nested cards/dropdowns. */
66
+ --bg-elev-3: #1d2230;
67
+
68
+ /* Brand sweep — used by .md hr and the mini status bar fill. */
69
+ --gradient-rule: linear-gradient(90deg, var(--c-brand), var(--c-accent));
70
+ }
71
+
72
+ * { box-sizing: border-box; }
73
+ html, body { background: var(--bg); color: var(--fg-1); margin: 0; padding: 0; }
74
+
75
+ * { scrollbar-width: thin; scrollbar-color: var(--bd-strong) transparent; }
76
+ *::-webkit-scrollbar { width: 10px; height: 10px; }
77
+ *::-webkit-scrollbar-track { background: transparent; }
78
+ *::-webkit-scrollbar-thumb { background: var(--bd); border: 2px solid var(--bg); border-radius: 6px; }
79
+ *::-webkit-scrollbar-thumb:hover { background: var(--fg-4); }
80
+ *::-webkit-scrollbar-corner { background: transparent; }
81
+ body {
82
+ font-family: var(--font-sans);
83
+ font-size: 14px;
84
+ line-height: 1.55;
85
+ -webkit-font-smoothing: antialiased;
86
+ }
87
+ code, .mono { font-family: var(--font-mono); }
88
+
89
+ a { color: var(--c-brand); text-decoration: none; }
90
+ a:hover { text-decoration: underline; }
91
+
92
+ /* ── Doc chrome ─────────────────────────────────────────────────────────── */
93
+ .page {
94
+ display: grid;
95
+ grid-template-columns: 260px minmax(0, 1fr);
96
+ max-width: 1320px;
97
+ margin: 0 auto;
98
+ min-height: 100vh;
99
+ }
100
+ .toc {
101
+ position: sticky; top: 0; align-self: start;
102
+ height: 100vh; overflow-y: auto;
103
+ border-right: 1px solid var(--bd);
104
+ padding: 28px 16px;
105
+ background: var(--bg);
106
+ }
107
+ .toc h1 { font-size: 15px; font-weight: 700; margin: 0 0 4px; color: var(--fg-0); letter-spacing: .03em; font-family: var(--font-mono); }
108
+ .toc h1 .dot { color: var(--c-brand); margin-right: 8px; }
109
+ .toc .sub { font-size: 12px; color: var(--fg-3); margin: 0 0 18px; letter-spacing: .04em; }
110
+ .toc-section { font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--fg-4); margin: 22px 0 6px; font-weight: 700; }
111
+ .toc-section:first-of-type { margin-top: 0; }
112
+ .toc ul { list-style: none; padding: 0; margin: 0; }
113
+ .toc li a {
114
+ display: block; padding: 4px 10px; margin: 1px 0;
115
+ color: var(--fg-2); font-size: 14px; line-height: 1.4;
116
+ border-radius: var(--r); overflow-wrap: anywhere;
117
+ }
118
+ .toc li a:hover { color: var(--fg-0); background: var(--bg-elev); text-decoration: none; }
119
+
120
+ main { padding: 32px 40px 60px 32px; min-width: 0; }
121
+ .section { padding: 28px 0 36px; border-bottom: 1px solid #14171e; }
122
+ .section:last-child { border-bottom: none; }
123
+ .section > h2 {
124
+ font-size: 22px; font-weight: 700; color: var(--fg-0);
125
+ margin: 0 0 4px; letter-spacing: -.005em; font-family: var(--font-mono);
126
+ }
127
+ .section > h2 .num { color: var(--fg-4); margin-right: 10px; font-weight: 500; }
128
+ .section > .lede {
129
+ color: var(--fg-2); margin: 0 0 22px; font-size: 15px; max-width: 720px; line-height: 1.6;
130
+ }
131
+ .subsec { margin-bottom: 22px; }
132
+ .subsec > h3 {
133
+ font-size: 13px; font-weight: 700; color: var(--fg-1);
134
+ margin: 24px 0 4px; letter-spacing: .04em; text-transform: uppercase;
135
+ font-family: var(--font-mono);
136
+ }
137
+ .subsec > h3 .desc { color: var(--fg-3); font-weight: 400; margin-left: 10px; font-size: 13px; text-transform: none; letter-spacing: 0; }
138
+ .subsec > p { color: var(--fg-3); font-size: 15px; margin: 0 0 12px; max-width: 720px; line-height: 1.6; }
139
+
140
+ /* "Mock" — a faux-window frame to display dashboard pieces inside the design doc */
141
+ .mock {
142
+ background: var(--bg-elev);
143
+ border: 1px solid var(--bd);
144
+ border-radius: var(--r);
145
+ margin: 14px 0;
146
+ overflow: hidden;
147
+ }
148
+ .mock-cap {
149
+ font-family: var(--font-mono);
150
+ font-size: 11px;
151
+ color: var(--fg-3);
152
+ margin: 18px 0 6px;
153
+ letter-spacing: .06em;
154
+ }
155
+
156
+ /* ── §1 Tokens display ─────────────────────────────────────────────────── */
157
+ .swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 8px; margin: 8px 0 14px; }
158
+ .swatch {
159
+ background: var(--bg-elev); border: 1px solid var(--bd); padding: 10px 12px; border-radius: var(--r);
160
+ display: flex; align-items: center; gap: 10px;
161
+ font-family: var(--font-mono); font-size: 11.5px;
162
+ }
163
+ .swatch .chip { width: 22px; height: 22px; border-radius: var(--r); flex-shrink: 0; border: 1px solid rgba(255,255,255,.04); }
164
+ .swatch .meta { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
165
+ .swatch .name { color: var(--fg-1); font-size: 11.5px; }
166
+ .swatch .hex { color: var(--fg-3); font-size: 11.5px; }
167
+
168
+ .scale-row { display: flex; align-items: baseline; gap: 16px; padding: 6px 0; border-bottom: 1px dashed #181b22; }
169
+ .scale-row:last-child { border-bottom: none; }
170
+ .scale-row .lbl { font-family: var(--font-mono); font-size: 11.5px; color: var(--fg-3); width: 76px; flex-shrink: 0; }
171
+ .scale-row .ex { color: var(--fg-1); }
172
+
173
+ .glyph-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 6px; }
174
+ .glyph-cell {
175
+ background: var(--bg-elev); border: 1px solid var(--bd); padding: 8px 10px; border-radius: var(--r);
176
+ display: flex; align-items: center; gap: 10px; font-family: var(--font-mono); font-size: 12px;
177
+ }
178
+ .glyph-cell .g { color: var(--c-brand); font-size: 16px; width: 18px; text-align: center; }
179
+ .glyph-cell .n { color: var(--fg-2); font-size: 11px; }
180
+
181
+ /* ── App shell — sidebar / topbar / statusrow ──────────────────────────── */
182
+ .app {
183
+ display: grid;
184
+ grid-template-columns: 220px minmax(0, 1fr);
185
+ grid-template-rows: 44px 1fr 26px;
186
+ grid-template-areas:
187
+ "side top"
188
+ "side body"
189
+ "side status";
190
+ height: 100vh;
191
+ background: var(--bg);
192
+ font-size: 13px;
193
+ }
194
+ .app.collapsed { grid-template-columns: 56px minmax(0, 1fr); }
195
+
196
+ /* Sidebar */
197
+ .app-side {
198
+ grid-area: side;
199
+ background: var(--bg-elev);
200
+ border-right: 1px solid var(--bd);
201
+ display: flex; flex-direction: column;
202
+ }
203
+ .app-side .brand {
204
+ padding: 14px 16px 12px; display: flex; align-items: center; gap: 8px;
205
+ font-family: var(--font-mono); font-size: 13px; font-weight: 700; color: var(--fg-0);
206
+ letter-spacing: .08em;
207
+ }
208
+ .app-side .brand .glyph { color: var(--c-brand); font-size: 16px; }
209
+ .app-side .brand .ver { color: var(--fg-4); font-size: 10.5px; margin-left: auto; font-weight: 400; letter-spacing: .04em; }
210
+ .app.collapsed .app-side .brand .label,
211
+ .app.collapsed .app-side .brand .ver { display: none; }
212
+
213
+ .side-tabs { padding: 6px 8px; flex: 1; overflow-y: auto; }
214
+ .side-tab {
215
+ display: flex; align-items: center; gap: 10px;
216
+ padding: 6px 10px; margin: 1px 0;
217
+ color: var(--fg-2); font-family: var(--font-mono); font-size: 12px;
218
+ border-radius: var(--r); cursor: pointer;
219
+ border-left: 2px solid transparent;
220
+ letter-spacing: .02em;
221
+ }
222
+ .side-tab .g { font-family: var(--font-mono); font-size: 13px; width: 16px; text-align: center; color: var(--fg-3); flex-shrink: 0; }
223
+ .side-tab:hover { background: var(--bg-hover); color: var(--fg-0); }
224
+ .side-tab:hover .g { color: var(--fg-1); }
225
+ .side-tab.active { background: var(--bg-hover); color: var(--fg-0); border-left-color: var(--c-brand); }
226
+ .side-tab.active .g { color: var(--c-brand); }
227
+ .side-tab .badge { margin-left: auto; font-family: var(--font-mono); font-size: 10px; color: var(--fg-3); background: var(--bg-elev-2); padding: 1px 5px; border-radius: 8px; }
228
+ .app.collapsed .side-tab .label,
229
+ .app.collapsed .side-tab .badge { display: none; }
230
+ .app.collapsed .side-tab { justify-content: center; padding: 8px; }
231
+
232
+ .side-section { font-family: var(--font-mono); font-size: 10px; color: var(--fg-4); padding: 14px 14px 4px; letter-spacing: .12em; text-transform: uppercase; font-weight: 600; }
233
+ .app.collapsed .side-section { display: none; }
234
+
235
+ .side-foot {
236
+ padding: 8px; border-top: 1px solid var(--bd); display: flex; align-items: center; gap: 8px;
237
+ font-family: var(--font-mono); font-size: 11px; color: var(--fg-3);
238
+ }
239
+ .side-foot .toggle { margin-left: auto; cursor: pointer; color: var(--fg-3); padding: 2px 6px; border-radius: var(--r); }
240
+ .side-foot .toggle:hover { color: var(--fg-1); background: var(--bg-hover); }
241
+ .app.collapsed .side-foot .label { display: none; }
242
+
243
+ /* Top bar */
244
+ .app-top {
245
+ grid-area: top;
246
+ display: flex; align-items: center; gap: 12px;
247
+ padding: 0 16px;
248
+ background: var(--bg-elev);
249
+ border-bottom: 1px solid var(--bd);
250
+ font-family: var(--font-mono); font-size: 12px;
251
+ }
252
+ .app-top .ws { color: var(--fg-1); display: flex; align-items: center; gap: 6px; }
253
+ .app-top .ws .path { color: var(--fg-2); }
254
+ .app-top .ws .branch { color: var(--c-ok); padding: 1px 5px; background: rgba(126,231,135,.08); border-radius: var(--r); font-size: 10.5px; }
255
+ .app-top .sep { color: var(--fg-4); margin: 0 4px; }
256
+ .app-top .session { color: var(--c-accent); }
257
+ .app-top .grow { flex: 1; }
258
+ .app-top .meter { display: flex; align-items: center; gap: 6px; color: var(--fg-2); }
259
+ .app-top .meter .v { color: var(--fg-0); font-weight: 600; }
260
+ .app-top .meter .lbl { color: var(--fg-4); font-size: 10.5px; }
261
+
262
+ /* Body / panel content slot */
263
+ .app-body {
264
+ grid-area: body;
265
+ overflow-y: auto;
266
+ padding: 24px 28px;
267
+ }
268
+
269
+ /* Status row */
270
+ .app-status {
271
+ grid-area: status;
272
+ display: flex; align-items: center; gap: 14px;
273
+ padding: 0 14px;
274
+ background: var(--bg-elev);
275
+ border-top: 1px solid var(--bd);
276
+ font-family: var(--font-mono); font-size: 11px; color: var(--fg-3);
277
+ }
278
+ .app-status .item { display: flex; align-items: center; gap: 4px; }
279
+ .app-status .item .v { color: var(--fg-1); }
280
+ .app-status .item .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--c-ok); }
281
+ .app-status .item .dot.warn { background: var(--c-warn); }
282
+ .app-status .item .dot.err { background: var(--c-err); }
283
+ .app-status .grow { flex: 1; }
284
+
285
+ /* ── §3 Components ─────────────────────────────────────────────────────── */
286
+
287
+ /* Card */
288
+ .card {
289
+ background: var(--bg-elev);
290
+ border: 1px solid var(--bd);
291
+ border-radius: var(--r);
292
+ padding: 14px 16px;
293
+ }
294
+ .card.accent-brand { border-left: 2px solid var(--c-brand); }
295
+ .card.accent-accent { border-left: 2px solid var(--c-accent); }
296
+ .card.accent-warn { border-left: 2px solid var(--c-warn); }
297
+ .card.accent-err { border-left: 2px solid var(--c-err); }
298
+ .card-h { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
299
+ .card-h .glyph { font-family: var(--font-mono); color: var(--c-brand); font-size: 14px; }
300
+ .card-h .title { color: var(--fg-0); font-weight: 600; font-size: 13px; }
301
+ .card-h .meta { margin-left: auto; color: var(--fg-3); font-family: var(--font-mono); font-size: 11px; }
302
+ .card-b { color: var(--fg-1); font-size: 13px; line-height: 1.55; }
303
+
304
+ /* Pill */
305
+ .pill {
306
+ display: inline-flex; align-items: center; gap: 4px;
307
+ font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
308
+ padding: 1px 7px;
309
+ border-radius: 9px;
310
+ background: var(--bg-elev-2);
311
+ color: var(--fg-2);
312
+ letter-spacing: .04em;
313
+ }
314
+ .pill .g { font-size: 9px; }
315
+ .pill.ok { color: var(--c-ok); background: rgba(126,231,135,.08); }
316
+ .pill.warn { color: var(--c-warn); background: rgba(240,176,125,.10); }
317
+ .pill.err { color: var(--c-err); background: rgba(255,139,129,.10); }
318
+ .pill.info { color: var(--c-brand); background: rgba(121,192,255,.10); }
319
+ .pill.acc { color: var(--c-accent); background: rgba(210,168,255,.10); }
320
+
321
+ /* Table */
322
+ .tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; table-layout: auto; }
323
+ .tbl th, .tbl td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--bd); }
324
+ .tbl th { font-family: var(--font-mono); font-size: 10.5px; font-weight: 600; color: var(--fg-3); text-transform: uppercase; letter-spacing: .08em; background: var(--bg-elev); }
325
+ .tbl th.num, .tbl td.num { font-family: var(--font-mono); text-align: right; font-variant-numeric: tabular-nums; }
326
+ .tbl td { color: var(--fg-1); }
327
+ .tbl tbody tr:hover { background: var(--bg-hover); }
328
+ .tbl td.num { color: var(--fg-0); }
329
+ .tbl td.dim { color: var(--fg-3); }
330
+ .tbl td.path { font-family: var(--font-mono); font-size: 11.5px; color: var(--fg-2); }
331
+
332
+ /* Toast */
333
+ .toast-wrap { display: flex; flex-direction: column; gap: 8px; max-width: 360px; }
334
+ .toast {
335
+ background: var(--bg-elev-2); border: 1px solid var(--bd);
336
+ border-left: 2px solid var(--c-brand);
337
+ padding: 10px 12px; border-radius: var(--r);
338
+ display: flex; align-items: flex-start; gap: 8px;
339
+ font-size: 12.5px; color: var(--fg-1);
340
+ }
341
+ .toast .g { font-family: var(--font-mono); color: var(--c-brand); font-size: 13px; flex-shrink: 0; margin-top: 1px; }
342
+ .toast.ok { border-left-color: var(--c-ok); } .toast.ok .g { color: var(--c-ok); }
343
+ .toast.warn { border-left-color: var(--c-warn); } .toast.warn .g { color: var(--c-warn); }
344
+ .toast.err { border-left-color: var(--c-err); } .toast.err .g { color: var(--c-err); }
345
+ .toast .x { margin-left: auto; color: var(--fg-3); cursor: pointer; }
346
+ .toast .x:hover { color: var(--fg-0); }
347
+
348
+ /* Code block */
349
+ .code {
350
+ background: var(--bg-code);
351
+ border: 1px solid var(--bd);
352
+ border-radius: var(--r);
353
+ padding: 10px 14px;
354
+ font-family: var(--font-mono);
355
+ font-size: 12.5px;
356
+ color: var(--fg-1);
357
+ white-space: pre;
358
+ overflow-x: auto;
359
+ line-height: 1.6;
360
+ }
361
+ .code .ln { color: var(--fg-4); user-select: none; padding-right: 14px; }
362
+ .code .kw { color: var(--c-accent); }
363
+ .code .str { color: var(--c-ok); }
364
+ .code .com { color: var(--fg-3); font-style: italic; }
365
+ .code .num { color: var(--c-warn); }
366
+
367
+ /* Diff */
368
+ .diff {
369
+ background: var(--bg-code); border: 1px solid var(--bd); border-radius: var(--r);
370
+ font-family: var(--font-mono); font-size: 12px; line-height: 1.55;
371
+ overflow: hidden;
372
+ }
373
+ .diff-h { padding: 6px 12px; background: var(--bg-elev); color: var(--fg-2); font-size: 11px; border-bottom: 1px solid var(--bd); display: flex; gap: 12px; align-items: center; }
374
+ .diff-h .file { color: var(--fg-1); }
375
+ .diff-h .stat { margin-left: auto; }
376
+ .diff-h .stat .add { color: var(--c-ok); }
377
+ .diff-h .stat .rem { color: var(--c-err); }
378
+ .diff-row { display: grid; grid-template-columns: 32px 32px 1fr; }
379
+ .diff-row .gut { color: var(--fg-4); padding: 0 8px; text-align: right; user-select: none; }
380
+ .diff-row .txt { padding: 0 10px; white-space: pre; }
381
+ .diff-row.add { background: rgba(126,231,135,.06); }
382
+ .diff-row.add .gut { color: var(--c-ok); }
383
+ .diff-row.add .txt { color: var(--c-ok); }
384
+ .diff-row.rem { background: rgba(255,139,129,.05); }
385
+ .diff-row.rem .gut { color: var(--c-err); }
386
+ .diff-row.rem .txt { color: var(--c-err); }
387
+ .diff-row.ctx .txt { color: var(--fg-2); }
388
+ .diff-row.hunk { background: var(--bg-elev); color: var(--fg-3); }
389
+ .diff-row.hunk .txt, .diff-row.hunk .gut { color: var(--fg-3); }
390
+
391
+ /* Inline syntax tokens inherit color from .kw/.str/.com defined in .code; intra-line word diff. */
392
+ .diff-row .word-add { background: rgba(126,231,135,.22); color: var(--c-ok); border-radius: 2px; padding: 0 2px; }
393
+ .diff-row .word-rem { background: rgba(255,139,129,.20); color: var(--c-err); border-radius: 2px; padding: 0 2px; text-decoration: line-through; text-decoration-color: rgba(255,139,129,.55); }
394
+
395
+ /* Expand-context chevron row sits between hunks; clicking loads the gap. */
396
+ .diff-row.expand { grid-template-columns: 1fr; cursor: pointer; user-select: none; background: transparent; }
397
+ .diff-row.expand .txt { padding: 4px 12px; color: var(--fg-3); text-align: center; font-size: 11px; border-top: 1px dashed var(--bd); border-bottom: 1px dashed var(--bd); }
398
+ .diff-row.expand:hover .txt { color: var(--fg-1); border-color: var(--c-brand); }
399
+
400
+ /* Side-by-side variant — content split into two cells, no shared gutter strip. */
401
+ .diff.split .diff-row { grid-template-columns: 32px 1fr 32px 1fr; }
402
+ .diff.split .diff-row .pane { padding: 0 10px; white-space: pre; }
403
+ .diff.split .diff-row.add .pane.l, .diff.split .diff-row.rem .pane.r { background: var(--bg-elev); color: var(--fg-4); }
404
+
405
+ /* Edit-review panel — multi-file aggregator card list. */
406
+ .review-summary {
407
+ display: flex; align-items: center; gap: 14px; padding: 10px 14px;
408
+ background: var(--bg-elev); border: 1px solid var(--bd); border-radius: var(--r);
409
+ font-family: var(--font-mono); font-size: 12px; margin-bottom: 12px;
410
+ }
411
+ .review-summary .count { color: var(--fg-0); font-weight: 600; }
412
+ .review-summary .stat .add { color: var(--c-ok); }
413
+ .review-summary .stat .rem { color: var(--c-err); }
414
+ .review-summary .actions { margin-left: auto; display: flex; gap: 6px; }
415
+ .review-mode { display: inline-flex; gap: 0; border: 1px solid var(--bd); border-radius: var(--r); overflow: hidden; }
416
+ .review-mode button {
417
+ background: transparent; border: 0; color: var(--fg-3); padding: 4px 10px;
418
+ font-family: var(--font-mono); font-size: 11px; cursor: pointer;
419
+ }
420
+ .review-mode button.on { background: var(--bg-input); color: var(--fg-0); }
421
+
422
+ .review-file { border: 1px solid var(--bd); border-radius: var(--r); margin-bottom: 10px; overflow: hidden; }
423
+ .review-file-h {
424
+ display: flex; align-items: center; gap: 10px; padding: 8px 12px;
425
+ background: var(--bg-elev); cursor: pointer; user-select: none;
426
+ font-family: var(--font-mono); font-size: 12px;
427
+ }
428
+ .review-file-h .chev { color: var(--fg-3); width: 12px; }
429
+ .review-file-h .file { color: var(--fg-1); }
430
+ .review-file-h .stat { color: var(--fg-3); }
431
+ .review-file-h .stat .add { color: var(--c-ok); }
432
+ .review-file-h .stat .rem { color: var(--c-err); }
433
+ .review-file-h .acts { margin-left: auto; display: flex; gap: 6px; }
434
+ .review-file.collapsed .review-file-body { display: none; }
435
+ .review-file.collapsed .review-file-h .chev::before { content: "▸"; }
436
+ .review-file:not(.collapsed) .review-file-h .chev::before { content: "▾"; }
437
+
438
+ /* Chart frame */
439
+ .chart {
440
+ background: var(--bg-elev); border: 1px solid var(--bd); border-radius: var(--r); padding: 14px 16px;
441
+ }
442
+ .chart-h { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
443
+ .chart-h .title { color: var(--fg-3); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .08em; }
444
+ .chart-h .delta { margin-left: auto; font-family: var(--font-mono); font-size: 11px; }
445
+ .chart-h .delta.up { color: var(--c-ok); }
446
+ .chart-h .delta.down { color: var(--c-err); }
447
+ .chart-v { font-family: var(--font-mono); font-size: 22px; font-weight: 700; color: var(--fg-0); margin-bottom: 4px; letter-spacing: -.01em; }
448
+ .chart-v .unit { color: var(--fg-3); font-size: 13px; font-weight: 400; margin-left: 4px; }
449
+ .chart-spark svg { width: 100%; height: 38px; display: block; }
450
+
451
+ /* Form */
452
+ .form-row { display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px; }
453
+ .form-row .lbl { font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-3); text-transform: uppercase; letter-spacing: .08em; }
454
+ .form-row .help { color: var(--fg-3); font-size: 11.5px; margin-top: 2px; }
455
+ .input, .select, .textarea {
456
+ background: var(--bg-input); border: 1px solid var(--bd); border-radius: var(--r);
457
+ padding: 6px 10px; color: var(--fg-0); font-family: var(--font-mono); font-size: 12.5px;
458
+ outline: none; width: 100%;
459
+ }
460
+ .input:focus, .select:focus, .textarea:focus { border-color: var(--c-brand); }
461
+ .checkbox-row { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--fg-1); }
462
+ .checkbox-row .box { width: 13px; height: 13px; border: 1px solid var(--bd-strong); border-radius: var(--r); display: inline-flex; align-items: center; justify-content: center; background: var(--bg-input); }
463
+ .checkbox-row .box.on { background: var(--c-brand); border-color: var(--c-brand); color: var(--bg); font-family: var(--font-mono); font-size: 10px; font-weight: 700; }
464
+
465
+ .btn {
466
+ display: inline-flex; align-items: center; gap: 6px;
467
+ background: var(--bg-elev-2); border: 1px solid var(--bd-strong); color: var(--fg-1);
468
+ padding: 5px 12px; border-radius: var(--r);
469
+ font-family: var(--font-mono); font-size: 12px; font-weight: 600; cursor: pointer;
470
+ letter-spacing: .02em;
471
+ }
472
+ .btn:hover { background: var(--bg-hover); color: var(--fg-0); border-color: var(--fg-4); }
473
+ .btn.primary { background: var(--c-brand); color: var(--bg); border-color: var(--c-brand); }
474
+ .btn.primary:hover { background: #94cdff; border-color: #94cdff; color: var(--bg); }
475
+ .btn.ghost { background: transparent; }
476
+ .btn .g { font-size: 11px; }
477
+
478
+ /* ── Progress ─────────────────────────────────────────────────────────── */
479
+ /* Linear bar */
480
+ .progress {
481
+ width: 100%; height: 6px; background: var(--bg-input);
482
+ border-radius: 3px; overflow: hidden; position: relative;
483
+ }
484
+ .progress-fill {
485
+ height: 100%; background: var(--c-brand);
486
+ transition: width .3s ease; border-radius: 3px;
487
+ }
488
+ .progress.thin { height: 3px; }
489
+ .progress.thick { height: 10px; }
490
+ .progress.ok .progress-fill { background: var(--c-ok); }
491
+ .progress.warn .progress-fill { background: var(--c-warn); }
492
+ .progress.err .progress-fill { background: var(--c-err); }
493
+ .progress.acc .progress-fill { background: var(--c-accent); }
494
+
495
+ /* Indeterminate — shimmer slice loops left-to-right */
496
+ .progress.indet .progress-fill {
497
+ width: 30%; animation: progress-indet 1.4s linear infinite;
498
+ }
499
+ @keyframes progress-indet {
500
+ 0% { transform: translateX(-100%); }
501
+ 100% { transform: translateX(400%); }
502
+ }
503
+
504
+ /* Segmented — multiple fills side by side, e.g. cache-hit / cache-miss split */
505
+ .progress.segmented { display: flex; gap: 1px; background: transparent; padding: 0; height: 6px; }
506
+ .progress.segmented .progress-seg { height: 100%; }
507
+ .progress.segmented .progress-seg.s1 { background: var(--s1); }
508
+ .progress.segmented .progress-seg.s2 { background: var(--s2); }
509
+ .progress.segmented .progress-seg.s3 { background: var(--s3); }
510
+ .progress.segmented .progress-seg.s4 { background: var(--s4); }
511
+ .progress.segmented .progress-seg.s5 { background: var(--s5); }
512
+ .progress.segmented .progress-seg.dim { background: var(--bg-input); }
513
+
514
+ /* Progress with caption row */
515
+ .progress-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; }
516
+ .progress-row .lbl { font-family: var(--font-mono); font-size: 11px; color: var(--fg-3); flex-shrink: 0; min-width: 110px; }
517
+ .progress-row .v { font-family: var(--font-mono); font-size: 11.5px; color: var(--fg-0); flex-shrink: 0; min-width: 60px; text-align: right; }
518
+ .progress-row .progress { flex: 1; }
519
+
520
+ /* Step progress — numbered dots connected by lines */
521
+ .steps { display: flex; align-items: center; gap: 0; padding: 4px 0; }
522
+ .step-dot {
523
+ width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
524
+ background: var(--bg-input); border: 1px solid var(--bd-strong);
525
+ display: flex; align-items: center; justify-content: center;
526
+ font-family: var(--font-mono); font-size: 11px; color: var(--fg-3); font-weight: 600;
527
+ }
528
+ .step-dot.done { background: var(--c-ok); border-color: var(--c-ok); color: var(--bg); }
529
+ .step-dot.active { background: var(--c-brand); border-color: var(--c-brand); color: var(--bg); }
530
+ .step-dot.fail { background: var(--c-err); border-color: var(--c-err); color: var(--bg); }
531
+ .step-line { flex: 1; height: 1px; background: var(--bd-strong); margin: 0 -1px; }
532
+ .step-line.done { background: var(--c-ok); }
533
+ .step-line.active { background: linear-gradient(90deg, var(--c-ok), var(--c-brand)); }
534
+
535
+ /* Ring — circular progress, anchors its own value text */
536
+ .ring { position: relative; display: inline-block; line-height: 0; }
537
+ .ring svg { transform: rotate(-90deg); display: block; }
538
+ .ring-bg { fill: none; stroke: var(--bg-input); }
539
+ .ring-fill { fill: none; stroke: var(--c-brand); stroke-linecap: round; transition: stroke-dashoffset .4s ease; }
540
+ .ring.ok .ring-fill { stroke: var(--c-ok); }
541
+ .ring.warn .ring-fill { stroke: var(--c-warn); }
542
+ .ring.err .ring-fill { stroke: var(--c-err); }
543
+ .ring-label { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; line-height: 1.1; }
544
+ .ring-label .v { font-family: var(--font-mono); font-size: 14px; font-weight: 700; color: var(--fg-0); }
545
+ .ring-label .u { font-family: var(--font-mono); font-size: 9px; color: var(--fg-3); text-transform: uppercase; letter-spacing: .08em; }
546
+
547
+ /* ── Modal / Overlay ──────────────────────────────────────────────────── */
548
+ .overlay {
549
+ position: relative;
550
+ background: rgba(6,8,12,.78);
551
+ padding: 28px;
552
+ border-radius: var(--r);
553
+ min-height: 280px;
554
+ display: flex; align-items: center; justify-content: center;
555
+ }
556
+ .overlay::before {
557
+ /* Box-drawing corner ticks at the four corners — TUI signature */
558
+ content: "";
559
+ position: absolute; inset: 8px;
560
+ border: 1px solid #14171e;
561
+ pointer-events: none;
562
+ border-radius: var(--r);
563
+ }
564
+ .dialog {
565
+ background: var(--bg-elev);
566
+ border: 1px solid var(--bd-strong);
567
+ border-radius: var(--r);
568
+ width: 100%; max-width: 540px;
569
+ box-shadow: 0 18px 48px rgba(0,0,0,.5), 0 0 0 1px rgba(255,255,255,.02);
570
+ }
571
+ .dialog-h {
572
+ padding: 11px 16px; border-bottom: 1px solid var(--bd);
573
+ display: flex; align-items: center; gap: 10px; font-family: var(--font-mono);
574
+ }
575
+ .dialog-h .glyph { font-size: 14px; color: var(--c-brand); }
576
+ .dialog-h .title { color: var(--fg-0); font-weight: 600; font-size: 12.5px; letter-spacing: .04em; text-transform: uppercase; }
577
+ .dialog-h .meta { margin-left: auto; font-size: 11px; color: var(--fg-3); }
578
+ .dialog-b { padding: 14px 16px; }
579
+ .dialog-f { padding: 10px 16px; border-top: 1px solid var(--bd); display: flex; align-items: center; gap: 8px; }
580
+ .dialog-f .grow { flex: 1; }
581
+ .dialog-f .hint { font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-4); }
582
+
583
+ .dialog.warn .dialog-h .glyph,
584
+ .dialog.warn .dialog-h .title { color: var(--c-warn); }
585
+ .dialog.warn { border-top: 2px solid var(--c-warn); }
586
+
587
+ .dialog.acc .dialog-h .glyph,
588
+ .dialog.acc .dialog-h .title { color: var(--c-accent); }
589
+ .dialog.acc { border-top: 2px solid var(--c-accent); }
590
+
591
+ /* Command palette — centered, larger, search-driven */
592
+ .cmd-palette {
593
+ background: var(--bg-elev);
594
+ border: 1px solid var(--bd-strong);
595
+ border-radius: var(--r);
596
+ width: 100%; max-width: 560px;
597
+ box-shadow: 0 24px 64px rgba(0,0,0,.6);
598
+ overflow: hidden;
599
+ }
600
+ .cmd-palette .cmd-input-row {
601
+ display: flex; align-items: center; gap: 10px; padding: 11px 16px;
602
+ border-bottom: 1px solid var(--bd);
603
+ }
604
+ .cmd-palette .cmd-input-row .g { font-family: var(--font-mono); color: var(--c-brand); font-size: 14px; }
605
+ .cmd-palette .cmd-input-row input {
606
+ flex: 1; background: transparent; border: none; outline: none;
607
+ color: var(--fg-0); font-family: var(--font-mono); font-size: 14px;
608
+ }
609
+ .cmd-palette .cmd-input-row .kbd {
610
+ font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-3);
611
+ border: 1px solid var(--bd); padding: 1px 5px; border-radius: var(--r); background: var(--bg-input);
612
+ }
613
+ .cmd-palette .cmd-list { padding: 4px 0; max-height: 320px; overflow-y: auto; }
614
+ .cmd-row {
615
+ display: flex; align-items: center; gap: 10px; padding: 6px 16px;
616
+ cursor: pointer; font-size: 13px; color: var(--fg-1);
617
+ }
618
+ .cmd-row:hover, .cmd-row.sel { background: var(--bg-hover); }
619
+ .cmd-row.sel { border-left: 2px solid var(--c-brand); padding-left: 14px; }
620
+ .cmd-row .g { font-family: var(--font-mono); color: var(--c-brand); font-size: 12px; width: 14px; flex-shrink: 0; }
621
+ .cmd-row .name { font-family: var(--font-mono); color: var(--fg-0); }
622
+ .cmd-row .desc { color: var(--fg-3); font-size: 12px; margin-left: auto; }
623
+ .cmd-row .kbd { font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-3); border: 1px solid var(--bd); padding: 1px 5px; border-radius: var(--r); background: var(--bg-input); }
624
+ .cmd-section-h { font-family: var(--font-mono); font-size: 10px; color: var(--fg-4); padding: 8px 16px 4px; text-transform: uppercase; letter-spacing: .12em; }
625
+
626
+ /* Popover — anchored dropdown for slash / @ menus */
627
+ .popover {
628
+ background: var(--bg-elev-2);
629
+ border: 1px solid var(--bd-strong);
630
+ border-radius: var(--r);
631
+ box-shadow: 0 12px 32px rgba(0,0,0,.5);
632
+ padding: 4px 0; min-width: 240px; max-width: 360px;
633
+ }
634
+ .popover-h { padding: 6px 12px 4px; font-family: var(--font-mono); font-size: 10px; color: var(--fg-4); text-transform: uppercase; letter-spacing: .12em; }
635
+ .popover-row {
636
+ padding: 5px 12px; display: flex; align-items: center; gap: 8px;
637
+ font-size: 12.5px; color: var(--fg-1); cursor: pointer;
638
+ }
639
+ .popover-row:hover, .popover-row.sel { background: var(--bg-hover); }
640
+ .popover-row.sel { border-left: 2px solid var(--c-brand); padding-left: 10px; }
641
+ .popover-row .g { font-family: var(--font-mono); color: var(--c-brand); font-size: 12px; width: 14px; flex-shrink: 0; }
642
+ .popover-row .name { font-family: var(--font-mono); color: var(--fg-0); }
643
+ .popover-row .meta { margin-left: auto; color: var(--fg-3); font-family: var(--font-mono); font-size: 11px; }
644
+
645
+ /* ── Composer (chat input, multi-line, with chips) ────────────────────── */
646
+ .composer {
647
+ background: var(--bg-input); border: 1px solid var(--bd);
648
+ border-radius: var(--r); padding: 8px 10px;
649
+ display: flex; flex-direction: column; gap: 6px;
650
+ }
651
+ .composer:focus-within { border-color: var(--c-brand); }
652
+ .composer-tags { display: flex; flex-wrap: wrap; gap: 4px; }
653
+ .composer-chip {
654
+ display: inline-flex; align-items: center; gap: 4px;
655
+ background: var(--bg-elev-2); padding: 2px 6px 2px 8px;
656
+ border-radius: var(--r); font-family: var(--font-mono); font-size: 11px;
657
+ border: 1px solid var(--bd);
658
+ }
659
+ .composer-chip.attach { color: var(--c-brand); border-color: rgba(121,192,255,.25); }
660
+ .composer-chip.paste { color: var(--c-accent); border-color: rgba(210,168,255,.25); }
661
+ .composer-chip .x { color: var(--fg-3); cursor: pointer; padding: 0 2px; }
662
+ .composer-chip .x:hover { color: var(--fg-0); }
663
+ .composer-text {
664
+ background: transparent; border: none; outline: none;
665
+ color: var(--fg-0); font-family: var(--font-mono); font-size: 13px;
666
+ width: 100%; resize: none; min-height: 22px; line-height: 1.6;
667
+ padding: 4px 0;
668
+ }
669
+ .composer-text .caret { display: inline-block; width: 8px; height: 16px; background: var(--c-brand); vertical-align: text-bottom; animation: caret 1s steps(2) infinite; margin-left: 1px; }
670
+ @keyframes caret { 50% { opacity: 0; } }
671
+ .composer-foot {
672
+ display: flex; align-items: center; gap: 14px; padding-top: 4px;
673
+ font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-4);
674
+ border-top: 1px solid #14171e;
675
+ }
676
+ .composer-foot .grow { flex: 1; }
677
+ .composer-foot .hint .kbd {
678
+ border: 1px solid var(--bd); padding: 0 4px; border-radius: var(--r);
679
+ color: var(--fg-3); margin: 0 2px; background: var(--bg-elev);
680
+ }
681
+ .composer-foot .send { color: var(--c-brand); cursor: pointer; }
682
+
683
+ /* TUI status indicator (small pill in topbar) */
684
+ .tui-status {
685
+ display: inline-flex; align-items: center; gap: 6px;
686
+ font-family: var(--font-mono); font-size: 10.5px;
687
+ padding: 2px 8px; border-radius: 9px;
688
+ background: var(--bg-elev-2); color: var(--fg-3); border: 1px solid var(--bd);
689
+ }
690
+ .tui-status .dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
691
+ .tui-status.online { color: var(--c-ok); } .tui-status.online .dot { background: var(--c-ok); box-shadow: 0 0 6px rgba(126,231,135,.5); }
692
+ .tui-status.laggy { color: var(--c-warn); } .tui-status.laggy .dot { background: var(--c-warn); }
693
+ .tui-status.offline { color: var(--c-err); } .tui-status.offline .dot { background: var(--c-err); }
694
+
695
+ /* ── Breadcrumbs — replace topbar `·` with `›` for crumb-style flow ───── */
696
+ .crumbs { display: flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 12px; }
697
+ .crumbs .crumb { color: var(--fg-1); }
698
+ .crumbs .crumb.dim { color: var(--fg-3); }
699
+ .crumbs .sep { color: var(--fg-4); }
700
+
701
+ /* ── Sessions panel ──────────────────────────────────────────────────── */
702
+ .sessions-grid {
703
+ display: grid;
704
+ grid-template-columns: 320px minmax(0, 1fr);
705
+ /* `minmax(0, 1fr)` on the row + `min-height: 0` on the children is the
706
+ standard recipe for "let the inner overflow:auto take effect" — without
707
+ it the grid items default to min-height: auto (= content size) and
708
+ grow past the parent's max-height, dragging .app-body along. */
709
+ grid-template-rows: minmax(0, 1fr);
710
+ gap: 14px;
711
+ min-height: 540px;
712
+ max-height: calc(100vh - 140px);
713
+ }
714
+ .sessions-list { background: var(--bg-elev); border: 1px solid var(--bd); border-radius: var(--r); display: flex; flex-direction: column; overflow: hidden; min-height: 0; min-width: 0; }
715
+ .sessions-list .ssl-h { padding: 10px 12px; border-bottom: 1px solid var(--bd); display: flex; align-items: center; gap: 8px; }
716
+ .sessions-list .ssl-h input {
717
+ flex: 1; background: var(--bg-input); border: 1px solid var(--bd); border-radius: var(--r);
718
+ padding: 4px 8px; font-family: var(--font-mono); font-size: 12px; color: var(--fg-0); outline: none;
719
+ }
720
+ .sessions-list .ssl-h input:focus { border-color: var(--c-brand); }
721
+ .sessions-list .ssl-rows { flex: 1; overflow-y: auto; }
722
+ .ssl-row {
723
+ padding: 8px 12px; border-bottom: 1px solid #14171e; cursor: pointer;
724
+ display: flex; flex-direction: column; gap: 3px;
725
+ }
726
+ .ssl-row:hover { background: var(--bg-hover); }
727
+ .ssl-row.sel { background: var(--bg-hover); border-left: 2px solid var(--c-brand); padding-left: 10px; }
728
+ .ssl-row .name { font-family: var(--font-mono); font-size: 12.5px; color: var(--fg-0); }
729
+ .ssl-row .preview { font-size: 11.5px; color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
730
+ .ssl-row .meta { display: flex; gap: 10px; font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-4); margin-top: 2px; }
731
+ .ssl-row .meta .v { color: var(--fg-2); }
732
+
733
+ .sessions-detail { background: var(--bg-elev); border: 1px solid var(--bd); border-radius: var(--r); padding: 14px 16px; overflow: auto; min-height: 0; min-width: 0; }
734
+ .sessions-detail-h { display: flex; align-items: baseline; gap: 12px; margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--bd); }
735
+ .sessions-detail-h .name { font-family: var(--font-mono); font-size: 14px; color: var(--fg-0); font-weight: 600; }
736
+ .sessions-detail-h .ws { font-family: var(--font-mono); font-size: 11px; color: var(--fg-3); }
737
+ .sessions-detail-h .actions { margin-left: auto; display: flex; gap: 6px; }
738
+ .sessions-detail-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 14px; }
739
+ .sessions-detail-kpis .kp { padding: 8px 10px; background: var(--bg-input); border-radius: var(--r); }
740
+ .sessions-detail-kpis .kp .lbl { font-family: var(--font-mono); font-size: 10px; color: var(--fg-4); text-transform: uppercase; letter-spacing: .1em; }
741
+ .sessions-detail-kpis .kp .v { font-family: var(--font-mono); font-size: 16px; color: var(--fg-0); font-weight: 600; margin-top: 2px; }
742
+
743
+ /* ── File tree (Editor panel) ────────────────────────────────────────── */
744
+ .tree { font-family: var(--font-mono); font-size: 12px; padding: 6px 0; user-select: none; }
745
+ .tree-node {
746
+ padding: 3px 8px 3px 0; cursor: pointer; display: flex; align-items: center; gap: 4px;
747
+ color: var(--fg-2); border-left: 2px solid transparent;
748
+ }
749
+ .tree-node:hover { background: var(--bg-hover); color: var(--fg-1); }
750
+ .tree-node.sel { background: var(--bg-hover); color: var(--c-brand); border-left-color: var(--c-brand); }
751
+ .tree-node .indent { display: inline-block; width: 10px; flex-shrink: 0; }
752
+ .tree-node .arrow { width: 10px; color: var(--fg-3); }
753
+ .tree-node.open .arrow { color: var(--c-brand); }
754
+ .tree-node .icon { width: 12px; color: var(--fg-3); flex-shrink: 0; }
755
+ .tree-node .icon.dir { color: var(--c-brand); }
756
+ .tree-node .icon.tsx { color: var(--c-brand); }
757
+ .tree-node .icon.css { color: var(--c-accent); }
758
+ .tree-node .icon.md { color: var(--c-warn); }
759
+ .tree-node .icon.json { color: var(--c-violet); }
760
+ .tree-node .name { flex: 1; }
761
+ .tree-node .badge { font-size: 9px; color: var(--c-warn); margin-left: 4px; }
762
+ .tree-node .modified { color: var(--c-warn); font-size: 14px; line-height: 0.5; margin-left: 4px; }
763
+
764
+ /* ── Editor tabs ─────────────────────────────────────────────────────── */
765
+ .editor-tabs {
766
+ display: flex; border-bottom: 1px solid var(--bd); background: var(--bg-elev);
767
+ overflow-x: auto; scrollbar-width: none;
768
+ }
769
+ .editor-tabs::-webkit-scrollbar { display: none; }
770
+ .editor-tab {
771
+ padding: 7px 14px; font-family: var(--font-mono); font-size: 12px;
772
+ color: var(--fg-3); border-right: 1px solid var(--bd);
773
+ display: flex; align-items: center; gap: 6px; cursor: pointer;
774
+ border-bottom: 2px solid transparent; margin-bottom: -1px; flex-shrink: 0;
775
+ }
776
+ .editor-tab:hover { color: var(--fg-1); background: var(--bg-hover); }
777
+ .editor-tab.active { color: var(--fg-0); background: var(--bg); border-bottom-color: var(--c-brand); }
778
+ .editor-tab .x { color: var(--fg-4); font-size: 10px; padding: 0 2px; border-radius: var(--r); }
779
+ .editor-tab .x:hover { color: var(--fg-0); background: var(--bd); }
780
+ .editor-tab .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--c-warn); flex-shrink: 0; }
781
+
782
+ /* ── Code editor area ────────────────────────────────────────────────── */
783
+ .editor-area {
784
+ background: var(--bg-code); padding: 8px 0;
785
+ font-family: var(--font-mono); font-size: 12.5px; line-height: 1.6;
786
+ color: var(--fg-1); overflow: auto;
787
+ flex: 1; min-height: 0;
788
+ }
789
+ .editor-line {
790
+ display: grid; grid-template-columns: 62px 1fr;
791
+ padding: 0; white-space: pre;
792
+ }
793
+ .editor-line:hover { background: rgba(121,192,255,.04); }
794
+ .editor-line.cur { background: rgba(121,192,255,.06); }
795
+ .editor-line .lineno { color: var(--fg-4); text-align: right; padding: 0 10px 0 20px; user-select: none; font-variant-numeric: tabular-nums; }
796
+ .editor-line .ln-content { color: var(--fg-1); }
797
+ .editor-line .ln-content .kw { color: var(--c-accent); }
798
+ .editor-line .ln-content .str { color: var(--c-ok); }
799
+ .editor-line .ln-content .com { color: var(--fg-3); font-style: italic; }
800
+ .editor-line .ln-content .num { color: var(--c-warn); }
801
+ .editor-line .ln-content .typ { color: var(--c-violet); }
802
+ .editor-line .ln-content .fn { color: var(--c-brand); }
803
+ .editor-line .ln-content .gut { color: var(--fg-4); }
804
+
805
+ .editor-status {
806
+ display: flex; align-items: center; gap: 12px; padding: 4px 14px;
807
+ background: var(--bg-elev); border-top: 1px solid var(--bd);
808
+ font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-3);
809
+ }
810
+ .editor-status .v { color: var(--fg-1); }
811
+ .editor-status .grow { flex: 1; }
812
+ .editor-status .glyph { color: var(--c-brand); }
813
+
814
+ /* ── Filter chips ────────────────────────────────────────────────────── */
815
+ .chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 0 8px; }
816
+ .chip-f {
817
+ font-family: var(--font-mono); font-size: 11px; padding: 3px 9px;
818
+ border: 1px solid var(--bd); border-radius: 12px; cursor: pointer;
819
+ color: var(--fg-2); background: var(--bg-elev);
820
+ display: inline-flex; align-items: center; gap: 5px;
821
+ }
822
+ .chip-f:hover { background: var(--bg-hover); color: var(--fg-1); }
823
+ .chip-f.active { color: var(--c-brand); border-color: var(--c-brand); background: rgba(121,192,255,.08); }
824
+ .chip-f.static { cursor: default; }
825
+ .chip-f.static:hover { background: var(--bg-elev); color: var(--fg-2); }
826
+ .chip-f.static.active:hover { color: var(--c-brand); background: rgba(121,192,255,.08); }
827
+ .chip-f .ct { color: var(--fg-4); font-size: 10px; }
828
+ .chip-f.active .ct { color: var(--c-brand); }
829
+ .chip-f .x { color: var(--fg-4); padding: 0 2px; }
830
+ .chip-f .x:hover { color: var(--c-err); }
831
+
832
+ .chip-edit-row { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; padding: 4px 0; }
833
+ .chip-add-input {
834
+ background: transparent; border: 1px dashed var(--bd); border-radius: 12px;
835
+ padding: 3px 9px; font-family: var(--font-mono); font-size: 11px;
836
+ color: var(--fg-3); outline: none; min-width: 80px;
837
+ }
838
+ .chip-add-input:focus { border-color: var(--c-brand); color: var(--fg-0); border-style: solid; }
839
+
840
+ /* ── Stacked bar (chart) ─────────────────────────────────────────────── */
841
+ .stacked-bar { width: 100%; height: 12px; background: var(--bg-input); border-radius: var(--r); overflow: hidden; display: flex; }
842
+ .stacked-bar > div { height: 100%; }
843
+
844
+ /* ── Form sub-tabs ───────────────────────────────────────────────────── */
845
+ .form-tabs {
846
+ display: flex; border-bottom: 1px solid var(--bd); margin-bottom: 14px; gap: 0;
847
+ }
848
+ .form-tab {
849
+ padding: 8px 14px; font-family: var(--font-mono); font-size: 12px;
850
+ color: var(--fg-3); cursor: pointer; border-bottom: 2px solid transparent;
851
+ margin-bottom: -1px; letter-spacing: .04em; text-transform: uppercase; font-size: 11px;
852
+ }
853
+ .form-tab:hover { color: var(--fg-1); }
854
+ .form-tab.active { color: var(--fg-0); border-bottom-color: var(--c-brand); }
855
+
856
+ /* ── Schema (JSON-like display) ──────────────────────────────────────── */
857
+ .schema {
858
+ font-family: var(--font-mono); font-size: 11.5px; color: var(--fg-1); line-height: 1.7;
859
+ padding: 10px 14px; background: var(--bg-code); border-radius: var(--r);
860
+ border: 1px solid var(--bd); white-space: pre; overflow-x: auto;
861
+ }
862
+ .schema .key { color: var(--c-brand); }
863
+ .schema .typ { color: var(--c-violet); }
864
+ .schema .req { color: var(--c-warn); font-style: italic; font-size: 10px; }
865
+ .schema .com { color: var(--fg-3); font-style: italic; }
866
+ .schema .str { color: var(--c-ok); }
867
+
868
+ /* ── Log tail ────────────────────────────────────────────────────────── */
869
+ .log-tail {
870
+ font-family: var(--font-mono); font-size: 11.5px; color: var(--fg-2);
871
+ padding: 10px 14px; background: var(--bg-code); border: 1px solid var(--bd);
872
+ border-radius: var(--r); line-height: 1.7; max-height: 240px; overflow-y: auto;
873
+ white-space: pre;
874
+ }
875
+ .log-tail .ts { color: var(--fg-4); }
876
+ .log-tail .lvl { display: inline-block; width: 50px; }
877
+ .log-tail .info { color: var(--c-info); }
878
+ .log-tail .warn { color: var(--c-warn); }
879
+ .log-tail .err { color: var(--c-err); }
880
+ .log-tail .ok { color: var(--c-ok); }
881
+ .log-tail .src { color: var(--c-accent); }
882
+
883
+ /* ── Search result card ──────────────────────────────────────────────── */
884
+ .sr-card { padding: 10px 14px; border-bottom: 1px solid #14171e; cursor: pointer; }
885
+ .sr-card:hover { background: var(--bg-hover); }
886
+ .sr-card .sr-h { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
887
+ .sr-card .sr-path { font-family: var(--font-mono); font-size: 12px; color: var(--c-brand); }
888
+ .sr-card .sr-loc { font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-3); }
889
+ .sr-card .sr-score { font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-4); margin-left: auto; }
890
+ .sr-card .sr-snip { font-family: var(--font-mono); font-size: 11.5px; color: var(--fg-2); padding: 4px 0 0; white-space: pre; overflow-x: auto; }
891
+ .sr-card .sr-snip mark { background: rgba(240,176,125,.18); color: var(--c-warn); padding: 0 2px; border-radius: 1px; }
892
+
893
+ /* ── Health grid ─────────────────────────────────────────────────────── */
894
+ .health-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; }
895
+ .health-item {
896
+ padding: 10px 12px; background: var(--bg-elev); border: 1px solid var(--bd);
897
+ border-left: 2px solid var(--c-ok); border-radius: var(--r);
898
+ }
899
+ .health-item.warn { border-left-color: var(--c-warn); }
900
+ .health-item.err { border-left-color: var(--c-err); }
901
+ .health-item .lbl { font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-3); text-transform: uppercase; letter-spacing: .08em; display: flex; align-items: center; gap: 6px; }
902
+ .health-item .lbl .pill { font-size: 9px; padding: 0 5px; }
903
+ .health-item .v { font-family: var(--font-mono); font-size: 13px; color: var(--fg-0); margin-top: 4px; }
904
+ .health-item .meta { font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-3); margin-top: 2px; }
905
+
906
+ /* ── Plan timeline (horizontal step bar with detail) ─────────────────── */
907
+ .plan-timeline {
908
+ display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
909
+ gap: 0; padding: 6px 0;
910
+ }
911
+ .plan-step {
912
+ position: relative; padding: 8px 10px;
913
+ border-top: 2px solid var(--bd-strong);
914
+ display: flex; flex-direction: column; gap: 2px;
915
+ }
916
+ .plan-step.done { border-top-color: var(--c-ok); }
917
+ .plan-step.active { border-top-color: var(--c-brand); }
918
+ .plan-step.fail { border-top-color: var(--c-err); }
919
+ .plan-step::before {
920
+ content: ""; position: absolute; top: -5px; left: 0;
921
+ width: 8px; height: 8px; border-radius: 50%; background: var(--bd-strong);
922
+ }
923
+ .plan-step.done::before { background: var(--c-ok); }
924
+ .plan-step.active::before { background: var(--c-brand); box-shadow: 0 0 0 3px rgba(121,192,255,.18); }
925
+ .plan-step.fail::before { background: var(--c-err); }
926
+ .plan-step .lbl { font-family: var(--font-mono); font-size: 10px; color: var(--fg-4); text-transform: uppercase; letter-spacing: .08em; }
927
+ .plan-step .name { font-family: var(--font-mono); font-size: 12px; color: var(--fg-1); }
928
+ .plan-step.active .name { color: var(--fg-0); }
929
+ .plan-step.done .name { color: var(--fg-2); }
930
+ .plan-step .meta { font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-3); }
931
+
932
+ /* ── Donut chart (SVG inline) ────────────────────────────────────────── */
933
+ .donut-legend { display: grid; grid-template-columns: 1fr; gap: 4px; padding-left: 8px; font-family: var(--font-mono); font-size: 11px; }
934
+ .donut-legend .row { display: flex; align-items: center; gap: 6px; color: var(--fg-2); }
935
+ .donut-legend .row .dot { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }
936
+ .donut-legend .row .v { color: var(--fg-0); margin-left: auto; }
937
+
938
+ /* ── Two-column inventory layout ─────────────────────────────────────── */
939
+ .inv-grid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 14px; }
940
+
941
+ /* ── Sub-tabs sidebar variant for Configuration ──────────────────────── */
942
+ .cfg-grid { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 14px; }
943
+ .cfg-nav { background: var(--bg-elev); border: 1px solid var(--bd); border-radius: var(--r); padding: 6px; }
944
+ .cfg-nav .cfg-item {
945
+ padding: 6px 10px; font-family: var(--font-mono); font-size: 12px;
946
+ color: var(--fg-2); cursor: pointer; border-radius: var(--r);
947
+ display: flex; align-items: center; gap: 8px;
948
+ border-left: 2px solid transparent; padding-left: 8px;
949
+ }
950
+ .cfg-nav .cfg-item:hover { background: var(--bg-hover); color: var(--fg-1); }
951
+ .cfg-nav .cfg-item.active { background: var(--bg-hover); color: var(--c-brand); border-left-color: var(--c-brand); }
952
+ .cfg-content { background: var(--bg-elev); border: 1px solid var(--bd); border-radius: var(--r); padding: 16px 18px; }
953
+
954
+ /* ── Hook event matrix ───────────────────────────────────────────────── */
955
+ .matrix { font-family: var(--font-mono); font-size: 11px; }
956
+ .matrix .row { display: grid; grid-template-columns: 160px repeat(6, 1fr); border-bottom: 1px solid var(--bd); }
957
+ .matrix .row.h { color: var(--fg-3); padding-bottom: 4px; text-transform: uppercase; letter-spacing: .08em; font-size: 10px; }
958
+ .matrix .row.h > div { padding: 6px 8px; text-align: center; }
959
+ .matrix .row.h > div:first-child { text-align: left; }
960
+ .matrix .cell {
961
+ padding: 6px 8px; text-align: center; color: var(--fg-3);
962
+ border-left: 1px solid var(--bd);
963
+ display: flex; align-items: center; justify-content: center; min-height: 28px;
964
+ }
965
+ .matrix .cell:first-child { border-left: none; text-align: left; justify-content: flex-start; color: var(--fg-1); }
966
+ .matrix .cell.on { color: var(--c-brand); background: rgba(121,192,255,.05); }
967
+ .matrix .cell.off { color: var(--fg-4); }
968
+
969
+ /* ── §4 Chat panel ─────────────────────────────────────────────────────── */
970
+ .chat-banner {
971
+ background: rgba(121,192,255,.06);
972
+ border: 1px solid rgba(121,192,255,.18);
973
+ border-radius: var(--r);
974
+ padding: 10px 14px;
975
+ display: flex; align-items: center; gap: 12px;
976
+ margin-bottom: 16px;
977
+ font-size: 12.5px;
978
+ }
979
+ .chat-banner .g { color: var(--c-brand); font-family: var(--font-mono); font-size: 14px; }
980
+ .chat-banner .txt { color: var(--fg-1); }
981
+ .chat-banner .txt b { color: var(--fg-0); }
982
+ .chat-banner .takeover { margin-left: auto; }
983
+
984
+ .chat-grid { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 20px; }
985
+
986
+ .chat-stream { display: flex; flex-direction: column; gap: 12px; }
987
+
988
+ /* Chat cards — web-flavored cards, more breathing room than the TUI */
989
+ .cc {
990
+ background: var(--bg-elev); border: 1px solid var(--bd); border-radius: var(--r);
991
+ padding: 12px 14px;
992
+ }
993
+ .cc-h { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; font-family: var(--font-mono); font-size: 11.5px; }
994
+ .cc-h .glyph { font-size: 13px; width: 14px; text-align: center; }
995
+ .cc-h .role { font-weight: 600; letter-spacing: .04em; text-transform: uppercase; font-size: 10.5px; }
996
+ .cc-h .meta { margin-left: auto; color: var(--fg-3); font-size: 10.5px; }
997
+ .cc-b { color: var(--fg-1); font-size: 13.5px; line-height: 1.65; }
998
+ .cc-b p { margin: 0 0 6px; }
999
+ .cc-b p:last-child { margin-bottom: 0; }
1000
+ .cc-b code.inline { background: var(--bg-code); padding: 1px 5px; border-radius: var(--r); font-size: 12px; color: var(--c-accent); }
1001
+
1002
+ .cc.user .cc-h .glyph, .cc.user .cc-h .role { color: var(--c-brand); }
1003
+ .cc.assistant .cc-h .glyph, .cc.assistant .cc-h .role { color: var(--c-ok); }
1004
+ .cc.tool .cc-h .glyph, .cc.tool .cc-h .role { color: var(--c-warn); }
1005
+ .cc.reasoning .cc-h .glyph, .cc.reasoning .cc-h .role { color: var(--c-accent); }
1006
+ .cc.reasoning .cc-b { color: var(--fg-2); font-size: 12.5px; font-style: italic; }
1007
+
1008
+ .cc.tool .tool-args { margin-top: 6px; font-family: var(--font-mono); font-size: 11.5px; color: var(--fg-2); padding: 4px 8px; background: var(--bg-code); border-radius: var(--r); }
1009
+ .cc.tool .tool-out { margin-top: 8px; }
1010
+
1011
+ /* Chat side rail */
1012
+ .chat-rail { display: flex; flex-direction: column; gap: 12px; }
1013
+ .rail-card {
1014
+ background: var(--bg-elev); border: 1px solid var(--bd); border-radius: var(--r);
1015
+ padding: 10px 12px;
1016
+ }
1017
+ .rail-card .rh {
1018
+ font-family: var(--font-mono); font-size: 10px; color: var(--fg-4);
1019
+ text-transform: uppercase; letter-spacing: .12em; margin-bottom: 8px;
1020
+ }
1021
+ .rail-step {
1022
+ display: flex; align-items: flex-start; gap: 8px;
1023
+ padding: 4px 0; font-size: 12.5px;
1024
+ }
1025
+ .rail-step .g { font-family: var(--font-mono); color: var(--fg-3); width: 14px; flex-shrink: 0; }
1026
+ .rail-step.done .g { color: var(--c-ok); }
1027
+ .rail-step.active .g { color: var(--c-brand); }
1028
+ .rail-step.active { color: var(--fg-0); }
1029
+ .rail-step.done { color: var(--fg-2); text-decoration: line-through; text-decoration-color: var(--fg-4); }
1030
+
1031
+ .rail-kv { display: flex; justify-content: space-between; padding: 2px 0; font-family: var(--font-mono); font-size: 11.5px; }
1032
+ .rail-kv .k { color: var(--fg-3); }
1033
+ .rail-kv .v { color: var(--fg-0); }
1034
+
1035
+ /* ── §5 Overview cockpit ────────────────────────────────────────────────── */
1036
+ .cockpit { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
1037
+ .cock-w-1 { grid-column: span 1; }
1038
+ .cock-w-2 { grid-column: span 2; }
1039
+ .cock-w-3 { grid-column: span 3; }
1040
+ .cock-w-4 { grid-column: span 4; }
1041
+
1042
+ .kpi {
1043
+ background: var(--bg-elev); border: 1px solid var(--bd); border-radius: var(--r); padding: 14px 16px;
1044
+ }
1045
+ .kpi .label { font-family: var(--font-mono); font-size: 10.5px; color: var(--fg-3); text-transform: uppercase; letter-spacing: .1em; margin-bottom: 6px; }
1046
+ .kpi .value { font-family: var(--font-mono); font-size: 24px; color: var(--fg-0); font-weight: 700; letter-spacing: -.01em; }
1047
+ .kpi .value .unit { font-size: 13px; color: var(--fg-3); font-weight: 400; margin-left: 4px; }
1048
+ .kpi .delta { font-family: var(--font-mono); font-size: 11px; margin-top: 4px; }
1049
+ .kpi .delta.up { color: var(--c-ok); }
1050
+ .kpi .delta.down { color: var(--c-err); }
1051
+ .kpi .delta.flat { color: var(--fg-3); }
1052
+
1053
+ .cock-list {
1054
+ background: var(--bg-elev); border: 1px solid var(--bd); border-radius: var(--r); padding: 12px 14px;
1055
+ }
1056
+ .cock-list .ch { display: flex; align-items: center; gap: 8px; padding-bottom: 8px; border-bottom: 1px solid var(--bd); margin-bottom: 8px; }
1057
+ .cock-list .ch .ttl { font-family: var(--font-mono); font-size: 11px; color: var(--fg-3); text-transform: uppercase; letter-spacing: .1em; }
1058
+ .cock-list .ch a { margin-left: auto; font-family: var(--font-mono); font-size: 11px; color: var(--c-brand); }
1059
+
1060
+ .feed-row {
1061
+ display: grid; grid-template-columns: 14px 1fr auto; gap: 8px;
1062
+ padding: 5px 0; font-size: 12.5px; align-items: center;
1063
+ }
1064
+ .feed-row .g { font-family: var(--font-mono); color: var(--fg-3); }
1065
+ .feed-row.ok .g { color: var(--c-ok); }
1066
+ .feed-row.warn .g { color: var(--c-warn); }
1067
+ .feed-row.err .g { color: var(--c-err); }
1068
+ .feed-row .name { color: var(--fg-1); font-family: var(--font-mono); font-size: 12px; }
1069
+ .feed-row .when { color: var(--fg-4); font-family: var(--font-mono); font-size: 10.5px; }
1070
+ .feed-row .name .args { color: var(--fg-3); }
1071
+
1072
+ /* Notes / "why" callouts */
1073
+ .why {
1074
+ font-size: 12px; color: var(--fg-3); padding: 8px 12px;
1075
+ border-left: 2px solid var(--c-accent); background: rgba(210,168,255,.04);
1076
+ border-radius: 0 var(--r) var(--r) 0;
1077
+ margin: 14px 0;
1078
+ }
1079
+ .why b { color: var(--fg-1); font-weight: 600; }
1080
+
1081
+ /* ── Live-mode overrides — design mockup constrained .app to a 640px tile;
1082
+ * the actual dashboard fills the viewport. ──────────────────────────── */
1083
+ html, body, #root { height: 100%; }
1084
+ #root { display: contents; }
1085
+ .app { height: 100vh; }
1086
+
1087
+ /* ── Shared utilities — small classes used across multiple panels. ── */
1088
+ .boot { color: var(--fg-3); padding: 24px; text-align: center; font-family: var(--font-mono); font-size: 12px; }
1089
+ .empty { color: var(--fg-3); padding: 18px; border: 1px dashed var(--bd); border-radius: var(--r); font-size: 12.5px; }
1090
+ .notice { background: var(--bg-elev); border: 1px solid var(--bd); border-left: 2px solid var(--c-brand); border-radius: var(--r); padding: 8px 12px; margin: 8px 0; font-size: 12.5px; color: var(--fg-1); }
1091
+ .notice.err { border-left-color: var(--c-err); color: var(--c-err); }
1092
+ .notice.warn { border-left-color: var(--c-warn); color: var(--c-warn); }
1093
+ .muted { color: var(--fg-3); }
1094
+ .pill-err { color: var(--c-err); background: rgba(255,139,129,.10); }
1095
+ .pill-active { color: var(--c-brand); background: rgba(121,192,255,.10); }
1096
+ button.primary { background: var(--c-brand); color: var(--bg); border: 1px solid var(--c-brand); padding: 5px 12px; border-radius: var(--r); font-family: var(--font-sans); font-size: 12px; cursor: pointer; }
1097
+ button.primary:hover { background: rgba(121,192,255,.85); }
1098
+ button.danger { background: transparent; color: var(--c-err); border: 1px solid var(--c-err); padding: 5px 12px; border-radius: var(--r); font-family: var(--font-sans); font-size: 12px; cursor: pointer; }
1099
+ button:not(.primary):not(.danger):not(.btn):not(.mode-btn):not(.chat-banner-close):not(.chat-inflight-abort) { background: var(--bg-elev-2); color: var(--fg-1); border: 1px solid var(--bd); padding: 5px 12px; border-radius: var(--r); font-family: var(--font-sans); font-size: 12px; cursor: pointer; }
1100
+ button:hover:not(.primary):not(.danger):not(.btn):not(.mode-btn):not(.chat-banner-close):not(.chat-inflight-abort) { background: var(--bg-hover); border-color: var(--bd-strong); }
1101
+ input[type=text], input[type=number], input[type=password], textarea, select { background: var(--bg-input); color: var(--fg-0); border: 1px solid var(--bd); border-radius: var(--r); padding: 5px 10px; font-family: var(--font-mono); font-size: 12.5px; outline: none; }
1102
+ input:focus, textarea:focus, select:focus { border-color: var(--c-brand); }
1103
+ .kv-key { display: inline-block; min-width: 70px; color: var(--fg-3); font-family: var(--font-mono); font-size: 11px; margin-right: 8px; }
1104
+
1105
+ /* ── Chat-panel legacy CSS — restored from pre-foundation app.css.
1106
+ * These selectors back the Chat panel's interior (chat-shell /
1107
+ * chat-feed / chat-msg / mode-picker / composer / modals / toasts /
1108
+ * tool-card / markdown blocks). The design mockup §4 covers the
1109
+ * chat surface conceptually but doesn't enumerate every selector;
1110
+ * rather than rewrite all of these by hand against design tokens,
1111
+ * we restore the working set and let panel migration tweak as
1112
+ * needed. Tokens inside these rules use the new design palette
1113
+ * (--c-brand, --fg-0, --bg-elev, etc.) so the visual still aligns.
1114
+ */
1115
+ /* ---------- Markdown rendering (matches TUI markdown.tsx palette) ----------
1116
+ *
1117
+ * Mapping comes from src/cli/ui/markdown.tsx:
1118
+ * H1 → bg #67e8f9 (cyan) text black, bold — pill
1119
+ * H2 → bg #c4b5fd (violet) text black, bold — pill
1120
+ * H3 → bg #f0abfc (fuchsia) text black, bold — pill
1121
+ * inline code → amber text on bg-2
1122
+ * code block → bg-1, monospace, soft border
1123
+ * blockquote → teal-300 left bar (brand)
1124
+ * strong / em → bold / italic
1125
+ * tables → bordered, monospace
1126
+ * strike → red strikethrough
1127
+ * link → cyan underline
1128
+ * diff +/- → green / red lines (handled by code-block class)
1129
+ */
1130
+
1131
+ .md {
1132
+ color: var(--fg-0);
1133
+ font-size: 14px;
1134
+ line-height: 1.7;
1135
+ }
1136
+ .md > *:first-child {
1137
+ margin-top: 0;
1138
+ }
1139
+ .md > *:last-child {
1140
+ margin-bottom: 0;
1141
+ }
1142
+
1143
+ .md p {
1144
+ margin: 0.5em 0;
1145
+ }
1146
+
1147
+ .md h1,
1148
+ .md h2,
1149
+ .md h3 {
1150
+ display: inline-block;
1151
+ padding: 2px 10px;
1152
+ margin: 0.8em 0 0.5em;
1153
+ border-radius: var(--r);
1154
+ color: #0a0e14;
1155
+ font-weight: 700;
1156
+ line-height: 1.4;
1157
+ }
1158
+ .md h1 {
1159
+ background: var(--c-brand);
1160
+ font-size: 18px;
1161
+ }
1162
+ .md h2 {
1163
+ background: var(--c-accent);
1164
+ font-size: 16px;
1165
+ }
1166
+ .md h3 {
1167
+ background: var(--s2);
1168
+ font-size: 14px;
1169
+ }
1170
+
1171
+ .md h4,
1172
+ .md h5,
1173
+ .md h6 {
1174
+ font-weight: 600;
1175
+ color: var(--c-accent);
1176
+ font-size: 14px;
1177
+ margin: 0.6em 0 0.3em;
1178
+ }
1179
+
1180
+ .md strong {
1181
+ color: var(--fg-0);
1182
+ font-weight: 700;
1183
+ }
1184
+ .md em {
1185
+ color: var(--fg-0);
1186
+ font-style: italic;
1187
+ }
1188
+ .md del {
1189
+ color: var(--c-err);
1190
+ text-decoration: line-through;
1191
+ }
1192
+
1193
+ .md a {
1194
+ color: var(--c-brand);
1195
+ text-decoration: none;
1196
+ }
1197
+ .md a:hover {
1198
+ text-decoration: underline;
1199
+ }
1200
+
1201
+ .md code {
1202
+ font-family: var(--font-mono);
1203
+ background: var(--bg-elev-2);
1204
+ color: var(--c-warn); /* amber matches TUI inline-code */
1205
+ padding: 1px 6px;
1206
+ border-radius: var(--r);
1207
+ font-size: 12px;
1208
+ }
1209
+
1210
+ .md pre {
1211
+ background: var(--bg-elev);
1212
+ border: 1px solid var(--bd);
1213
+ border-radius: var(--r-md);
1214
+ padding: 12px 14px;
1215
+ overflow-x: auto;
1216
+ margin: 0.6em 0;
1217
+ font-family: var(--font-mono);
1218
+ font-size: 12.5px;
1219
+ line-height: 1.55;
1220
+ color: var(--c-warn);
1221
+ white-space: pre;
1222
+ }
1223
+ .md pre code {
1224
+ background: transparent;
1225
+ padding: 0;
1226
+ border-radius: 0;
1227
+ color: inherit;
1228
+ font-size: inherit;
1229
+ }
1230
+
1231
+ /* Diff blocks — rendered by the custom renderer in app.js for
1232
+ * SEARCH/REPLACE markers and ``` diff fences. Mirror TUI's
1233
+ * markdown.tsx red/green palette so the experience reads as the same
1234
+ * tool whether you're in the terminal or the browser. */
1235
+ .md .diff-block,
1236
+ .diff-block {
1237
+ background: var(--bg-elev);
1238
+ border: 1px solid var(--bd);
1239
+ border-radius: var(--r-md);
1240
+ padding: 8px 12px;
1241
+ margin: 0.6em 0;
1242
+ font-family: var(--font-mono);
1243
+ font-size: 12.5px;
1244
+ line-height: 1.55;
1245
+ overflow-x: auto;
1246
+ white-space: pre;
1247
+ color: var(--fg-1);
1248
+ }
1249
+ .diff-line {
1250
+ display: block;
1251
+ padding: 0 4px;
1252
+ }
1253
+ .diff-line.ins {
1254
+ background: rgba(74, 222, 128, 0.1);
1255
+ color: #86efac;
1256
+ }
1257
+ .diff-line.del {
1258
+ background: rgba(248, 113, 113, 0.1);
1259
+ color: #fda4af;
1260
+ }
1261
+ .diff-line.hunk {
1262
+ color: var(--c-accent);
1263
+ font-weight: 500;
1264
+ }
1265
+ .diff-line.meta {
1266
+ color: var(--fg-3);
1267
+ }
1268
+
1269
+ /* highlight.js github-dark loads from CDN; we tweak surface colors
1270
+ * to merge with our card backgrounds. The theme provides token colors
1271
+ * (keyword, string, number, comment etc.) we keep as-is — they read
1272
+ * well against bg-1. */
1273
+ .md .hljs,
1274
+ .hljs {
1275
+ background: var(--bg-elev) !important;
1276
+ color: var(--fg-0);
1277
+ padding: 0;
1278
+ }
1279
+ .md pre code.hljs {
1280
+ background: transparent !important;
1281
+ }
1282
+
1283
+ .md ul,
1284
+ .md ol {
1285
+ margin: 0.4em 0;
1286
+ padding-left: 24px;
1287
+ }
1288
+ .md li {
1289
+ margin: 0.15em 0;
1290
+ }
1291
+ .md ul > li::marker {
1292
+ color: var(--c-brand);
1293
+ }
1294
+ .md ol > li::marker {
1295
+ color: var(--c-accent);
1296
+ font-weight: 600;
1297
+ }
1298
+
1299
+ .md blockquote {
1300
+ border-left: 3px solid var(--c-brand);
1301
+ padding: 4px 12px;
1302
+ margin: 0.6em 0;
1303
+ color: var(--fg-1);
1304
+ background: var(--bg-elev);
1305
+ border-radius: 0 var(--r) var(--r) 0;
1306
+ }
1307
+
1308
+ .md table {
1309
+ width: auto;
1310
+ margin: 0.6em 0;
1311
+ border-collapse: collapse;
1312
+ font-family: var(--font-mono);
1313
+ font-size: 12.5px;
1314
+ }
1315
+ .md thead {
1316
+ background: var(--bg-elev-2);
1317
+ }
1318
+ .md th,
1319
+ .md td {
1320
+ border: 1px solid var(--bd);
1321
+ padding: 6px 10px;
1322
+ text-align: left;
1323
+ }
1324
+ .md th {
1325
+ color: var(--c-brand);
1326
+ font-weight: 600;
1327
+ font-size: 11px;
1328
+ letter-spacing: 0.04em;
1329
+ text-transform: uppercase;
1330
+ }
1331
+ .md td {
1332
+ color: var(--fg-1);
1333
+ }
1334
+
1335
+ .md hr {
1336
+ border: none;
1337
+ height: 2px;
1338
+ background: var(--gradient-rule);
1339
+ margin: 1.2em 0;
1340
+ opacity: 0.6;
1341
+ }
1342
+
1343
+ .md img {
1344
+ max-width: 100%;
1345
+ border-radius: var(--r);
1346
+ }
1347
+
1348
+ /* ---------- Chat panel ---------- */
1349
+
1350
+ /* Subtracts .app-top (44) + .app-status (26) + .app-body padding (24×2). */
1351
+ .chat-shell {
1352
+ display: flex;
1353
+ flex-direction: column;
1354
+ height: calc(100vh - 44px - 26px - 48px);
1355
+ }
1356
+
1357
+ .chat-body {
1358
+ flex: 1;
1359
+ min-height: 0;
1360
+ display: grid;
1361
+ grid-template-columns: minmax(0, 1fr) 280px;
1362
+ gap: 20px;
1363
+ }
1364
+
1365
+ .chat-main {
1366
+ display: flex;
1367
+ flex-direction: column;
1368
+ min-height: 0;
1369
+ }
1370
+
1371
+ .chat-feed {
1372
+ flex: 1;
1373
+ min-height: 0;
1374
+ overflow-y: auto;
1375
+ padding: 4px 4px 16px;
1376
+ display: flex;
1377
+ flex-direction: column;
1378
+ gap: 14px;
1379
+ }
1380
+
1381
+ .chat-msg {
1382
+ display: flex;
1383
+ gap: 12px;
1384
+ align-items: flex-start;
1385
+ line-height: 1.6;
1386
+ }
1387
+
1388
+ .chat-msg .glyph {
1389
+ width: 22px;
1390
+ flex-shrink: 0;
1391
+ font-family: var(--font-mono);
1392
+ text-align: center;
1393
+ font-size: 14px;
1394
+ padding-top: 2px;
1395
+ }
1396
+
1397
+ .chat-msg .body {
1398
+ flex: 1;
1399
+ min-width: 0;
1400
+ }
1401
+
1402
+ .chat-msg.user .glyph {
1403
+ color: var(--c-brand);
1404
+ }
1405
+ .chat-msg.assistant .glyph {
1406
+ color: var(--c-ok);
1407
+ }
1408
+ .chat-msg.tool .glyph {
1409
+ color: var(--c-warn);
1410
+ }
1411
+ .chat-msg.info .glyph {
1412
+ color: var(--fg-3);
1413
+ }
1414
+ .chat-msg.warning .glyph {
1415
+ color: var(--c-warn);
1416
+ }
1417
+ .chat-msg.error .glyph {
1418
+ color: var(--c-err);
1419
+ }
1420
+
1421
+ .chat-msg.user .body {
1422
+ color: var(--fg-0);
1423
+ }
1424
+ .chat-msg.assistant .body {
1425
+ color: var(--fg-0);
1426
+ }
1427
+ /* Tool-card replaces the simple .body box for role="tool" rows. The
1428
+ * card carries a left accent bar (amber for success), a header with
1429
+ * tool name + path/lang pills, then the kind-specific body (diff for
1430
+ * edit_file, code block for read/write_file, terminal for run_command,
1431
+ * etc). Keeps the visual weight consistent across kinds. */
1432
+ .tool-card {
1433
+ flex: 1;
1434
+ background: var(--bg-elev);
1435
+ border: 1px solid var(--bd);
1436
+ border-left: 3px solid var(--c-warn);
1437
+ border-radius: var(--r-md);
1438
+ padding: 10px 12px;
1439
+ min-width: 0;
1440
+ }
1441
+ .tool-card-head {
1442
+ display: flex;
1443
+ align-items: center;
1444
+ gap: 8px;
1445
+ margin-bottom: 8px;
1446
+ font-family: var(--font-mono);
1447
+ font-size: 12px;
1448
+ flex-wrap: wrap;
1449
+ }
1450
+ .tool-card-icon {
1451
+ color: var(--c-warn);
1452
+ font-size: 14px;
1453
+ font-weight: 600;
1454
+ }
1455
+ .tool-card-name {
1456
+ color: var(--c-accent);
1457
+ font-weight: 500;
1458
+ }
1459
+ .tool-card-path {
1460
+ color: var(--c-brand);
1461
+ background: var(--bg-elev-2);
1462
+ padding: 1px 8px;
1463
+ border-radius: var(--r);
1464
+ font-size: 11px;
1465
+ }
1466
+ .tool-card pre,
1467
+ .tool-card .md {
1468
+ margin: 0;
1469
+ }
1470
+ .tool-card .md > pre,
1471
+ .tool-card-cmd,
1472
+ .tool-card-output {
1473
+ background: var(--bg-elev-2);
1474
+ border: 1px solid var(--bd);
1475
+ border-radius: var(--r);
1476
+ padding: 8px 10px;
1477
+ font-family: var(--font-mono);
1478
+ font-size: 12px;
1479
+ line-height: 1.55;
1480
+ max-height: 320px;
1481
+ overflow: auto;
1482
+ }
1483
+ .tool-card .md > pre code {
1484
+ background: transparent;
1485
+ padding: 0;
1486
+ color: inherit;
1487
+ }
1488
+ .tool-card .diff-block {
1489
+ margin: 0;
1490
+ max-height: 320px;
1491
+ }
1492
+ .tool-card-cmd {
1493
+ background: var(--bg);
1494
+ white-space: pre;
1495
+ margin: 0 0 6px 0;
1496
+ }
1497
+ .tool-card-prompt {
1498
+ color: var(--fg-3);
1499
+ margin-right: 6px;
1500
+ }
1501
+ .tool-card-output {
1502
+ white-space: pre-wrap;
1503
+ word-break: break-word;
1504
+ color: var(--fg-1);
1505
+ margin: 0;
1506
+ }
1507
+ .tool-card-result {
1508
+ margin-top: 6px;
1509
+ font-size: 11px;
1510
+ color: var(--fg-3);
1511
+ font-family: var(--font-mono);
1512
+ }
1513
+ .tool-card-args {
1514
+ margin-bottom: 6px;
1515
+ font-size: 11px;
1516
+ }
1517
+ .tool-card-args summary {
1518
+ cursor: pointer;
1519
+ color: var(--fg-2);
1520
+ }
1521
+ .tool-card-args summary:hover {
1522
+ color: var(--c-brand);
1523
+ }
1524
+ .tool-card-args pre {
1525
+ margin-top: 6px;
1526
+ white-space: pre;
1527
+ }
1528
+
1529
+ .chat-msg .reasoning {
1530
+ margin-top: 6px;
1531
+ padding: 6px 10px;
1532
+ background: var(--bg-elev);
1533
+ border-left: 2px solid var(--c-accent);
1534
+ color: var(--fg-2);
1535
+ font-size: 12px;
1536
+ font-style: italic;
1537
+ white-space: pre-wrap;
1538
+ word-break: break-word;
1539
+ border-radius: var(--r);
1540
+ }
1541
+
1542
+ .chat-msg .tool-name {
1543
+ color: var(--c-accent);
1544
+ font-weight: 500;
1545
+ }
1546
+
1547
+ .chat-streaming-cursor {
1548
+ display: inline-block;
1549
+ width: 7px;
1550
+ height: 14px;
1551
+ background: var(--c-brand);
1552
+ margin-left: 2px;
1553
+ vertical-align: middle;
1554
+ animation: blink 1s steps(1) infinite;
1555
+ }
1556
+
1557
+ @keyframes blink {
1558
+ 50% {
1559
+ opacity: 0;
1560
+ }
1561
+ }
1562
+
1563
+ .chat-input-area {
1564
+ display: flex;
1565
+ gap: 10px;
1566
+ padding-top: 12px;
1567
+ border-top: 1px solid var(--bd);
1568
+ flex-shrink: 0;
1569
+ }
1570
+
1571
+ .chat-input-area textarea {
1572
+ flex: 1;
1573
+ background: var(--bg-elev-2);
1574
+ border: 1px solid var(--bd);
1575
+ color: var(--fg-0);
1576
+ padding: 8px 12px;
1577
+ border-radius: var(--r-md);
1578
+ font-family: var(--font-mono);
1579
+ font-size: 13px;
1580
+ resize: vertical;
1581
+ min-height: 44px;
1582
+ max-height: 200px;
1583
+ }
1584
+
1585
+ .chat-input-area textarea:focus {
1586
+ border-color: var(--c-brand);
1587
+ outline: none;
1588
+ }
1589
+
1590
+ .chat-input-area textarea:disabled {
1591
+ opacity: 0.5;
1592
+ cursor: not-allowed;
1593
+ }
1594
+
1595
+ .chat-empty {
1596
+ margin: auto;
1597
+ text-align: center;
1598
+ color: var(--fg-3);
1599
+ font-family: var(--font-mono);
1600
+ font-size: 13px;
1601
+ padding: 40px 20px;
1602
+ }
1603
+
1604
+ .chat-status {
1605
+ display: flex;
1606
+ align-items: center;
1607
+ gap: 8px;
1608
+ margin-bottom: 12px;
1609
+ font-size: 12px;
1610
+ color: var(--fg-2);
1611
+ }
1612
+
1613
+ /* Onboarding banner that nudges new users to the Semantic panel.
1614
+ * Only shown when the project has no built index AND the user hasn't
1615
+ * explicitly dismissed it (state in localStorage). The "Build it →"
1616
+ * action navigates the sidebar via the appBus so the rest of the
1617
+ * panel state isn't disturbed. */
1618
+ .chat-banner {
1619
+ display: flex;
1620
+ align-items: center;
1621
+ gap: 12px;
1622
+ margin-bottom: 14px;
1623
+ padding: 10px 14px;
1624
+ background: var(--bg-elev);
1625
+ border: 1px solid var(--bd);
1626
+ border-left: 3px solid var(--c-accent);
1627
+ border-radius: var(--r-md);
1628
+ font-size: 13px;
1629
+ }
1630
+ .chat-banner-icon {
1631
+ font-family: var(--font-mono);
1632
+ color: var(--c-accent);
1633
+ font-size: 18px;
1634
+ }
1635
+ .chat-banner-text {
1636
+ flex: 1;
1637
+ display: flex;
1638
+ flex-direction: column;
1639
+ gap: 2px;
1640
+ font-size: 13px;
1641
+ }
1642
+ .chat-banner-text strong {
1643
+ color: var(--fg-0);
1644
+ font-weight: 600;
1645
+ }
1646
+ .chat-banner-text .muted {
1647
+ font-size: 12px;
1648
+ line-height: 1.45;
1649
+ }
1650
+ .chat-banner-close {
1651
+ background: transparent;
1652
+ border: none;
1653
+ color: var(--fg-3);
1654
+ font-size: 20px;
1655
+ line-height: 1;
1656
+ padding: 0 6px;
1657
+ cursor: pointer;
1658
+ border-radius: var(--r);
1659
+ }
1660
+ .chat-banner-close:hover {
1661
+ background: var(--bg-input);
1662
+ color: var(--fg-0);
1663
+ }
1664
+
1665
+ /* In-flight row sits just above ChatStatusBar — the user's eyes are
1666
+ * already at the input; this puts the spinner + elapsed + token
1667
+ * stream in the same visual neighborhood instead of pushing them up
1668
+ * to the top of the panel. Border on the bottom only so it shares the
1669
+ * statusbar's top divider. */
1670
+ .chat-inflight {
1671
+ display: flex;
1672
+ flex-wrap: wrap;
1673
+ align-items: center;
1674
+ gap: 8px;
1675
+ padding: 7px 8px;
1676
+ margin-top: 6px;
1677
+ background: var(--bg-elev);
1678
+ border: 1px solid var(--bd);
1679
+ border-radius: var(--r);
1680
+ font-family: var(--font-mono);
1681
+ font-size: 12px;
1682
+ color: var(--fg-1);
1683
+ flex-shrink: 0;
1684
+ }
1685
+ .chat-inflight-phase {
1686
+ color: var(--c-accent);
1687
+ font-weight: 600;
1688
+ }
1689
+ .chat-inflight-sep {
1690
+ color: var(--fg-3);
1691
+ }
1692
+ .chat-inflight-tool {
1693
+ color: var(--fg-1);
1694
+ white-space: nowrap;
1695
+ overflow: hidden;
1696
+ text-overflow: ellipsis;
1697
+ max-width: 480px;
1698
+ }
1699
+ .chat-inflight-abort {
1700
+ margin-left: auto;
1701
+ background: transparent;
1702
+ border: 1px solid var(--bd);
1703
+ color: var(--fg-2);
1704
+ padding: 3px 10px;
1705
+ border-radius: var(--r);
1706
+ font-family: inherit;
1707
+ font-size: 11px;
1708
+ cursor: pointer;
1709
+ }
1710
+ .chat-inflight-abort:hover {
1711
+ border-color: var(--c-err);
1712
+ color: var(--c-err);
1713
+ }
1714
+
1715
+ /* ---------- Chat status bar ----------
1716
+ *
1717
+ * Compact metric strip below the input area. Mirrors the TUI's
1718
+ * StatsPanel (model · ctx · cache · turn $ · session $ · balance) so
1719
+ * the user has the same one-glance read-out without leaving Chat.
1720
+ */
1721
+ .chat-statusbar {
1722
+ display: flex;
1723
+ flex-wrap: wrap;
1724
+ gap: 16px;
1725
+ padding: 8px 4px 0;
1726
+ margin-top: 8px;
1727
+ border-top: 1px solid var(--bd);
1728
+ font-family: var(--font-mono);
1729
+ font-size: 11px;
1730
+ color: var(--fg-2);
1731
+ flex-shrink: 0;
1732
+ }
1733
+ .status-item {
1734
+ display: inline-flex;
1735
+ align-items: center;
1736
+ gap: 6px;
1737
+ }
1738
+ .status-label {
1739
+ color: var(--fg-3);
1740
+ font-size: 10px;
1741
+ letter-spacing: 0.06em;
1742
+ text-transform: uppercase;
1743
+ }
1744
+ .status-bar-mini {
1745
+ display: inline-block;
1746
+ width: 60px;
1747
+ height: 4px;
1748
+ background: var(--bg-input);
1749
+ border-radius: 2px;
1750
+ overflow: hidden;
1751
+ }
1752
+ .status-bar-mini-fill {
1753
+ display: block;
1754
+ height: 100%;
1755
+ background: var(--gradient-rule);
1756
+ }
1757
+ .status-ok {
1758
+ color: var(--c-ok);
1759
+ }
1760
+ .status-warn {
1761
+ color: var(--c-warn);
1762
+ }
1763
+ .status-err {
1764
+ color: var(--c-err);
1765
+ }
1766
+
1767
+ /* ---------- Header pickers (effort / preset / edit-mode) ----------
1768
+ *
1769
+ * Three segmented controls that flow on the chat header right side.
1770
+ * On narrow screens they wrap onto multiple rows. The `accent` variant
1771
+ * paints active segments violet (preset / effort) instead of cyan
1772
+ * (edit-mode), so the three picker groups remain visually distinct.
1773
+ */
1774
+ .header-pickers {
1775
+ display: flex;
1776
+ gap: 8px;
1777
+ flex-wrap: wrap;
1778
+ justify-content: flex-end;
1779
+ }
1780
+
1781
+ .mode-picker {
1782
+ display: inline-flex;
1783
+ border: 1px solid var(--bd);
1784
+ border-radius: var(--r-md);
1785
+ overflow: hidden;
1786
+ background: var(--bg-elev);
1787
+ }
1788
+ .mode-btn {
1789
+ background: transparent;
1790
+ border: none;
1791
+ border-radius: 0;
1792
+ padding: 4px 12px;
1793
+ font-family: var(--font-mono);
1794
+ font-size: 11px;
1795
+ letter-spacing: 0.05em;
1796
+ text-transform: uppercase;
1797
+ color: var(--fg-2);
1798
+ cursor: pointer;
1799
+ transition: color 0.12s, background 0.12s;
1800
+ }
1801
+ .mode-btn + .mode-btn {
1802
+ border-left: 1px solid var(--bd);
1803
+ }
1804
+ .mode-btn:hover {
1805
+ background: var(--bg-elev-2);
1806
+ color: var(--fg-0);
1807
+ }
1808
+ .mode-btn.active {
1809
+ background: var(--c-brand);
1810
+ color: var(--bg);
1811
+ font-weight: 600;
1812
+ }
1813
+ .mode-btn.active.accent {
1814
+ background: var(--c-accent);
1815
+ color: var(--bg);
1816
+ }
1817
+ .mode-btn.active.yolo {
1818
+ background: var(--c-err);
1819
+ color: var(--bg);
1820
+ }
1821
+
1822
+ /* ---------- Modal cards (shell / choice / plan / edit-review) ----------
1823
+ *
1824
+ * Mirrors the TUI's ModalCard shape — left-accent border in the modal
1825
+ * kind's color (red shell, magenta choice, cyan plan, green edits)
1826
+ * with an icon, title, optional subtitle, then content + actions. The
1827
+ * card sits above the chat input area, full-width within the chat
1828
+ * column. Styled minimal so it doesn't compete with conversation
1829
+ * content for attention.
1830
+ */
1831
+
1832
+ .modal-card {
1833
+ margin: 12px 0;
1834
+ background: var(--bg-elev);
1835
+ border: 1px solid var(--bd);
1836
+ border-left: 3px solid var(--c-accent);
1837
+ border-radius: var(--r-md);
1838
+ padding: 14px 16px;
1839
+ display: flex;
1840
+ flex-direction: column;
1841
+ gap: 12px;
1842
+ }
1843
+
1844
+ .modal-card-head {
1845
+ display: flex;
1846
+ gap: 12px;
1847
+ align-items: flex-start;
1848
+ }
1849
+
1850
+ .modal-card-icon {
1851
+ font-size: 18px;
1852
+ font-family: var(--font-mono);
1853
+ line-height: 1.4;
1854
+ }
1855
+
1856
+ .modal-card-title {
1857
+ font-size: 14px;
1858
+ font-weight: 600;
1859
+ color: var(--fg-0);
1860
+ }
1861
+
1862
+ .modal-card-subtitle {
1863
+ font-size: 12px;
1864
+ color: var(--fg-2);
1865
+ margin-top: 2px;
1866
+ }
1867
+
1868
+ .modal-cmd {
1869
+ background: var(--bg-elev-2);
1870
+ border-radius: var(--r);
1871
+ padding: 8px 12px;
1872
+ font-family: var(--font-mono);
1873
+ font-size: 13px;
1874
+ overflow-x: auto;
1875
+ max-height: 240px;
1876
+ overflow-y: auto;
1877
+ white-space: pre-wrap;
1878
+ word-break: break-all;
1879
+ }
1880
+ .modal-cmd-prompt {
1881
+ color: var(--fg-3);
1882
+ margin-right: 6px;
1883
+ }
1884
+ .modal-cmd code {
1885
+ color: var(--c-brand);
1886
+ background: transparent;
1887
+ padding: 0;
1888
+ word-break: break-all;
1889
+ }
1890
+
1891
+ .modal-actions {
1892
+ display: flex;
1893
+ gap: 8px;
1894
+ flex-wrap: wrap;
1895
+ }
1896
+
1897
+ .modal-choice-row {
1898
+ display: grid;
1899
+ grid-template-columns: 28px 1fr;
1900
+ grid-template-rows: auto auto;
1901
+ gap: 2px 12px;
1902
+ background: transparent;
1903
+ border: 1px solid var(--bd);
1904
+ border-radius: var(--r);
1905
+ padding: 8px 12px;
1906
+ text-align: left;
1907
+ cursor: pointer;
1908
+ transition: border-color 0.12s, background 0.12s;
1909
+ }
1910
+ .modal-choice-row:hover {
1911
+ border-color: var(--c-accent);
1912
+ background: rgba(196, 181, 253, 0.06);
1913
+ }
1914
+ .modal-choice-row.modal-choice-cancel {
1915
+ margin-top: 4px;
1916
+ border-style: dashed;
1917
+ }
1918
+ .modal-choice-id {
1919
+ grid-row: 1 / 3;
1920
+ align-self: center;
1921
+ font-family: var(--font-mono);
1922
+ font-size: 14px;
1923
+ color: var(--c-accent);
1924
+ font-weight: 600;
1925
+ text-align: center;
1926
+ }
1927
+ .modal-choice-title {
1928
+ color: var(--fg-0);
1929
+ font-size: 13px;
1930
+ font-weight: 500;
1931
+ }
1932
+ .modal-choice-summary {
1933
+ color: var(--fg-2);
1934
+ font-size: 12px;
1935
+ grid-column: 2;
1936
+ }
1937
+
1938
+ .modal-custom textarea {
1939
+ width: 100%;
1940
+ background: var(--bg-elev-2);
1941
+ border: 1px solid var(--bd);
1942
+ color: var(--fg-0);
1943
+ padding: 8px 12px;
1944
+ border-radius: var(--r);
1945
+ font-family: var(--font-mono);
1946
+ font-size: 13px;
1947
+ resize: vertical;
1948
+ min-height: 56px;
1949
+ }
1950
+
1951
+ .modal-plan-body {
1952
+ background: var(--bg-elev-2);
1953
+ border-radius: var(--r);
1954
+ padding: 12px 14px;
1955
+ max-height: 320px;
1956
+ overflow-y: auto;
1957
+ }
1958
+
1959
+ /* Plan-revision modal — list of remaining steps with risk dots. */
1960
+ .modal-revise-reason {
1961
+ background: var(--bg-elev-2);
1962
+ border-left: 3px solid #c4b5fd;
1963
+ border-radius: 0 var(--r) var(--r) 0;
1964
+ padding: 8px 12px;
1965
+ color: var(--fg-1);
1966
+ font-size: 13px;
1967
+ white-space: pre-wrap;
1968
+ }
1969
+ .modal-revise-steps {
1970
+ list-style: none;
1971
+ margin: 0;
1972
+ padding: 0;
1973
+ display: flex;
1974
+ flex-direction: column;
1975
+ gap: 6px;
1976
+ max-height: 280px;
1977
+ overflow-y: auto;
1978
+ }
1979
+ .modal-revise-steps li {
1980
+ display: grid;
1981
+ grid-template-columns: 12px 64px 1fr;
1982
+ grid-template-rows: auto auto;
1983
+ gap: 2px 10px;
1984
+ background: var(--bg-elev-2);
1985
+ border: 1px solid var(--bd);
1986
+ border-radius: var(--r);
1987
+ padding: 8px 12px;
1988
+ align-items: center;
1989
+ }
1990
+ .modal-revise-dot {
1991
+ grid-row: 1 / 3;
1992
+ width: 8px;
1993
+ height: 8px;
1994
+ border-radius: 50%;
1995
+ align-self: center;
1996
+ }
1997
+ .modal-revise-id {
1998
+ grid-row: 1;
1999
+ font-family: var(--font-mono);
2000
+ font-size: 12px;
2001
+ color: var(--fg-2);
2002
+ }
2003
+ .modal-revise-title {
2004
+ grid-row: 1;
2005
+ color: var(--fg-0);
2006
+ font-size: 13px;
2007
+ font-weight: 500;
2008
+ }
2009
+ .modal-revise-action {
2010
+ grid-column: 2 / 4;
2011
+ grid-row: 2;
2012
+ color: var(--fg-2);
2013
+ font-size: 12px;
2014
+ white-space: pre-wrap;
2015
+ }
2016
+
2017
+ .modal-edit-preview {
2018
+ background: var(--bg-elev-2);
2019
+ border: 1px solid var(--bd);
2020
+ border-radius: var(--r);
2021
+ padding: 10px 12px;
2022
+ margin: 0;
2023
+ font-family: var(--font-mono);
2024
+ font-size: 12px;
2025
+ color: var(--fg-1);
2026
+ white-space: pre;
2027
+ overflow-x: auto;
2028
+ max-height: 200px;
2029
+ }
2030
+
2031
+ .modal-picker-search {
2032
+ width: 100%;
2033
+ background: var(--bg-elev-2);
2034
+ border: 1px solid var(--bd);
2035
+ border-radius: var(--r);
2036
+ color: var(--fg-1);
2037
+ padding: 6px 10px;
2038
+ font-size: 13px;
2039
+ margin-bottom: 8px;
2040
+ }
2041
+
2042
+ .modal-picker-list {
2043
+ display: flex;
2044
+ flex-direction: column;
2045
+ gap: 2px;
2046
+ max-height: 320px;
2047
+ overflow-y: auto;
2048
+ border: 1px solid var(--bd);
2049
+ border-radius: var(--r);
2050
+ background: var(--bg-elev-2);
2051
+ padding: 4px;
2052
+ margin-bottom: 8px;
2053
+ }
2054
+
2055
+ .modal-picker-row {
2056
+ display: grid;
2057
+ grid-template-columns: 1fr auto;
2058
+ gap: 4px 8px;
2059
+ align-items: baseline;
2060
+ padding: 6px 8px;
2061
+ background: transparent;
2062
+ border: 1px solid transparent;
2063
+ border-radius: var(--r-sm, 4px);
2064
+ color: var(--fg-1);
2065
+ text-align: left;
2066
+ cursor: pointer;
2067
+ }
2068
+
2069
+ .modal-picker-row:hover {
2070
+ background: var(--bg-elev-3, var(--bg-elev-2));
2071
+ }
2072
+
2073
+ .modal-picker-row.selected {
2074
+ border-color: var(--c-accent);
2075
+ background: var(--bg-elev-3, var(--bg-elev-2));
2076
+ }
2077
+
2078
+ .modal-picker-title {
2079
+ grid-column: 1;
2080
+ font-weight: 500;
2081
+ }
2082
+
2083
+ .modal-picker-badge {
2084
+ grid-column: 2;
2085
+ font-size: 11px;
2086
+ color: var(--fg-2);
2087
+ padding: 1px 6px;
2088
+ border-radius: 999px;
2089
+ background: var(--bg-elev);
2090
+ }
2091
+
2092
+ .modal-picker-subtitle {
2093
+ grid-column: 1 / 3;
2094
+ font-size: 12px;
2095
+ color: var(--fg-2);
2096
+ }
2097
+
2098
+ .modal-picker-meta {
2099
+ grid-column: 1 / 3;
2100
+ font-size: 11px;
2101
+ color: var(--fg-3, var(--fg-2));
2102
+ }
2103
+
2104
+ .modal-picker-empty {
2105
+ padding: 16px;
2106
+ text-align: center;
2107
+ color: var(--fg-2);
2108
+ font-size: 12px;
2109
+ }
2110
+
2111
+ .modal-picker-more {
2112
+ align-self: center;
2113
+ margin: 0 auto 8px;
2114
+ font-size: 12px;
2115
+ }
2116
+
2117
+ .modal-picker-form {
2118
+ display: flex;
2119
+ flex-direction: column;
2120
+ gap: 8px;
2121
+ margin-bottom: 8px;
2122
+ }
2123
+
2124
+ .modal-picker-form input {
2125
+ width: 100%;
2126
+ background: var(--bg-elev-2);
2127
+ border: 1px solid var(--bd);
2128
+ border-radius: var(--r);
2129
+ color: var(--fg-1);
2130
+ padding: 6px 10px;
2131
+ font-size: 13px;
2132
+ }
2133
+
2134
+ .modal-viewer-steps {
2135
+ list-style: none;
2136
+ padding: 0;
2137
+ margin: 0 0 8px;
2138
+ display: flex;
2139
+ flex-direction: column;
2140
+ gap: 4px;
2141
+ }
2142
+
2143
+ .modal-viewer-step {
2144
+ display: grid;
2145
+ grid-template-columns: 18px 1fr;
2146
+ gap: 6px;
2147
+ padding: 4px 8px;
2148
+ border-radius: var(--r-sm, 4px);
2149
+ background: var(--bg-elev-2);
2150
+ align-items: baseline;
2151
+ }
2152
+
2153
+ .modal-viewer-step-mark {
2154
+ text-align: center;
2155
+ font-weight: 600;
2156
+ color: var(--fg-2);
2157
+ }
2158
+
2159
+ .modal-viewer-step-done .modal-viewer-step-mark {
2160
+ color: #86efac;
2161
+ }
2162
+
2163
+ .modal-viewer-step-title {
2164
+ color: var(--fg-1);
2165
+ font-size: 13px;
2166
+ }
2167
+
2168
+ .modal-viewer-step-done .modal-viewer-step-title {
2169
+ color: var(--fg-2);
2170
+ }
2171
+
2172
+ .modal-viewer-body {
2173
+ margin-top: 4px;
2174
+ font-size: 13px;
2175
+ color: var(--fg-1);
2176
+ max-height: 360px;
2177
+ overflow-y: auto;
2178
+ }
2179
+
2180
+ /* Side-by-side diff for the edit-review modal — left is "before" (red
2181
+ * tint), right is "after" (green tint), context rows render unchanged.
2182
+ * Lines hljs-highlight per the file's language. */
2183
+ .edit-diff-wrap {
2184
+ border: 1px solid var(--bd);
2185
+ border-radius: var(--r);
2186
+ background: var(--bg-elev-2);
2187
+ font-family: var(--font-mono);
2188
+ font-size: 12px;
2189
+ overflow: hidden;
2190
+ max-height: 60vh;
2191
+ display: flex;
2192
+ flex-direction: column;
2193
+ }
2194
+ .edit-diff-head {
2195
+ display: flex;
2196
+ background: var(--bg-elev);
2197
+ border-bottom: 1px solid var(--bd);
2198
+ font-size: 11px;
2199
+ text-transform: uppercase;
2200
+ letter-spacing: 0.06em;
2201
+ color: var(--fg-3);
2202
+ flex-shrink: 0;
2203
+ }
2204
+ .edit-diff-side {
2205
+ flex: 1;
2206
+ padding: 6px 12px;
2207
+ }
2208
+ .edit-diff-side + .edit-diff-side {
2209
+ border-left: 1px solid var(--bd);
2210
+ }
2211
+ .edit-diff-side-old .edit-diff-marker {
2212
+ color: #f87171;
2213
+ font-weight: 700;
2214
+ margin-right: 4px;
2215
+ }
2216
+ .edit-diff-side-new .edit-diff-marker {
2217
+ color: #86efac;
2218
+ font-weight: 700;
2219
+ margin-right: 4px;
2220
+ }
2221
+ .edit-diff-body {
2222
+ flex: 1;
2223
+ overflow-y: auto;
2224
+ overflow-x: auto;
2225
+ }
2226
+ .edit-diff-row {
2227
+ display: flex;
2228
+ width: 100%;
2229
+ align-items: stretch;
2230
+ min-height: 19px;
2231
+ }
2232
+ .edit-diff-cell {
2233
+ flex: 1;
2234
+ padding: 1px 12px;
2235
+ white-space: pre;
2236
+ overflow-x: auto;
2237
+ border-right: 1px solid var(--bd);
2238
+ color: var(--fg-1);
2239
+ line-height: 1.55;
2240
+ }
2241
+ .edit-diff-cell:last-child {
2242
+ border-right: none;
2243
+ }
2244
+ .edit-diff-row-context .edit-diff-cell {
2245
+ background: transparent;
2246
+ color: var(--fg-2);
2247
+ }
2248
+ .edit-diff-row-del .edit-diff-cell-old,
2249
+ .edit-diff-row-change .edit-diff-cell-old {
2250
+ background: rgba(248, 113, 113, 0.12);
2251
+ border-left: 2px solid #f87171;
2252
+ padding-left: 10px;
2253
+ }
2254
+ .edit-diff-row-ins .edit-diff-cell-new,
2255
+ .edit-diff-row-change .edit-diff-cell-new {
2256
+ background: rgba(134, 239, 172, 0.12);
2257
+ border-left: 2px solid #86efac;
2258
+ padding-left: 10px;
2259
+ }
2260
+ .edit-diff-cell-old .edit-diff-empty,
2261
+ .edit-diff-cell-new .edit-diff-empty {
2262
+ display: inline-block;
2263
+ width: 1px;
2264
+ }
2265
+ .edit-diff-row-del .edit-diff-cell-new,
2266
+ .edit-diff-row-ins .edit-diff-cell-old {
2267
+ background: var(--bg-input);
2268
+ opacity: 0.5;
2269
+ }
2270
+ .edit-diff-line {
2271
+ font-family: var(--font-mono);
2272
+ }
2273
+
2274
+ @media (max-width: 800px) {
2275
+ .edit-diff-row {
2276
+ flex-direction: column;
2277
+ }
2278
+ .edit-diff-cell {
2279
+ border-right: none;
2280
+ border-bottom: 1px solid var(--bd);
2281
+ }
2282
+ .edit-diff-head {
2283
+ flex-direction: column;
2284
+ }
2285
+ .edit-diff-side + .edit-diff-side {
2286
+ border-left: none;
2287
+ border-top: 1px solid var(--bd);
2288
+ }
2289
+ }
2290
+
2291
+ .muted {
2292
+ color: var(--fg-3);
2293
+ }
2294
+
2295
+ /* ---------- Toast ----------
2296
+ * Ephemeral notifications stacked bottom-right of the viewport. Fired
2297
+ * by save / network success paths instead of inline banners that push
2298
+ * the form around. Auto-dismiss after 3 seconds. */
2299
+ .toast-stack {
2300
+ position: fixed;
2301
+ bottom: 20px;
2302
+ right: 20px;
2303
+ display: flex;
2304
+ flex-direction: column;
2305
+ gap: 8px;
2306
+ z-index: 50;
2307
+ pointer-events: none;
2308
+ }
2309
+ .toast {
2310
+ pointer-events: auto;
2311
+ background: var(--bg-elev);
2312
+ border: 1px solid var(--bd);
2313
+ border-left: 3px solid var(--c-ok);
2314
+ border-radius: var(--r-md);
2315
+ padding: 10px 14px;
2316
+ font-size: 13px;
2317
+ color: var(--fg-0);
2318
+ font-family: var(--font-sans);
2319
+ min-width: 200px;
2320
+ max-width: 360px;
2321
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
2322
+ animation: toast-slide-in 0.18s ease-out;
2323
+ }
2324
+ .toast.warn {
2325
+ border-left-color: var(--c-warn);
2326
+ }
2327
+ .toast.err {
2328
+ border-left-color: var(--c-err);
2329
+ }
2330
+ .toast.info {
2331
+ border-left-color: var(--c-accent);
2332
+ }
2333
+
2334
+ /* ---------- Error overlay ----------
2335
+ *
2336
+ * Full-screen modal triggered by uncaught exceptions / promise
2337
+ * rejections / Preact render errors. The TUI is unaffected — this
2338
+ * only blocks the browser tab. Includes "Copy details" + a GitHub
2339
+ * issue link prefilled with redacted environment info.
2340
+ */
2341
+ .error-overlay {
2342
+ position: fixed;
2343
+ inset: 0;
2344
+ background: rgba(10, 14, 20, 0.85);
2345
+ backdrop-filter: blur(4px);
2346
+ display: flex;
2347
+ align-items: center;
2348
+ justify-content: center;
2349
+ padding: 32px;
2350
+ z-index: 100;
2351
+ animation: fade-in 0.18s ease-out;
2352
+ }
2353
+ .error-overlay-card {
2354
+ max-width: 720px;
2355
+ width: 100%;
2356
+ max-height: 85vh;
2357
+ overflow-y: auto;
2358
+ background: var(--bg-elev);
2359
+ border: 1px solid var(--c-err);
2360
+ border-left: 4px solid var(--c-err);
2361
+ border-radius: var(--r-md);
2362
+ padding: 22px 26px;
2363
+ box-shadow: 0 12px 60px rgba(248, 113, 113, 0.18);
2364
+ }
2365
+ .error-overlay-head {
2366
+ display: flex;
2367
+ gap: 14px;
2368
+ align-items: flex-start;
2369
+ margin-bottom: 16px;
2370
+ }
2371
+ .error-overlay-icon {
2372
+ color: var(--c-err);
2373
+ font-size: 22px;
2374
+ font-weight: 700;
2375
+ }
2376
+ .error-overlay-title {
2377
+ font-size: 16px;
2378
+ font-weight: 600;
2379
+ color: var(--fg-0);
2380
+ }
2381
+ .error-overlay-subtitle {
2382
+ font-size: 13px;
2383
+ color: var(--fg-2);
2384
+ font-family: var(--font-mono);
2385
+ margin-top: 4px;
2386
+ word-break: break-word;
2387
+ }
2388
+ .error-overlay-trace {
2389
+ background: var(--bg-elev-2);
2390
+ border: 1px solid var(--bd);
2391
+ border-radius: var(--r);
2392
+ padding: 12px 14px;
2393
+ font-family: var(--font-mono);
2394
+ font-size: 12px;
2395
+ line-height: 1.55;
2396
+ color: var(--fg-1);
2397
+ white-space: pre-wrap;
2398
+ word-break: break-word;
2399
+ max-height: 280px;
2400
+ overflow-y: auto;
2401
+ margin: 0 0 12px;
2402
+ }
2403
+ .error-overlay-info {
2404
+ font-size: 12px;
2405
+ font-family: var(--font-mono);
2406
+ color: var(--fg-2);
2407
+ margin-bottom: 12px;
2408
+ }
2409
+ .error-overlay-help {
2410
+ font-size: 13px;
2411
+ color: var(--fg-1);
2412
+ margin-bottom: 18px;
2413
+ line-height: 1.55;
2414
+ }
2415
+ .error-overlay-actions {
2416
+ display: flex;
2417
+ gap: 8px;
2418
+ flex-wrap: wrap;
2419
+ align-items: center;
2420
+ }
2421
+ .error-overlay-actions a.button {
2422
+ display: inline-block;
2423
+ text-decoration: none;
2424
+ background: var(--bg-elev-2);
2425
+ color: var(--fg-1);
2426
+ border: 1px solid var(--bd);
2427
+ border-radius: var(--r);
2428
+ padding: 6px 12px;
2429
+ font-family: var(--font-sans);
2430
+ font-size: 12px;
2431
+ }
2432
+ .error-overlay-actions a.button:hover {
2433
+ border-color: var(--c-brand);
2434
+ color: var(--c-brand);
2435
+ }
2436
+
2437
+ .changes-layout {
2438
+ display: flex;
2439
+ flex-direction: row;
2440
+ height: 100%;
2441
+ overflow: hidden;
2442
+ }
2443
+
2444
+ .app-body.changes-active {
2445
+ padding: 0;
2446
+ overflow: hidden;
2447
+ }
2448
+
2449
+ .changes-panel {
2450
+ display: flex;
2451
+ flex-direction: column;
2452
+ min-width: 200px;
2453
+ overflow: hidden;
2454
+ background: var(--bg-elev);
2455
+ border: 1px solid var(--bd);
2456
+ border-radius: var(--r);
2457
+ }
2458
+
2459
+ .changes-panel-left {
2460
+ width: 30%;
2461
+ }
2462
+
2463
+ .changes-panel-center {
2464
+ flex: 1;
2465
+ min-width: 0;
2466
+ }
2467
+
2468
+ .changes-panel-right {
2469
+ width: 30%;
2470
+ }
2471
+
2472
+ .changes-panel-header {
2473
+ display: flex;
2474
+ align-items: center;
2475
+ gap: 8px;
2476
+ padding: 8px 12px;
2477
+ border-bottom: 1px solid var(--bd);
2478
+ font-family: var(--font-mono);
2479
+ font-size: 10.5px;
2480
+ color: var(--fg-3);
2481
+ text-transform: uppercase;
2482
+ letter-spacing: .1em;
2483
+ flex-shrink: 0;
2484
+ background: var(--bg-elev);
2485
+ }
2486
+
2487
+ .changes-panel-header .glyph {
2488
+ color: var(--c-brand);
2489
+ font-size: 12px;
2490
+ }
2491
+
2492
+ .changes-panel-body {
2493
+ flex: 1;
2494
+ overflow-y: auto;
2495
+ min-height: 0;
2496
+ }
2497
+
2498
+ @media (max-width: 899px) {
2499
+ .changes-layout {
2500
+ flex-direction: column;
2501
+ }
2502
+ .changes-panel {
2503
+ min-width: 0;
2504
+ min-height: 180px;
2505
+ }
2506
+ .changes-panel-left,
2507
+ .changes-panel-right {
2508
+ width: 100%;
2509
+ max-height: 40vh;
2510
+ }
2511
+ .changes-panel-center {
2512
+ flex: 1;
2513
+ }
2514
+ .changes-layout .resize-handle {
2515
+ display: none;
2516
+ }
2517
+ }
2518
+
2519
+ /* ── Line Comment System ──────────────────────────────────────────── */
2520
+ .line-comment-anchor {
2521
+ width: 16px;
2522
+ height: 16px;
2523
+ display: flex;
2524
+ align-items: center;
2525
+ justify-content: center;
2526
+ opacity: 0;
2527
+ pointer-events: none;
2528
+ cursor: pointer;
2529
+ transition: opacity 0.15s ease;
2530
+ flex-shrink: 0;
2531
+ }
2532
+
2533
+ .editor-line:hover .line-comment-anchor.visible {
2534
+ opacity: 1;
2535
+ pointer-events: auto;
2536
+ }
2537
+
2538
+ .line-comment-anchor .plus-icon,
2539
+ .line-comment-anchor .comment-count {
2540
+ font-family: var(--font-mono);
2541
+ font-size: 14px;
2542
+ color: var(--fg-3);
2543
+ line-height: 1;
2544
+ }
2545
+
2546
+ .line-comment-anchor:hover .plus-icon,
2547
+ .line-comment-anchor:hover .comment-count {
2548
+ color: var(--c-brand);
2549
+ }
2550
+
2551
+ .line-comment-anchor .comment-count {
2552
+ background: rgba(121, 192, 255, 0.12);
2553
+ border-radius: var(--r);
2554
+ padding: 0 3px;
2555
+ font-size: 10px;
2556
+ color: var(--c-brand);
2557
+ }
2558
+
2559
+ .line-comment-editor {
2560
+ grid-column: 2;
2561
+ justify-self: stretch;
2562
+ min-width: 0;
2563
+ background: var(--bg-elev);
2564
+ border: 1px solid var(--bd-strong);
2565
+ border-radius: 6px;
2566
+ padding: 10px 12px;
2567
+ margin: 2px 0 4px 0;
2568
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
2569
+ display: flex;
2570
+ flex-direction: column;
2571
+ gap: 8px;
2572
+ }
2573
+
2574
+ .line-comment-bubble {
2575
+ grid-column: 2;
2576
+ justify-self: stretch;
2577
+ min-width: 0;
2578
+ background: var(--bg-elev);
2579
+ border: 1px solid var(--bd-strong);
2580
+ border-radius: 6px;
2581
+ padding: 10px 12px;
2582
+ margin: 2px 0 4px 0;
2583
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
2584
+ display: flex;
2585
+ flex-direction: column;
2586
+ gap: 8px;
2587
+ }
2588
+
2589
+ .line-comment-label {
2590
+ font-family: var(--font-mono);
2591
+ font-size: 10.5px;
2592
+ color: var(--fg-3);
2593
+ text-transform: uppercase;
2594
+ letter-spacing: .08em;
2595
+ }
2596
+
2597
+ .line-comment-textarea {
2598
+ background: var(--bg-input);
2599
+ border: 1px solid var(--bd);
2600
+ border-radius: var(--r);
2601
+ color: var(--fg-0);
2602
+ font-family: var(--font-mono);
2603
+ font-size: 12px;
2604
+ padding: 8px 10px;
2605
+ resize: vertical;
2606
+ min-height: 60px;
2607
+ outline: none;
2608
+ line-height: 1.5;
2609
+ width: 100%;
2610
+ box-sizing: border-box;
2611
+ }
2612
+
2613
+ .line-comment-textarea:focus {
2614
+ border-color: var(--c-brand);
2615
+ }
2616
+
2617
+ .line-comment-actions {
2618
+ display: flex;
2619
+ gap: 6px;
2620
+ justify-content: flex-end;
2621
+ }
2622
+
2623
+ .bubble-content {
2624
+ background: var(--bg-input);
2625
+ border: 1px solid var(--bd);
2626
+ border-radius: var(--r);
2627
+ color: var(--fg-0);
2628
+ font-family: var(--font-mono);
2629
+ font-size: 12px;
2630
+ padding: 8px 10px;
2631
+ min-height: 36px;
2632
+ line-height: 1.5;
2633
+ white-space: pre-wrap;
2634
+ word-break: break-word;
2635
+ box-sizing: border-box;
2636
+ }
2637
+
2638
+ .bubble-footer {
2639
+ display: flex;
2640
+ align-items: center;
2641
+ gap: 8px;
2642
+ font-family: var(--font-mono);
2643
+ font-size: 10px;
2644
+ color: var(--fg-3);
2645
+ }
2646
+
2647
+ .bubble-line {
2648
+ flex: 1;
2649
+ }
2650
+
2651
+ .bubble-actions {
2652
+ display: flex;
2653
+ gap: 4px;
2654
+ }
2655
+
2656
+ .bubble-btn {
2657
+ background: transparent;
2658
+ border: none;
2659
+ color: var(--fg-3);
2660
+ padding: 2px 6px;
2661
+ font-size: 10px;
2662
+ cursor: pointer;
2663
+ border-radius: var(--r);
2664
+ }
2665
+
2666
+ .bubble-btn:hover {
2667
+ background: var(--bg-hover);
2668
+ color: var(--fg-0);
2669
+ }
2670
+
2671
+ .bubble-btn.danger:hover {
2672
+ color: var(--c-err);
2673
+ }
2674
+
2675
+ .comment-card {
2676
+ display: inline-flex;
2677
+ align-items: center;
2678
+ gap: 8px;
2679
+ background: var(--bg-elev);
2680
+ border: 1px solid var(--bd);
2681
+ border-radius: 6px;
2682
+ padding: 6px 10px;
2683
+ font-family: var(--font-mono);
2684
+ font-size: 12px;
2685
+ color: var(--fg-2);
2686
+ cursor: default;
2687
+ min-width: 120px;
2688
+ }
2689
+
2690
+ .comment-card-icon {
2691
+ color: var(--c-brand);
2692
+ font-size: 12px;
2693
+ font-weight: bold;
2694
+ flex-shrink: 0;
2695
+ }
2696
+
2697
+ .comment-card-file {
2698
+ color: var(--c-brand);
2699
+ white-space: nowrap;
2700
+ }
2701
+
2702
+ .comment-card-content {
2703
+ color: var(--fg-1);
2704
+ font-size: 12px;
2705
+ line-height: 1.4;
2706
+ white-space: nowrap;
2707
+ overflow: hidden;
2708
+ text-overflow: ellipsis;
2709
+ }
2710
+
2711
+ .comment-card-remove {
2712
+ color: var(--fg-3);
2713
+ cursor: pointer;
2714
+ padding: 0 2px;
2715
+ font-size: 14px;
2716
+ line-height: 1;
2717
+ transition: color 0.15s ease;
2718
+ flex-shrink: 0;
2719
+ margin-left: auto;
2720
+ }
2721
+
2722
+ .comment-card-remove:hover {
2723
+ color: var(--c-err);
2724
+ }
2725
+
2726
+ /* ── File Tree Toggle ─────────────────────────────────────────────── */
2727
+ .file-tree-toggle {
2728
+ display: flex;
2729
+ gap: 0;
2730
+ padding: 6px 8px;
2731
+ border-bottom: 1px solid var(--bd);
2732
+ }
2733
+
2734
+ .toggle-btn {
2735
+ flex: 1;
2736
+ background: transparent;
2737
+ border: 1px solid var(--bd);
2738
+ color: var(--fg-3);
2739
+ padding: 4px 10px;
2740
+ font-family: var(--font-mono);
2741
+ font-size: 11px;
2742
+ cursor: pointer;
2743
+ text-align: center;
2744
+ transition: all 0.15s ease;
2745
+ }
2746
+
2747
+ .toggle-btn:first-child {
2748
+ border-radius: var(--r) 0 0 var(--r);
2749
+ border-right: none;
2750
+ }
2751
+
2752
+ .toggle-btn:last-child {
2753
+ border-radius: 0 var(--r) var(--r) 0;
2754
+ }
2755
+
2756
+ .toggle-btn:hover {
2757
+ background: var(--bg-hover);
2758
+ color: var(--fg-1);
2759
+ }
2760
+
2761
+ .toggle-btn.active {
2762
+ background: var(--bg-hover);
2763
+ color: var(--fg-0);
2764
+ border-color: var(--fg-4);
2765
+ }
2766
+
2767
+ /* ── Review Tab ───────────────────────────────────────────────────── */
2768
+ .review-tab {
2769
+ display: flex;
2770
+ align-items: center;
2771
+ gap: 4px;
2772
+ }
2773
+
2774
+ .review-tab .review-icon {
2775
+ font-size: 12px;
2776
+ color: var(--c-brand);
2777
+ }
2778
+
2779
+ .review-tab.active .review-icon {
2780
+ color: var(--c-brand);
2781
+ }
2782
+
2783
+ /* ── Modification Indicator ───────────────────────────────────────── */
2784
+ .tree-node .mod-indicator {
2785
+ width: 6px;
2786
+ height: 6px;
2787
+ border-radius: 50%;
2788
+ background: var(--c-ok);
2789
+ flex-shrink: 0;
2790
+ margin-left: 4px;
2791
+ }
2792
+
2793
+ /* ── Review Diff View ─────────────────────────────────────────────── */
2794
+ .review-diff-view {
2795
+ display: flex;
2796
+ flex-direction: column;
2797
+ height: 100%;
2798
+ overflow: hidden;
2799
+ }
2800
+
2801
+ .review-diff-header {
2802
+ display: flex;
2803
+ align-items: center;
2804
+ gap: 12px;
2805
+ padding: 8px 12px;
2806
+ border-bottom: 1px solid var(--bd);
2807
+ background: var(--bg-elev);
2808
+ flex-shrink: 0;
2809
+ }
2810
+
2811
+ .review-diff-title {
2812
+ font-family: var(--font-mono);
2813
+ font-size: 11px;
2814
+ color: var(--fg-2);
2815
+ text-transform: uppercase;
2816
+ letter-spacing: .08em;
2817
+ }
2818
+
2819
+ .review-diff-list {
2820
+ flex: 1;
2821
+ overflow-y: auto;
2822
+ padding: 8px;
2823
+ }
2824
+
2825
+ .review-file-item {
2826
+ margin-bottom: 8px;
2827
+ border: 1px solid var(--bd);
2828
+ border-radius: var(--r);
2829
+ overflow: hidden;
2830
+ }
2831
+
2832
+ .review-file-header {
2833
+ display: flex;
2834
+ align-items: center;
2835
+ gap: 8px;
2836
+ padding: 8px 10px;
2837
+ background: var(--bg-elev);
2838
+ cursor: pointer;
2839
+ user-select: none;
2840
+ font-family: var(--font-mono);
2841
+ font-size: 12px;
2842
+ color: var(--fg-1);
2843
+ }
2844
+
2845
+ .review-file-header:hover {
2846
+ background: var(--bg-hover);
2847
+ }
2848
+
2849
+ .review-file-header .chev {
2850
+ color: var(--fg-3);
2851
+ font-size: 10px;
2852
+ width: 12px;
2853
+ }
2854
+
2855
+ .review-file-header .filename {
2856
+ flex: 1;
2857
+ }
2858
+
2859
+ .review-file-header .stat {
2860
+ font-size: 11px;
2861
+ color: var(--fg-3);
2862
+ }
2863
+
2864
+ .review-file-header .stat .add {
2865
+ color: var(--c-ok);
2866
+ }
2867
+
2868
+ .review-file-header .stat .rem {
2869
+ color: var(--c-err);
2870
+ }
2871
+
2872
+ .review-file-body {
2873
+ padding: 8px;
2874
+ background: var(--bg-code);
2875
+ }
2876
+
2877
+ .review-empty {
2878
+ padding: 32px;
2879
+ text-align: center;
2880
+ color: var(--fg-3);
2881
+ font-family: var(--font-mono);
2882
+ font-size: 12px;
2883
+ }
2884
+
2885
+ /* ── Split Diff View ──────────────────────────────────────────── */
2886
+ .split-diff {
2887
+ font-family: var(--font-mono);
2888
+ font-size: 12px;
2889
+ line-height: 1.5;
2890
+ overflow-x: auto;
2891
+ }
2892
+ .diff-hunk-header {
2893
+ padding: 4px 12px;
2894
+ background: var(--bg-elev-2);
2895
+ color: var(--fg-3);
2896
+ font-size: 11px;
2897
+ display: flex;
2898
+ gap: 8px;
2899
+ border-bottom: 1px solid var(--bd);
2900
+ }
2901
+ .diff-hdr-left,
2902
+ .diff-hdr-right {
2903
+ flex: 1;
2904
+ }
2905
+ .diff-line {
2906
+ display: flex;
2907
+ padding: 0 12px;
2908
+ min-height: 20px;
2909
+ }
2910
+ .diff-line.diff-add { background: rgba(126,231,135,.08); }
2911
+ .diff-line.diff-del { background: rgba(255,139,129,.08); }
2912
+ .diff-line {
2913
+ display: flex;
2914
+ padding-left: 8px;
2915
+ }
2916
+ .diff-ln-old,
2917
+ .diff-ln-new {
2918
+ display: inline-block;
2919
+ min-width: 32px;
2920
+ text-align: right;
2921
+ color: var(--fg-4);
2922
+ font-size: 11px;
2923
+ padding: 0 6px 0 12px;
2924
+ user-select: none;
2925
+ flex-shrink: 0;
2926
+ }
2927
+ .diff-prefix {
2928
+ width: 14px;
2929
+ flex-shrink: 0;
2930
+ color: var(--fg-3);
2931
+ }
2932
+ .diff-content {
2933
+ flex: 1;
2934
+ white-space: pre;
2935
+ }
2936
+ .diff-add .diff-content { color: var(--c-ok); }
2937
+ .diff-del .diff-content { color: var(--c-err); }
2938
+
2939
+ /* Split rows */
2940
+ .diff-split-row {
2941
+ display: flex;
2942
+ }
2943
+ .diff-split-cell {
2944
+ flex: 1;
2945
+ min-width: 0;
2946
+ display: flex;
2947
+ padding: 0 8px;
2948
+ min-height: 20px;
2949
+ border-right: 1px solid var(--bd);
2950
+ overflow: hidden;
2951
+ }
2952
+ .diff-split-cell:last-child { border-right: none; }
2953
+ .diff-split-cell .diff-content {
2954
+ flex: 1;
2955
+ white-space: pre;
2956
+ overflow: hidden;
2957
+ text-overflow: ellipsis;
2958
+ }
2959
+
2960
+ /* Diff source toggle */
2961
+ .diff-source-toggle {
2962
+ display: flex;
2963
+ gap: 4px;
2964
+ align-items: center;
2965
+ }
2966
+ .diff-source-toggle .toggle-btn {
2967
+ font-family: var(--font-mono);
2968
+ font-size: 10.5px;
2969
+ padding: 2px 8px;
2970
+ border: 1px solid var(--bd);
2971
+ border-radius: var(--r);
2972
+ background: var(--bg-elev);
2973
+ color: var(--fg-2);
2974
+ cursor: pointer;
2975
+ }
2976
+ .diff-source-toggle .toggle-btn.active {
2977
+ background: var(--c-brand);
2978
+ color: var(--bg);
2979
+ border-color: var(--c-brand);
2980
+ }
2981
+ .diff-source-toggle .toggle-btn:hover:not(.active) {
2982
+ background: var(--bg-hover);
2983
+ color: var(--fg-0);
2984
+ }
2985
+
2986
+ /* Diff style toggle */
2987
+ .diff-style-toggle {
2988
+ display: flex;
2989
+ gap: 4px;
2990
+ align-items: center;
2991
+ }
2992
+ .diff-style-toggle .toggle-btn {
2993
+ font-family: var(--font-mono);
2994
+ font-size: 10.5px;
2995
+ padding: 2px 8px;
2996
+ border: 1px solid var(--bd);
2997
+ border-radius: var(--r);
2998
+ background: var(--bg-elev);
2999
+ color: var(--fg-2);
3000
+ cursor: pointer;
3001
+ }
3002
+ .diff-style-toggle .toggle-btn.active {
3003
+ background: var(--c-brand);
3004
+ color: var(--bg);
3005
+ border-color: var(--c-brand);
3006
+ }
3007
+ .diff-style-toggle .toggle-btn:hover:not(.active) {
3008
+ background: var(--bg-hover);
3009
+ color: var(--fg-0);
3010
+ }
3011
+
3012
+ .diff-empty {
3013
+ padding: 24px;
3014
+ text-align: center;
3015
+ color: var(--fg-3);
3016
+ font-family: var(--font-mono);
3017
+ font-size: 12px;
3018
+ }
3019
+
3020
+ /* ═══════════════════════════════════════════════════════════════════════════
3021
+ Light theme — toggled via data-theme="light" on <html>
3022
+
3023
+ Palette inspired by Element Plus: clean white surfaces, dark body text,
3024
+ and slightly deepened accent colours so they stay legible on light
3025
+ backgrounds. Every variable from the :root dark set is overridden here;
3026
+ hardcoded-hex fixups follow in a second block.
3027
+ ═══════════════════════════════════════════════════════════════════════════ */
3028
+ [data-theme="light"] {
3029
+ /* Surfaces */
3030
+ --bg: #f5f7fa;
3031
+ --bg-elev: #ffffff;
3032
+ --bg-elev-2: #f0f2f5;
3033
+ --bg-input: #ffffff;
3034
+ --bg-code: #f5f7fa;
3035
+ --bg-hover: #ecf5ff;
3036
+
3037
+ /* Text */
3038
+ --fg-0: #303133; /* primary — headings, emphasis */
3039
+ --fg-1: #606266; /* body — paragraphs, default */
3040
+ --fg-2: #909399; /* secondary — labels, meta */
3041
+ --fg-3: #a8abb2; /* dim — placeholders, hints */
3042
+ --fg-4: #c0c4cc; /* very dim — separators, disabled */
3043
+
3044
+ /* Accents — deepened ~15% so they hit ≥4.5:1 on white */
3045
+ --c-brand: #409eff; /* primary blue (Element Plus) */
3046
+ --c-accent: #9b6bff; /* purple */
3047
+ --c-violet: #8b5cf6; /* violet */
3048
+ --c-ok: #67c23a; /* success green */
3049
+ --c-warn: #e6a23c; /* warning amber */
3050
+ --c-err: #f56c6c; /* error red */
3051
+ --c-info: #409eff;
3052
+
3053
+ /* Chart spectrum */
3054
+ --s1: #409eff;
3055
+ --s2: #36cfc9;
3056
+ --s3: #67c23a;
3057
+ --s4: #e6a23c;
3058
+ --s5: #f56c6c;
3059
+ --s6: #9b6bff;
3060
+
3061
+ /* Borders */
3062
+ --bd: #e4e7ed;
3063
+ --bd-strong: #dcdfe6;
3064
+
3065
+ /* Elevation step above --bg-elev-2 in light mode — matches the surface scale. */
3066
+ --bg-elev-3: #e4e7ed;
3067
+ }
3068
+
3069
+ /* ── Light-theme fixups for hardcoded hex / rgba values ────────────────
3070
+ These selectors use literal colours (not CSS variables) in the dark
3071
+ theme and therefore need explicit overrides to look correct on a
3072
+ white background. Keep them scoped under [data-theme="light"] so
3073
+ dark mode is never touched. ────────────────────────────────────────── */
3074
+
3075
+ /* Hardcoded #14171e borders (dark-theme inner dividers) → var(--bd) */
3076
+ [data-theme="light"] .section,
3077
+ [data-theme="light"] .ssl-row,
3078
+ [data-theme="light"] .sr-card {
3079
+ border-bottom-color: var(--bd);
3080
+ }
3081
+ [data-theme="light"] .overlay::before {
3082
+ border-color: var(--bd);
3083
+ }
3084
+ [data-theme="light"] .composer-foot {
3085
+ border-top-color: var(--bd);
3086
+ }
3087
+ [data-theme="light"] .scale-row {
3088
+ border-bottom-color: var(--bd);
3089
+ }
3090
+
3091
+ /* Primary button hover — lighten the brand colour instead of the
3092
+ dark-theme hardcoded #94cdff. */
3093
+ [data-theme="light"] .btn.primary:hover,
3094
+ [data-theme="light"] button.primary:hover {
3095
+ background: #66b1ff;
3096
+ border-color: #66b1ff;
3097
+ color: #fff;
3098
+ }
3099
+
3100
+ /* Markdown headings — dark theme puts black text on coloured bg;
3101
+ light theme uses white text for cleaner contrast. */
3102
+ [data-theme="light"] .md h1,
3103
+ [data-theme="light"] .md h2,
3104
+ [data-theme="light"] .md h3 {
3105
+ color: #fff;
3106
+ }
3107
+
3108
+ /* Chat banner — rgba tint references the brand colour so it must
3109
+ switch to the light-mode brand hex. */
3110
+ [data-theme="light"] .chat-banner {
3111
+ background: rgba(64,158,255,.06);
3112
+ border-color: rgba(64,158,255,.18);
3113
+ }
3114
+
3115
+ /* Pills — semi-transparent accent backgrounds must shift hue. */
3116
+ [data-theme="light"] .pill.ok { background: rgba(103,194,58,.10); }
3117
+ [data-theme="light"] .pill.warn { background: rgba(230,162,60,.12); }
3118
+ [data-theme="light"] .pill.err { background: rgba(245,108,108,.10); }
3119
+ [data-theme="light"] .pill.info { background: rgba(64,158,255,.10); }
3120
+ [data-theme="light"] .pill.acc { background: rgba(155,107,255,.10); }
3121
+ [data-theme="light"] .pill-err { background: rgba(245,108,108,.10); }
3122
+ [data-theme="light"] .pill-active { background: rgba(64,158,255,.10); }
3123
+
3124
+ /* Step-dot glow — brand-colour box-shadow. */
3125
+ [data-theme="light"] .plan-step.active::before {
3126
+ box-shadow: 0 0 0 3px rgba(64,158,255,.18);
3127
+ }
3128
+
3129
+ /* Filter chips active state. */
3130
+ [data-theme="light"] .chip-f.active {
3131
+ background: rgba(64,158,255,.08);
3132
+ }
3133
+ [data-theme="light"] .chip-f.static.active:hover {
3134
+ background: rgba(64,158,255,.08);
3135
+ }
3136
+
3137
+ /* Matrix cell on-state. */
3138
+ [data-theme="light"] .matrix .cell.on {
3139
+ background: rgba(64,158,255,.05);
3140
+ }
3141
+
3142
+ /* Editor line hover. */
3143
+ [data-theme="light"] .editor-line:hover {
3144
+ background: rgba(64,158,255,.04);
3145
+ }
3146
+ [data-theme="light"] .editor-line.cur {
3147
+ background: rgba(64,158,255,.06);
3148
+ }
3149
+
3150
+ /* Markdown search-result highlight. */
3151
+ [data-theme="light"] .sr-card .sr-snip mark {
3152
+ background: rgba(230,162,60,.18);
3153
+ }
3154
+
3155
+ /* Why / notes callout. */
3156
+ [data-theme="light"] .why {
3157
+ background: rgba(155,107,255,.04);
3158
+ }
3159
+
3160
+ /* Diff-line insert / delete. */
3161
+ [data-theme="light"] .diff-line.ins {
3162
+ background: rgba(103,194,58,0.10);
3163
+ color: var(--c-ok);
3164
+ }
3165
+ [data-theme="light"] .diff-line.del {
3166
+ background: rgba(245,108,108,0.10);
3167
+ color: var(--c-err);
3168
+ }
3169
+
3170
+ /* Diff-row add / remove backgrounds. */
3171
+ [data-theme="light"] .diff-row.add { background: rgba(103,194,58,.06); }
3172
+ [data-theme="light"] .diff-row.rem { background: rgba(245,108,108,.05); }
3173
+ [data-theme="light"] .diff-row .word-add { background: rgba(103,194,58,.22); }
3174
+ [data-theme="light"] .diff-row .word-rem { background: rgba(245,108,108,.20); }
3175
+
3176
+ /* Edit-diff side-by-side markers and borders. */
3177
+ [data-theme="light"] .edit-diff-side-old .edit-diff-marker { color: var(--c-err); }
3178
+ [data-theme="light"] .edit-diff-side-new .edit-diff-marker { color: var(--c-ok); }
3179
+ [data-theme="light"] .edit-diff-row-del .edit-diff-cell-old,
3180
+ [data-theme="light"] .edit-diff-row-change .edit-diff-cell-old {
3181
+ background: rgba(245,108,108,0.10);
3182
+ border-left-color: var(--c-err);
3183
+ }
3184
+ [data-theme="light"] .edit-diff-row-ins .edit-diff-cell-new,
3185
+ [data-theme="light"] .edit-diff-row-change .edit-diff-cell-new {
3186
+ background: rgba(103,194,58,0.10);
3187
+ border-left-color: var(--c-ok);
3188
+ }
3189
+
3190
+ /* Plan-revision modal border. */
3191
+ [data-theme="light"] .modal-revise-reason {
3192
+ border-left-color: var(--c-accent);
3193
+ }
3194
+
3195
+ /* Picker selected row. */
3196
+ [data-theme="light"] .modal-picker-row.selected {
3197
+ border-color: var(--c-warn);
3198
+ }
3199
+
3200
+ /* Modal viewer step-done mark. */
3201
+ [data-theme="light"] .modal-viewer-step-done .modal-viewer-step-mark {
3202
+ color: var(--c-ok);
3203
+ }
3204
+
3205
+ /* Top-bar status dot glow. */
3206
+ [data-theme="light"] .tui-status.online .dot {
3207
+ box-shadow: 0 0 6px rgba(103,194,58,.5);
3208
+ }
3209
+
3210
+ /* Dialog box-shadow — dark mode uses a deep black shadow; light mode
3211
+ needs a softer grey one. */
3212
+ [data-theme="light"] .dialog {
3213
+ box-shadow: 0 18px 48px rgba(0,0,0,.08), 0 0 0 1px rgba(0,0,0,.04);
3214
+ }
3215
+ [data-theme="light"] .cmd-palette {
3216
+ box-shadow: 0 24px 64px rgba(0,0,0,.10);
3217
+ }
3218
+ [data-theme="light"] .popover {
3219
+ box-shadow: 0 12px 32px rgba(0,0,0,.08);
3220
+ }
3221
+
3222
+ /* Scrollbar — lighter thumb for light backgrounds. */
3223
+ [data-theme="light"] * {
3224
+ scrollbar-color: var(--bd-strong) transparent;
3225
+ }
3226
+ [data-theme="light"] *::-webkit-scrollbar-thumb {
3227
+ background: var(--bd);
3228
+ border-color: var(--bg);
3229
+ }
3230
+ [data-theme="light"] *::-webkit-scrollbar-thumb:hover {
3231
+ background: var(--fg-4);
3232
+ }
3233
+