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