wisp-agents 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,893 @@
1
+ /* wisp — quiet, neutral, out of the way. One accent, hairlines, native type. */
2
+
3
+ :root {
4
+ --bg: #ffffff;
5
+ --bg-2: #f3f3f2;
6
+ --rail: #f7f7f6;
7
+ --surface: #ffffff;
8
+ --surface-2: #f9f9f8;
9
+ --ink: #171717;
10
+ --ink-2: #3d3d3d;
11
+ --muted: #6e6e6e;
12
+ --faint: #a3a3a3;
13
+ --line: #ebebea;
14
+ --line-2: #dcdcda;
15
+ --accent: #2f5bea;
16
+ --accent-ink: #2149cc;
17
+ --accent-soft: rgba(47, 91, 234, 0.08);
18
+ --good: #18794e;
19
+ --warn: #a35c00;
20
+ --bad: #cd2b31;
21
+ --info: #2f5bea;
22
+ --add: #18794e;
23
+ --del: #cd2b31;
24
+ --add-bg: rgba(24, 121, 78, 0.07);
25
+ --del-bg: rgba(205, 43, 49, 0.06);
26
+ --add-strong: rgba(24, 121, 78, 0.14);
27
+ --term-bg: #141414;
28
+ --term-ink: #e8e8e6;
29
+ --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.04);
30
+ --shadow-2: 0 1px 2px rgba(0, 0, 0, 0.04), 0 10px 30px -12px rgba(0, 0, 0, 0.14);
31
+ --radius: 10px;
32
+ --sans: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Inter', 'Segoe UI', system-ui, sans-serif;
33
+ --display: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Inter', 'Segoe UI', system-ui, sans-serif;
34
+ --mono: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
35
+ --ease: cubic-bezier(0.25, 0.8, 0.25, 1);
36
+ --tk-k: #cf222e;
37
+ --tk-s: #0a3069;
38
+ --tk-c: #8c8c8c;
39
+ --tk-n: #0550ae;
40
+ --tk-t: #8250df;
41
+ color-scheme: light;
42
+ }
43
+
44
+ @media (prefers-color-scheme: dark) {
45
+ :root:not([data-theme='light']) {
46
+ --bg: #111111;
47
+ --bg-2: #1e1e1e;
48
+ --rail: #151515;
49
+ --surface: #171717;
50
+ --surface-2: #1a1a1a;
51
+ --ink: #ededed;
52
+ --ink-2: #c7c7c7;
53
+ --muted: #8f8f8f;
54
+ --faint: #5e5e5e;
55
+ --line: #262626;
56
+ --line-2: #333333;
57
+ --accent: #6d8dff;
58
+ --accent-ink: #94adff;
59
+ --accent-soft: rgba(109, 141, 255, 0.12);
60
+ --good: #4cc38a;
61
+ --warn: #f0a33a;
62
+ --bad: #ff6369;
63
+ --info: #6d8dff;
64
+ --add: #4cc38a;
65
+ --del: #ff6369;
66
+ --add-bg: rgba(76, 195, 138, 0.08);
67
+ --del-bg: rgba(255, 99, 105, 0.08);
68
+ --add-strong: rgba(76, 195, 138, 0.16);
69
+ --term-bg: #0c0c0c;
70
+ --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3);
71
+ --shadow-2: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 32px -12px rgba(0, 0, 0, 0.6);
72
+ --tk-k: #ff7b72;
73
+ --tk-s: #a5d6ff;
74
+ --tk-c: #6e7681;
75
+ --tk-n: #79c0ff;
76
+ --tk-t: #d2a8ff;
77
+ color-scheme: dark;
78
+ }
79
+ }
80
+
81
+ /* project colours — muted, distinguishable, never neon */
82
+ .c-violet { --pc: #7c6bd6; }
83
+ .c-teal { --pc: #2b9a8a; }
84
+ .c-amber { --pc: #c9932a; }
85
+ .c-rose { --pc: #c9586f; }
86
+ .c-sky { --pc: #3f8fd2; }
87
+ .c-lime { --pc: #5f9a3a; }
88
+ .c-orange { --pc: #d27637; }
89
+ .c-indigo { --pc: #5262c9; }
90
+ .c-slate { --pc: #8a8a8a; }
91
+
92
+ * { box-sizing: border-box; }
93
+ html, body { margin: 0; height: 100%; }
94
+ body {
95
+ background: var(--bg);
96
+ color: var(--ink);
97
+ font: 14px/1.55 var(--sans);
98
+ -webkit-font-smoothing: antialiased;
99
+ letter-spacing: -0.003em;
100
+ }
101
+ button, input, textarea, select { font: inherit; color: inherit; }
102
+ button { cursor: pointer; background: none; border: 0; padding: 0; }
103
+ a { color: inherit; text-decoration: none; }
104
+ code, kbd, pre { font-family: var(--mono); }
105
+ kbd {
106
+ font-size: 10.5px; padding: 1px 5px; border-radius: 5px; border: 1px solid var(--line-2);
107
+ border-bottom-width: 2px; color: var(--muted); background: var(--surface); line-height: 1.4;
108
+ }
109
+ .i { width: 16px; height: 16px; flex: none; vertical-align: -3px; }
110
+ .muted { color: var(--muted); }
111
+ .xs { font-size: 12px; }
112
+ .grow { flex: 1; }
113
+ [hidden] { display: none !important; }
114
+ ::selection { background: var(--accent-soft); }
115
+
116
+ /* ---------- buttons ---------- */
117
+ .primary {
118
+ display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 14px 0 16px;
119
+ border-radius: 8px; background: var(--ink); color: var(--bg); font-weight: 500;
120
+ transition: opacity 0.15s;
121
+ }
122
+ .primary:hover { opacity: 0.86; }
123
+ .primary:disabled { opacity: 0.5; }
124
+ .primary kbd { background: transparent; color: inherit; border-color: color-mix(in srgb, var(--bg) 35%, transparent); opacity: 0.7; }
125
+ .primary.sm { height: 30px; padding: 0 12px; font-size: 13px; border-radius: 9px; }
126
+ .ghost {
127
+ display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px; border-radius: 9px;
128
+ color: var(--ink-2); transition: background 0.15s, color 0.15s;
129
+ }
130
+ .ghost:hover { background: var(--bg-2); color: var(--ink); }
131
+ .ghost.on { color: var(--good); }
132
+ .ghost.sm { height: 28px; font-size: 13px; }
133
+ .ghost.xs { height: 24px; padding: 0 6px; border-radius: 7px; }
134
+ .ghost.danger:hover { color: var(--bad); background: var(--del-bg); }
135
+ .icon-btn {
136
+ display: inline-grid; place-items: center; width: 32px; height: 32px; border-radius: 9px; color: var(--muted);
137
+ transition: background 0.15s, color 0.15s;
138
+ }
139
+ .icon-btn:hover { background: var(--bg-2); color: var(--ink); }
140
+ .link { color: var(--accent-ink); font-weight: 500; }
141
+ .link:hover { text-decoration: underline; text-underline-offset: 3px; }
142
+ .link.on { color: var(--ink); }
143
+ select {
144
+ height: 30px; border-radius: 9px; border: 1px solid var(--line); background: var(--surface); padding: 0 26px 0 10px;
145
+ appearance: none; font-size: 13px; color: var(--ink-2);
146
+ background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
147
+ background-position: calc(100% - 13px) 13px, calc(100% - 9px) 13px; background-size: 4px 4px; background-repeat: no-repeat;
148
+ }
149
+
150
+ /* ---------- the mark ---------- */
151
+ /* A plain dot. Brand: ink dot with an offset accent dot. Live: a thin spinner ring. */
152
+ .orb { --s: 14px; position: relative; display: inline-block; width: var(--s); height: var(--s); border-radius: 50%; background: var(--ink); flex: none; }
153
+ .orb i { display: none; }
154
+ .orb.tiny { --s: 12px; }
155
+ .orb.tiny::after {
156
+ content: ''; position: absolute; width: 6px; height: 6px; right: -4px; bottom: -2px; border-radius: 50%;
157
+ background: var(--accent); box-shadow: 0 0 0 2px var(--bg);
158
+ }
159
+ .orb.big { display: none; }
160
+ .orb.live {
161
+ --s: 18px; background: none; border: 2px solid var(--line-2); border-top-color: var(--accent);
162
+ animation: orb-spin 0.9s linear infinite;
163
+ }
164
+ .waiting .orb.live { border: 0; background: var(--warn); --s: 10px; margin: 4px; animation: pulse 1.6s ease-in-out infinite; }
165
+
166
+ @keyframes orb-spin { to { rotate: 360deg; } }
167
+
168
+ /* ---------- layout: one column — top bar, launcher, feed ---------- */
169
+ .stage { position: relative; height: 100vh; overflow-y: auto; overflow-x: hidden; scroll-padding-top: 64px; }
170
+ .feed-wrap { max-width: 800px; margin: 0 auto; padding: 20px 24px 120px; }
171
+
172
+ .topbar {
173
+ position: sticky; top: 0; z-index: 10; display: flex; align-items: center; gap: 14px; height: 52px; padding: 0 20px;
174
+ background: color-mix(in srgb, var(--bg) 94%, transparent); backdrop-filter: blur(10px);
175
+ border-bottom: 1px solid transparent; transition: border-color 0.2s;
176
+ }
177
+ .topbar.scrolled { border-bottom-color: var(--line); }
178
+
179
+ .to-top {
180
+ position: fixed; top: 64px; left: 0; right: 0; margin-inline: auto; z-index: 20; display: grid; place-items: center;
181
+ width: 38px; height: 38px; border-radius: 50%; color: var(--ink-2);
182
+ background: var(--surface); border: 1px solid var(--line-2); box-shadow: var(--shadow-2);
183
+ transition: color 0.15s, border-color 0.15s, translate 0.2s var(--ease); animation: to-top-in 0.25s var(--ease);
184
+ }
185
+ .to-top:hover { color: var(--ink); border-color: var(--faint); translate: 0 -2px; }
186
+ @keyframes to-top-in { from { opacity: 0; transform: translateY(-10px) scale(0.97); } }
187
+ .to-top:focus-visible { outline: 0; box-shadow: 0 0 0 2px var(--accent-soft), 0 0 0 1px var(--accent); }
188
+ .brand { display: flex; align-items: center; gap: 9px; flex: none; }
189
+ .brand .word { font: 600 15px/1 var(--display); letter-spacing: -0.02em; }
190
+ .agent-status { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--muted); white-space: nowrap; }
191
+ .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--faint); flex: none; }
192
+ .dot.ok { background: var(--good); }
193
+ .dot.bad { background: var(--bad); }
194
+
195
+ /* project filter chips in the top bar */
196
+ .projects { flex: 1; min-width: 0; display: flex; align-items: center; gap: 4px; overflow-x: auto; scrollbar-width: none; }
197
+ .projects::-webkit-scrollbar { display: none; }
198
+ .p-chip {
199
+ display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; border-radius: 99px; flex: none;
200
+ font-size: 12.5px; color: var(--muted); border: 1px solid transparent; transition: background 0.15s, border-color 0.15s, color 0.15s;
201
+ }
202
+ .p-chip:hover { background: var(--bg-2); color: var(--ink-2); }
203
+ .p-chip.on { background: var(--surface); border-color: var(--line-2); color: var(--ink); font-weight: 500; }
204
+ .p-chip.add { padding: 0 6px; }
205
+ .p-chip.add .i { width: 14px; height: 14px; }
206
+ .p-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--pc); display: inline-block; flex: none; }
207
+ .p-run { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); animation: pulse 1.6s ease-in-out infinite; }
208
+ .p-need { font-size: 10.5px; font-weight: 600; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 99px; background: var(--ink); color: var(--bg); display: grid; place-items: center; }
209
+
210
+ /* ---------- launcher ---------- */
211
+ .launcher { padding: 12px 12px 10px; border-radius: 12px; border-color: var(--line-2); box-shadow: var(--shadow-1); transition: box-shadow 0.15s, border-color 0.15s; }
212
+ .launcher:focus-within { border-color: color-mix(in srgb, var(--accent) 55%, var(--line-2)); box-shadow: 0 0 0 3px var(--accent-soft); }
213
+ .launcher.drop, .composer.drop { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
214
+ .l-projects { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 0 2px 8px; }
215
+ .l-in { font-size: 12.5px; color: var(--faint); margin-right: 2px; }
216
+ .lp-chip {
217
+ display: inline-flex; align-items: center; gap: 6px; height: 27px; padding: 0 10px; border-radius: 99px;
218
+ font-size: 12.5px; color: var(--ink-2); border: 1px solid var(--line); transition: all 0.15s;
219
+ }
220
+ .lp-chip:hover { border-color: var(--line-2); background: var(--surface-2); }
221
+ .lp-chip.on { background: var(--bg-2); border-color: var(--line-2); color: var(--ink); font-weight: 500; }
222
+ .lp-chip.add { color: var(--muted); border-style: dashed; }
223
+ .lp-chip.add .i { width: 14px; height: 14px; }
224
+ .launcher textarea, .composer textarea {
225
+ display: block; width: 100%; resize: none; border: 0; outline: 0; background: transparent; padding: 8px 4px;
226
+ font-size: 15px; line-height: 1.55; color: var(--ink); min-height: 64px;
227
+ }
228
+ .launcher textarea::placeholder, .composer textarea::placeholder { color: var(--faint); }
229
+ .l-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-top: 6px; }
230
+ .seg { display: inline-flex; padding: 2px; border-radius: 8px; background: var(--bg-2); }
231
+ .seg button { height: 26px; padding: 0 10px; border-radius: 6px; font-size: 12.5px; color: var(--muted); transition: all 0.15s; }
232
+ .seg button.on { background: var(--surface); color: var(--ink); box-shadow: 0 0 0 1px var(--line-2); font-weight: 500; }
233
+ .seg button[data-mode='auto'].on { color: var(--warn); }
234
+ .model-btn {
235
+ display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 8px 0 9px; border-radius: 8px;
236
+ font-size: 12.5px; color: var(--muted); transition: background 0.15s, color 0.15s;
237
+ }
238
+ .model-btn .i { width: 14px; height: 14px; }
239
+ .model-btn .chev { width: 12px; height: 12px; color: var(--faint); transform: rotate(90deg); transition: transform 0.2s var(--ease); }
240
+ .model-btn:hover, .model-btn.open { background: var(--bg-2); color: var(--ink); }
241
+ .model-btn.open .chev { transform: rotate(-90deg); }
242
+ .model-btn.set { color: var(--ink-2); font-weight: 500; }
243
+ .model-btn.set > .i:first-child { color: var(--accent); }
244
+ .model-btn:focus-visible { outline: 0; box-shadow: 0 0 0 2px var(--accent-soft), 0 0 0 1px var(--accent); }
245
+
246
+ /* ---------- feed ---------- */
247
+ .feed-head { display: flex; align-items: center; gap: 14px; min-height: 22px; margin: 26px 2px 10px; font-size: 13px; }
248
+ .fh-status { display: flex; gap: 14px; }
249
+ .feed-head[hidden] + .feed { margin-top: 26px; }
250
+ .hs { display: inline-flex; align-items: center; gap: 7px; color: var(--ink-2); }
251
+ .hs i { width: 7px; height: 7px; border-radius: 50%; }
252
+ .hs.working i { background: var(--accent); animation: pulse 1.6s infinite; }
253
+ .hs.needs i { background: var(--warn); }
254
+
255
+ .f-group { margin-bottom: 22px; }
256
+ .f-group h4 {
257
+ display: flex; align-items: center; gap: 6px; margin: 0 0 6px; padding: 0 4px;
258
+ font-size: 12px; font-weight: 500; color: var(--muted);
259
+ }
260
+ .f-group h4 .n { color: var(--faint); }
261
+ .collapse-all {
262
+ position: fixed; right: 22px; bottom: 22px; z-index: 30; height: 30px; padding: 0 12px; border-radius: 15px;
263
+ background: var(--surface); border: 1px solid var(--line-2); box-shadow: var(--shadow-2);
264
+ font-size: 12.5px; font-weight: 500; color: var(--ink-2);
265
+ opacity: 0; visibility: hidden; translate: 0 6px; transition: opacity 0.18s, translate 0.18s var(--ease), visibility 0.18s, color 0.15s;
266
+ }
267
+ .collapse-all.on { opacity: 1; visibility: visible; translate: 0 0; }
268
+ .collapse-all:hover { color: var(--ink); }
269
+ .toggle-done { cursor: pointer; user-select: none; }
270
+ .toggle-done:hover { color: var(--ink-2); }
271
+ .toggle-done .chev { width: 12px; height: 12px; transition: transform 0.2s; }
272
+ .f-group.done:not(.collapsed) .chev { transform: rotate(90deg); }
273
+ .f-list { display: flex; flex-direction: column; gap: 6px; }
274
+ .feed-empty { padding: 48px 0; text-align: center; color: var(--faint); font-size: 13.5px; }
275
+
276
+ /* one feed item — a row that expands in place */
277
+ .item {
278
+ background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
279
+ transition: border-color 0.15s, box-shadow 0.15s;
280
+ }
281
+ .item:hover { border-color: var(--line-2); }
282
+ .item.focused { border-color: var(--line-2); box-shadow: 0 0 0 1px var(--line-2); }
283
+ .item.open { border-color: var(--line-2); box-shadow: var(--shadow-2); }
284
+ .item.st-done:not(.open) { background: transparent; }
285
+ .item.arrived { animation: arrive 1.4s var(--ease); }
286
+ @keyframes arrive { from { box-shadow: 0 0 0 3px var(--accent-soft); border-color: var(--accent); } }
287
+
288
+ .it-head {
289
+ display: grid; grid-template-columns: 10px 1fr auto; gap: 12px; align-items: center;
290
+ padding: 11px 12px 11px 14px; cursor: pointer; outline: 0; border-radius: var(--radius);
291
+ }
292
+ .item.open .it-head { border-bottom: 1px solid var(--line); border-radius: var(--radius) var(--radius) 0 0; }
293
+ .q-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--pc); position: relative; }
294
+ .item.st-done .q-dot { opacity: 0.35; }
295
+ .q-dot.live::after, .q-dot.waiting::after {
296
+ content: ''; position: absolute; inset: -4px; border-radius: 50%; border: 1.5px solid var(--pc); animation: ring 1.8s ease-out infinite;
297
+ }
298
+ .q-dot.waiting { background: var(--warn); --pc: var(--warn); }
299
+ .it-main { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
300
+ .it-title { font-size: 14px; font-weight: 500; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; outline: 0; border-radius: 5px; }
301
+ .item.unread .it-title, .item.st-waiting .it-title, .item.open .it-title { color: var(--ink); font-weight: 600; }
302
+ .item.open .it-title { white-space: normal; }
303
+ .item.st-done .it-title { color: var(--muted); }
304
+ .it-title[contenteditable='true'] { white-space: normal; background: var(--surface-2); box-shadow: 0 0 0 3px var(--accent-soft); padding: 0 4px; cursor: text; }
305
+ .it-sub, .q-live { font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
306
+ .q-live.running { color: var(--ink-2); }
307
+ .q-live.waiting { color: var(--warn); font-weight: 500; }
308
+ .it-side { display: flex; align-items: center; gap: 10px; }
309
+ .it-side .chev { width: 14px; height: 14px; color: var(--faint); transition: transform 0.2s; }
310
+ .item.open .it-side .chev { transform: rotate(90deg); }
311
+ .q-proj {
312
+ font-size: 11px; font-weight: 500; padding: 0 7px; border-radius: 5px; line-height: 19px; white-space: nowrap; max-width: 120px; overflow: hidden; text-overflow: ellipsis;
313
+ color: color-mix(in srgb, var(--pc) 65%, var(--ink)); background: color-mix(in srgb, var(--pc) 10%, transparent);
314
+ }
315
+ .q-time { font-size: 11.5px; color: var(--faint); min-width: 26px; text-align: right; font-variant-numeric: tabular-nums; }
316
+ .q-queued { font-size: 11px; color: var(--accent-ink); font-weight: 600; }
317
+ /* one-click done on collapsed review rows; revealed on hover/focus */
318
+ .it-quick {
319
+ display: grid; place-items: center; width: 24px; height: 24px; margin: -4px -6px -4px 0; border-radius: 7px;
320
+ color: var(--faint); opacity: 0; transition: opacity 0.15s, background 0.15s, color 0.15s;
321
+ }
322
+ .it-quick .i { width: 14px; height: 14px; }
323
+ .item:hover .it-quick, .item.focused .it-quick, .it-quick:focus-visible { opacity: 1; }
324
+ .it-quick:hover { background: var(--bg-2); color: var(--good); }
325
+ @media (hover: none) { .it-quick { opacity: 1; } }
326
+
327
+ /* expanded body */
328
+ .it-body { animation: rise 0.3s var(--ease); }
329
+ .it-loading { display: flex; align-items: center; gap: 10px; padding: 18px; color: var(--muted); font-size: 13px; }
330
+ .it-bar { display: flex; align-items: center; gap: 12px; padding: 8px 10px 8px 14px; }
331
+ .it-meta { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; }
332
+ .it-meta .path { font-family: var(--mono); font-size: 11px; color: var(--faint); }
333
+ .it-actions { display: flex; gap: 2px; flex: none; }
334
+ .it-body .earlier { display: block; margin: 4px 0 0 18px; }
335
+ .it-dock { padding: 4px 14px 14px; }
336
+
337
+ /* ---------- pills ---------- */
338
+ .pill {
339
+ display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px; border-radius: 6px;
340
+ font-size: 12px; font-weight: 500; --tone: var(--good); color: color-mix(in srgb, var(--tone) 85%, var(--ink));
341
+ background: color-mix(in srgb, var(--tone) 9%, transparent);
342
+ }
343
+ .pill i { width: 6px; height: 6px; border-radius: 50%; background: var(--tone); }
344
+ .pill.st-partial, .pill.st-waiting { --tone: var(--warn); }
345
+ .pill.st-blocked { --tone: var(--bad); }
346
+ .pill.st-info { --tone: var(--accent); }
347
+
348
+ .turns { padding: 6px 18px 8px; }
349
+ .turn { padding-top: 12px; }
350
+ .turn + .turn { margin-top: 28px; border-top: 1px solid var(--line); padding-top: 28px; }
351
+ /* older exchanges fold to a single row; the latest stays open */
352
+ .turn.folded { padding-top: 0; }
353
+ .turn.folded + .turn.folded { margin-top: 2px; border-top: 0; padding-top: 0; }
354
+ .turn + .turn.folded { margin-top: 14px; padding-top: 10px; }
355
+ .turn.folded + .turn:not(.folded) { margin-top: 14px; }
356
+ .t-fold {
357
+ display: flex; align-items: center; gap: 10px; width: 100%; min-width: 0; padding: 7px 10px; border-radius: 8px;
358
+ text-align: left; font-size: 13px; color: var(--muted); transition: background 0.15s, color 0.15s;
359
+ }
360
+ .t-fold:hover { background: var(--bg-2); color: var(--ink); }
361
+ .t-fold .chev { flex: none; width: 12px; height: 12px; color: var(--faint); }
362
+ .t-prompt { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ink); }
363
+ .t-result { flex: 0 1 auto; max-width: 40%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 12px; color: var(--faint); }
364
+ .t-fold time { flex: none; font-size: 11.5px; color: var(--faint); font-variant-numeric: tabular-nums; }
365
+ .ask:has(.t-unfold) { padding-right: 40px; }
366
+ .t-unfold { position: absolute; top: 6px; right: 6px; }
367
+ .t-unfold .chev { width: 12px; height: 12px; transform: rotate(90deg); }
368
+
369
+ .ask { position: relative; margin: 0 0 20px; padding: 10px 14px; border-radius: var(--radius); background: var(--bg-2); }
370
+ .ask-text { white-space: pre-wrap; color: var(--ink); font-size: 14px; }
371
+ .ask-text.clamped { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
372
+ .ask time { display: block; margin-top: 3px; font-size: 11.5px; color: var(--faint); }
373
+ .ask-atts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
374
+ .ask-atts img { height: 72px; border-radius: 10px; border: 1px solid var(--line); cursor: zoom-in; object-fit: cover; }
375
+ .att-pill { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: 8px; background: var(--surface); border: 1px solid var(--line); font-size: 12.5px; }
376
+
377
+ /* ---------- working panel (not `.working` — the feed group and head badge use that) ---------- */
378
+ .w-panel {
379
+ display: flex; gap: 14px; padding: 16px 18px; border-radius: var(--radius); background: var(--surface); border: 1px solid var(--line);
380
+ animation: rise 0.4s var(--ease) both; position: relative; overflow: hidden;
381
+ }
382
+ .w-panel.waiting { border-color: color-mix(in srgb, var(--warn) 35%, var(--line)); }
383
+ .w-orb { padding-top: 2px; }
384
+ .w-body { flex: 1; min-width: 0; position: relative; }
385
+ .w-status { display: flex; align-items: baseline; gap: 12px; margin-bottom: 10px; }
386
+ .w-status b { font-weight: 600; }
387
+ .w-status span { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
388
+ .ticker, .log { list-style: none; margin: 0; padding: 0; }
389
+ .act { display: flex; align-items: center; gap: 9px; padding: 3px 0; font-size: 13px; color: var(--ink-2); min-width: 0; }
390
+ .act span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
391
+ .act .i { width: 14px; height: 14px; color: var(--faint); }
392
+ .ticker .act:nth-child(1) { color: var(--ink); }
393
+ .ticker .act:nth-child(1) .i { color: var(--accent); }
394
+ .ticker .act:nth-child(2) { opacity: 0.8; }
395
+ .ticker .act:nth-child(3) { opacity: 0.6; }
396
+ .ticker .act:nth-child(4) { opacity: 0.42; }
397
+ .ticker .act:nth-child(5) { opacity: 0.25; }
398
+ .act.new { animation: tick-in 0.45s var(--ease); }
399
+ .act.k-error { color: var(--bad); }
400
+ .act.k-ask, .act.k-wait { color: var(--warn); }
401
+ .act.k-text span { white-space: normal; color: var(--muted); }
402
+ .log { max-height: 340px; overflow-y: auto; margin-top: 12px; padding: 10px 12px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--line); }
403
+ .w-actions { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
404
+ .w-queued { font-size: 12px; color: var(--accent-ink); font-weight: 500; }
405
+ @keyframes tick-in { from { opacity: 0; transform: translateY(-4px); } }
406
+
407
+ /* ask card (mid-run question) */
408
+ .ask-card, .b-question {
409
+ position: relative; padding: 16px 18px; border-radius: var(--radius); margin: 4px 0 14px;
410
+ background: var(--surface); border: 1px solid color-mix(in srgb, var(--warn) 40%, var(--line));
411
+ box-shadow: inset 3px 0 0 var(--warn);
412
+ animation: rise 0.4s var(--ease) both;
413
+ }
414
+ .b-question { border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); box-shadow: inset 3px 0 0 var(--accent); }
415
+ .b-question.answered { opacity: 0.65; box-shadow: none; background: var(--surface-2); border: 1px solid var(--line); }
416
+ .q-head { display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 500; color: var(--warn); }
417
+ .b-question .q-head { color: var(--accent-ink); }
418
+ .q-text { margin: 6px 0 12px; font: 600 17px/1.4 var(--display); letter-spacing: -0.015em; color: var(--ink); }
419
+ .q-context { margin: -4px 0 12px; font-size: 13.5px; color: var(--ink-2); }
420
+ .q-opts { display: flex; flex-wrap: wrap; gap: 8px; }
421
+ .opt {
422
+ display: inline-flex; align-items: center; gap: 9px; min-height: 34px; padding: 6px 12px 6px 8px; border-radius: 8px;
423
+ border: 1px solid var(--line-2); background: var(--surface); font-weight: 500; text-align: left; transition: border-color 0.15s, background 0.15s;
424
+ }
425
+ .opt small { display: block; font-weight: 400; color: var(--muted); font-size: 12px; }
426
+ .opt .k { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 6px; background: var(--bg-2); font: 500 11px var(--mono); color: var(--muted); flex: none; }
427
+ .opt:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-soft); }
428
+ .opt.own { color: var(--muted); border-style: dashed; padding-left: 12px; }
429
+ .q-own { display: flex; gap: 8px; margin-top: 12px; }
430
+ .q-own input { flex: 1; height: 34px; border-radius: 10px; border: 1px solid var(--line); background: var(--surface-2); padding: 0 12px; outline: 0; }
431
+ .q-own input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
432
+ .ask-card.sent { opacity: 0.5; pointer-events: none; }
433
+
434
+ /* ---------- presentation blocks ---------- */
435
+ .presentation { display: flex; flex-direction: column; gap: 14px; }
436
+ .blk { animation: rise 0.45s var(--ease) var(--d) both; min-width: 0; }
437
+ @keyframes rise { from { opacity: 0; transform: translateY(6px); } }
438
+ .card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
439
+ .b-title { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; font-size: 13px; font-weight: 600; color: var(--ink); }
440
+ .b-title .count { font-weight: 500; color: var(--faint); }
441
+ .caption { margin: 0; padding: 10px 16px 12px; font-size: 13px; color: var(--muted); border-top: 1px solid var(--line); }
442
+ .fallback-note { display: flex; gap: 8px; align-items: center; font-size: 12.5px; color: var(--muted); }
443
+
444
+ /* hero */
445
+ .b-hero { position: relative; padding: 2px 0 6px; }
446
+ .b-hero .aura { display: none; }
447
+ .hero-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
448
+ .hero-top .meta { font-size: 12.5px; color: var(--muted); }
449
+ .hero-top .meta + .meta::before { content: '·'; margin-right: 12px; color: var(--faint); }
450
+ .b-hero h2 { margin: 12px 0 6px; font: 600 26px/1.2 var(--display); letter-spacing: -0.025em; text-wrap: balance; }
451
+ .b-hero p { margin: 0; font-size: 15px; line-height: 1.6; color: var(--ink-2); max-width: 70ch; text-wrap: pretty; }
452
+
453
+ /* markdown */
454
+ .prose { color: var(--ink-2); line-height: 1.65; }
455
+ .prose > :first-child { margin-top: 0; }
456
+ .prose > :last-child { margin-bottom: 0; }
457
+ .prose p, .prose ul, .prose ol, .prose pre, .prose blockquote, .prose .table-wrap { margin: 0 0 12px; }
458
+ .prose h3, .prose h4, .prose h5, .prose h6 { color: var(--ink); margin: 18px 0 8px; font-weight: 600; font-size: 15px; }
459
+ .prose h3 { font: 600 17px/1.3 var(--display); letter-spacing: -0.015em; }
460
+ .prose ul, .prose ol { padding-left: 20px; }
461
+ .prose li { margin: 3px 0; }
462
+ .prose li::marker { color: var(--faint); }
463
+ .prose li.task { list-style: none; margin-left: -18px; }
464
+ .prose li.task::before { content: '☐ '; color: var(--faint); }
465
+ .prose li.task.done::before { content: '☑ '; color: var(--good); }
466
+ .prose strong { color: var(--ink); font-weight: 600; }
467
+ .prose a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent); }
468
+ .prose code, .b-hero code, .note code, .b-steps code, .q-text code, .b-check code, .b-compare code, .b-commits code {
469
+ font-size: 0.86em; padding: 1px 5px; border-radius: 5px; background: var(--bg-2); border: 1px solid var(--line); color: var(--ink);
470
+ }
471
+ .prose blockquote { border-left: 2px solid var(--line-2); padding-left: 14px; color: var(--muted); }
472
+ .prose hr { border: 0; border-top: 1px solid var(--line); margin: 18px 0; }
473
+ .table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 10px; }
474
+ .prose table { border-collapse: collapse; width: 100%; font-size: 13.5px; }
475
+ .prose th, .prose td { padding: 7px 12px; text-align: left; border-bottom: 1px solid var(--line); }
476
+ .prose th { font-weight: 600; color: var(--ink); background: var(--surface-2); }
477
+ .prose tr:last-child td { border-bottom: 0; }
478
+ pre.code { margin: 0 0 12px; padding: 12px 14px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--line); overflow-x: auto; font-size: 12.5px; line-height: 1.6; }
479
+ .b-md { padding: 0 2px; }
480
+
481
+ /* steps */
482
+ .b-steps { padding: 18px 20px 8px; }
483
+ .b-steps ol { list-style: none; margin: 0; padding: 0; position: relative; }
484
+ .b-steps ol::before {
485
+ content: ''; position: absolute; left: 10px; top: 12px; bottom: 22px; width: 1.5px; background: var(--line-2);
486
+ transform-origin: top; animation: draw-y 1.1s var(--ease) calc(var(--d, 0ms) + 200ms) both;
487
+ }
488
+ .blk-steps { --dd: var(--d); }
489
+ .b-steps li { display: grid; grid-template-columns: 22px 1fr; gap: 12px; padding-bottom: 14px; position: relative; animation: rise 0.55s var(--ease) calc(240ms + var(--k) * 110ms) both; }
490
+ .b-steps .dot {
491
+ width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; background: var(--surface);
492
+ border: 1.5px solid var(--good); color: var(--good); position: relative; z-index: 1;
493
+ }
494
+ .b-steps .dot .i { width: 12px; height: 12px; }
495
+ .b-steps .st-failed .dot { border-color: var(--bad); color: var(--bad); }
496
+ .b-steps .st-skipped .dot { border-color: var(--line-2); color: var(--faint); }
497
+ .b-steps b { font-weight: 600; display: block; line-height: 22px; }
498
+ .b-steps li p { margin: 2px 0 0; color: var(--muted); font-size: 13.5px; }
499
+ @keyframes draw-y { from { transform: scaleY(0); } }
500
+
501
+ /* stats */
502
+ .b-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
503
+ .stat { position: relative; padding: 14px 16px 12px; border-radius: var(--radius); background: var(--surface); border: 1px solid var(--line); overflow: hidden; animation: rise 0.4s var(--ease) calc(var(--k) * 50ms) both; }
504
+ .stat .num { font: 600 26px/1.1 var(--display); letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
505
+ .stat .u { font-size: 15px; font-weight: 500; color: var(--muted); margin-left: 2px; letter-spacing: 0; }
506
+ .stat .lbl { margin-top: 4px; font-size: 12.5px; color: var(--muted); }
507
+ .stat .delta { position: absolute; top: 12px; right: 12px; font: 500 11.5px var(--mono); padding: 1px 6px; border-radius: 5px; background: var(--bg-2); color: var(--ink-2); }
508
+ .stat.tone-good .delta { background: var(--add-bg); color: var(--good); }
509
+ .stat.tone-bad .delta { background: var(--del-bg); color: var(--bad); }
510
+ @keyframes draw-x { from { transform: scaleX(0); } }
511
+
512
+ /* files */
513
+ .b-files { padding: 16px 8px 8px; }
514
+ .b-files .b-title { padding: 0 12px; }
515
+ .b-files ul { list-style: none; margin: 0; padding: 0; }
516
+ .b-files li { border-radius: 10px; animation: rise 0.5s var(--ease) calc(200ms + var(--k) * 60ms) both; }
517
+ .b-files li.has-diff { cursor: pointer; }
518
+ .b-files li:hover { background: var(--surface-2); }
519
+ .b-files li.open { background: var(--surface-2); }
520
+ .b-files .row { display: flex; align-items: center; gap: 10px; padding: 7px 12px; min-width: 0; }
521
+ .b-files .note { margin: -4px 0 0; padding: 0 12px 8px 42px; font-size: 13px; color: var(--muted); }
522
+ .b-files .actions { margin-left: auto; display: flex; opacity: 0; transition: opacity 0.15s; }
523
+ .b-files li:hover .actions, .b-files li.open .actions { opacity: 1; }
524
+ .b-files .toggle .i { transition: transform 0.2s; }
525
+ .b-files li.open .toggle .i { transform: rotate(90deg); }
526
+ .b-files .b-diff.bare { margin: 0 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
527
+ .badge { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 6px; font: 600 11px var(--mono); flex: none; }
528
+ .badge.add { background: var(--add-bg); color: var(--add); }
529
+ .badge.mod { background: color-mix(in srgb, var(--warn) 12%, transparent); color: var(--warn); }
530
+ .badge.del { background: var(--del-bg); color: var(--del); }
531
+ .badge.ren { background: var(--accent-soft); color: var(--accent-ink); }
532
+ .path { font: 12.5px var(--mono); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
533
+ .path .dir { color: var(--faint); }
534
+ .path .base { color: var(--ink); font-weight: 500; }
535
+ .nums { font: 500 11.5px var(--mono); display: inline-flex; gap: 6px; flex: none; }
536
+ .plus { color: var(--add); }
537
+ .minus { color: var(--del); }
538
+
539
+ /* tree */
540
+ .b-tree { padding: 16px 18px 12px; }
541
+ .b-tree ul { list-style: none; margin: 0; padding: 0; font: 12.5px/1.5 var(--mono); }
542
+ .b-tree li { padding-left: calc(var(--depth) * 18px); animation: rise 0.45s var(--ease) calc(150ms + var(--k) * 40ms) both; }
543
+ .b-tree .row { display: flex; align-items: center; gap: 7px; padding: 3px 6px; border-radius: 7px; }
544
+ .b-tree li.file .row { cursor: pointer; }
545
+ .b-tree li.file .row:hover { background: var(--surface-2); }
546
+ .b-tree .i { width: 14px; height: 14px; color: var(--faint); }
547
+ .b-tree .dir .name { color: var(--muted); }
548
+ .b-tree .badge { width: 17px; height: 17px; font-size: 10px; }
549
+ .b-tree .note { font-family: var(--sans); color: var(--muted); font-size: 12.5px; margin-left: 4px; }
550
+
551
+ /* diff & code */
552
+ .b-diff, .b-code { overflow: hidden; }
553
+ .diff-head, .code-head {
554
+ display: flex; align-items: center; gap: 10px; padding: 9px 10px 9px 14px; border-bottom: 1px solid var(--line); background: var(--surface-2);
555
+ }
556
+ .diff-head .i { color: var(--faint); }
557
+ .diff-head .nums { margin-left: auto; }
558
+ .code-head { justify-content: space-between; }
559
+ .code-head .lang { font: 500 11.5px var(--mono); color: var(--muted); }
560
+ .code-head .file { display: inline-flex; min-width: 0; }
561
+ .lineno { font: 12.5px var(--mono); color: var(--faint); }
562
+ .diff-scroll, .code-scroll { overflow-x: auto; max-height: 560px; overflow-y: auto; }
563
+ .b-diff table, .b-code table { border-collapse: collapse; width: 100%; font: 12.5px/1.65 var(--mono); }
564
+ .b-diff td, .b-code td { padding: 0; vertical-align: top; }
565
+ .b-diff .no, .b-code .no { width: 1%; min-width: 36px; padding: 0 10px 0 12px; text-align: right; color: var(--faint); user-select: none; font-size: 11.5px; }
566
+ .b-diff .sign { width: 1%; padding: 0 6px 0 4px; color: var(--faint); user-select: none; }
567
+ .b-diff .src, .b-code .src { white-space: pre; padding-right: 18px; color: var(--ink-2); }
568
+ .b-diff tr.add { background: var(--add-bg); }
569
+ .b-diff tr.add .sign, .b-diff tr.add .no { color: var(--add); }
570
+ .b-diff tr.del { background: var(--del-bg); }
571
+ .b-diff tr.del .sign, .b-diff tr.del .no { color: var(--del); }
572
+ .b-diff tr.del .src { opacity: 0.8; }
573
+ .b-diff tr.gap td { padding: 3px 12px; font: 11.5px var(--sans); color: var(--faint); background: var(--surface-2); }
574
+ .b-diff tr.gap .i { width: 12px; height: 12px; vertical-align: -2px; }
575
+ .b-diff tr.sep td { height: 10px; background: var(--surface-2); border-top: 1px dashed var(--line); border-bottom: 1px dashed var(--line); }
576
+ .b-diff tbody tr:first-child td { padding-top: 6px; }
577
+ .b-diff tbody tr:last-child td { padding-bottom: 6px; }
578
+ .b-diff tr.ln { animation: line-in 0.4s var(--ease) both; }
579
+ .b-diff.missing { padding: 0 0 4px; }
580
+ .b-diff.missing p { padding: 10px 14px; margin: 0; font-size: 13px; }
581
+ .b-code tr.hl { background: color-mix(in srgb, var(--accent) 10%, transparent); }
582
+ .b-code tr.hl .no { color: var(--accent); box-shadow: inset 2px 0 var(--accent); }
583
+ .b-code .code-scroll { padding: 6px 0; }
584
+ .copy.copied { color: var(--good); }
585
+ @keyframes line-in { from { opacity: 0; } }
586
+
587
+ .tk-k { color: var(--tk-k); }
588
+ .tk-s { color: var(--tk-s); }
589
+ .tk-c { color: var(--tk-c); font-style: italic; }
590
+ .tk-n { color: var(--tk-n); }
591
+ .tk-t { color: var(--tk-t); }
592
+
593
+ /* compare */
594
+ .b-compare { display: grid; grid-template-columns: 1fr 34px 1fr; align-items: stretch; }
595
+ .b-compare .side { padding: 16px 18px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--surface); }
596
+ .b-compare .before { background: var(--surface-2); }
597
+ .b-compare .after { border-color: var(--line-2); }
598
+ .side-label { font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 8px; }
599
+ .after .side-label { color: var(--good); }
600
+ .b-compare ul { list-style: none; margin: 0; padding: 0; }
601
+ .b-compare li { display: flex; gap: 9px; padding: 4px 0; font-size: 13.5px; animation: rise 0.5s var(--ease) calc(250ms + var(--k) * 90ms) both; }
602
+ .b-compare li .i { margin-top: 3px; width: 14px; height: 14px; }
603
+ .before li { color: var(--muted); }
604
+ .before li .i { color: var(--del); }
605
+ .after li .i { color: var(--good); }
606
+ .b-compare .arrow { display: grid; place-items: center; color: var(--faint); }
607
+ .b-compare pre.code { margin: 0; }
608
+
609
+ /* flow */
610
+ .b-flow { padding: 16px 18px 20px; }
611
+ .flow-stage { position: relative; padding: 4px 2px; }
612
+ .wires { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
613
+ .wire { fill: none; stroke: var(--line-2); stroke-width: 1.5; stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw 0.9s var(--ease) calc(500ms + var(--k) * 180ms) forwards; }
614
+ .wire.back { stroke-dasharray: 0.012 0.012; stroke-dashoffset: 0; animation: fade-in 0.6s calc(900ms + var(--k) * 180ms) both; stroke: var(--faint); }
615
+ .spark { fill: var(--accent); }
616
+ .spark.back { fill: var(--muted); }
617
+ .wire-label { font: 500 11px var(--sans); fill: var(--muted); paint-order: stroke; stroke: var(--surface); stroke-width: 4px; }
618
+ .cols { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 46px; }
619
+ .col { flex: 1; display: flex; flex-direction: column; gap: 12px; min-width: 0; max-width: 220px; }
620
+ .node {
621
+ position: relative; padding: 9px 12px; border-radius: 8px; background: var(--surface); border: 1px solid var(--line-2);
622
+ text-align: center; animation: pop 0.4s var(--ease) calc(200ms + var(--k) * 120ms) both;
623
+ }
624
+ .node b { display: block; font-weight: 600; font-size: 13.5px; line-height: 1.3; }
625
+ .node span { display: block; margin-top: 2px; font-size: 12px; color: var(--muted); line-height: 1.35; }
626
+ @keyframes draw { to { stroke-dashoffset: 0; } }
627
+ @keyframes dash { to { stroke-dashoffset: -0.024; } }
628
+ @keyframes fade-in { from { opacity: 0; } }
629
+ @keyframes pop { from { opacity: 0; transform: scale(0.9) translateY(6px); } }
630
+
631
+ /* chart */
632
+ .b-chart { padding: 16px 18px 14px; }
633
+ .bars { display: flex; flex-direction: column; gap: 10px; }
634
+ .bar-row { display: grid; grid-template-columns: minmax(80px, 28%) 1fr auto; align-items: center; gap: 12px; animation: rise 0.5s var(--ease) calc(150ms + var(--k) * 90ms) both; }
635
+ .bar-label { font-size: 13px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
636
+ .bar-track { height: 8px; border-radius: 3px; background: var(--bg-2); overflow: hidden; }
637
+ .bar { display: block; height: 100%; width: var(--w); border-radius: 3px; background: var(--accent); transform-origin: left; animation: grow-x 0.8s var(--ease) calc(200ms + var(--k) * 100ms) both; }
638
+ .bar-row:nth-child(2n) .bar { background: color-mix(in srgb, var(--accent) 55%, var(--surface)); }
639
+ .bar-val { font: 500 13px var(--mono); font-variant-numeric: tabular-nums; min-width: 48px; text-align: right; }
640
+ .bar-val .u { color: var(--muted); margin-left: 2px; font-size: 11.5px; }
641
+ @keyframes grow-x { from { transform: scaleX(0); } }
642
+
643
+ /* terminal */
644
+ .b-term { border-radius: var(--radius); background: var(--term-bg); color: var(--term-ink); overflow: hidden; border: 1px solid var(--line); }
645
+ .term-head { display: flex; align-items: center; gap: 10px; padding: 8px 14px; border-bottom: 1px solid rgba(255, 255, 255, 0.07); font-size: 12px; color: #8a8a8a; }
646
+ .lights { display: none; }
647
+ .term-head .title { flex: 1; font-family: var(--mono); font-size: 11.5px; }
648
+ .exit { font: 500 11px var(--mono); padding: 1px 7px; border-radius: 5px; }
649
+ .exit.ok { background: rgba(76, 195, 138, 0.14); color: #4cc38a; }
650
+ .exit.bad { background: rgba(255, 99, 105, 0.14); color: #ff6369; }
651
+ .b-term pre { margin: 0; padding: 12px 14px 14px; font: 12.5px/1.6 var(--mono); white-space: pre-wrap; word-break: break-word; max-height: 440px; overflow-y: auto; }
652
+ .b-term .ps { color: #8a8a8a; }
653
+ .b-term .cmd { color: #fff; }
654
+ .b-term .caret { display: inline-block; width: 7px; height: 14px; margin-left: 1px; vertical-align: -2px; background: #e8e8e6; animation: blink 1s steps(1) infinite; }
655
+ .b-term.ran .caret { display: none; }
656
+ .b-term .out { color: #b4b4b0; opacity: 0; transition: opacity 0.4s; }
657
+ .b-term.ran .out { opacity: 1; }
658
+ @keyframes blink { 50% { opacity: 0; } }
659
+
660
+ /* tests */
661
+ .b-tests { padding: 18px 20px; }
662
+ .tests-main { display: flex; align-items: center; gap: 18px; position: relative; }
663
+ .ring { width: 76px; height: 76px; transform: rotate(-90deg); flex: none; }
664
+ .ring circle { fill: none; stroke-width: 7; }
665
+ .ring .track { stroke: var(--bg-2); }
666
+ .ring .seg { stroke-linecap: butt; animation: ring-in 1.3s var(--ease) 0.35s both; }
667
+ .ring .pass { stroke: var(--good); }
668
+ .ring .fail { stroke: var(--bad); }
669
+ .ring .skip { stroke: var(--line-2); }
670
+ .ring-label { position: absolute; left: 0; width: 76px; display: grid; place-items: center; }
671
+ .ring-label .i { width: 24px; height: 24px; }
672
+ .b-tests.ok .ring-label { color: var(--good); }
673
+ .b-tests.bad .ring-label { color: var(--bad); }
674
+ .verdict { font: 600 18px/1.25 var(--display); letter-spacing: -0.015em; }
675
+ .counts { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 4px; font-size: 13px; color: var(--muted); }
676
+ .counts b { font-weight: 600; font-variant-numeric: tabular-nums; }
677
+ .counts .pass b { color: var(--good); }
678
+ .counts .fail b { color: var(--bad); }
679
+ .cmdline { display: inline-block; margin-top: 8px; font-size: 12px; color: var(--muted); }
680
+ .failures { list-style: none; margin: 16px 0 0; padding: 12px 0 0; border-top: 1px solid var(--line); }
681
+ .failures li { display: flex; gap: 10px; padding: 6px 0; }
682
+ .failures li > .i { color: var(--bad); margin-top: 3px; }
683
+ .failures b { font-weight: 600; font-size: 13.5px; }
684
+ .failures pre { margin: 4px 0; padding: 8px 10px; border-radius: 8px; background: var(--del-bg); font-size: 12px; white-space: pre-wrap; color: var(--ink-2); }
685
+ .failures .file { font: 12px var(--mono); }
686
+ @keyframes ring-in { from { stroke-dasharray: 0 400; } }
687
+
688
+ /* commits */
689
+ .b-commits { padding: 16px 20px 10px; }
690
+ .b-commits .b-title .i { width: 14px; height: 14px; }
691
+ .b-commits ol { list-style: none; margin: 0; padding: 0; position: relative; }
692
+ .b-commits ol::before { content: ''; position: absolute; left: 6px; top: 8px; bottom: 16px; width: 2px; background: var(--line-2); transform-origin: top; animation: draw-y 0.9s var(--ease) 0.3s both; }
693
+ .b-commits li { display: grid; grid-template-columns: 14px 1fr; gap: 14px; padding-bottom: 12px; animation: rise 0.5s var(--ease) calc(300ms + var(--k) * 110ms) both; }
694
+ .b-commits .node { all: unset; width: 10px; height: 10px; margin-top: 5px; border-radius: 50%; background: var(--surface); border: 2px solid var(--ink-2); position: relative; z-index: 1; }
695
+ .b-commits .msg { font-weight: 500; }
696
+ .b-commits .sub { display: flex; gap: 10px; margin-top: 2px; font: 12px var(--mono); color: var(--muted); }
697
+ .b-commits .sub code { padding: 0 5px; }
698
+
699
+ /* checklist */
700
+ .b-check { padding: 16px 20px 12px; }
701
+ .b-check ul { list-style: none; margin: 0; padding: 0; }
702
+ .b-check li { display: flex; gap: 10px; padding: 5px 0; animation: rise 0.45s var(--ease) calc(200ms + var(--k) * 90ms) both; }
703
+ .b-check .box { display: grid; place-items: center; width: 18px; height: 18px; margin-top: 2px; border-radius: 6px; border: 1.5px solid var(--line-2); color: transparent; flex: none; }
704
+ .b-check .box .i { width: 12px; height: 12px; }
705
+ .b-check li.done .box { background: var(--good); border-color: var(--good); color: #fff; animation: check-in 0.4s var(--ease) calc(400ms + var(--k) * 90ms) both; }
706
+ .b-check li.done > span:last-child { color: var(--ink-2); }
707
+ .b-check li:not(.done) > span:last-child { color: var(--muted); }
708
+ @keyframes check-in { from { transform: scale(0.4); background: transparent; border-color: var(--line-2); } }
709
+
710
+ /* callout */
711
+ .b-callout { --t: var(--info); display: flex; gap: 12px; padding: 12px 14px; border-radius: var(--radius); background: color-mix(in srgb, var(--t) 5%, var(--surface)); border: 1px solid color-mix(in srgb, var(--t) 20%, var(--line)); }
712
+ .b-callout.tone-success { --t: var(--good); }
713
+ .b-callout.tone-warn { --t: var(--warn); }
714
+ .b-callout.tone-danger { --t: var(--bad); }
715
+ .b-callout .ic { color: var(--t); padding-top: 1px; }
716
+ .b-callout b { display: block; font-weight: 600; margin-bottom: 2px; color: var(--ink); }
717
+ .b-callout .prose { font-size: 14px; }
718
+
719
+ /* image */
720
+ .b-image { margin: 0; overflow: hidden; }
721
+ .b-image img { display: block; width: 100%; max-height: 520px; object-fit: contain; background: var(--surface-2); cursor: zoom-in; }
722
+ .b-image figcaption { padding: 10px 16px; font-size: 13px; color: var(--muted); border-top: 1px solid var(--line); }
723
+ .b-image.broken img { min-height: 80px; }
724
+ .lightbox { max-width: 92vw; max-height: 90vh; border-radius: 12px; box-shadow: var(--shadow-2); }
725
+
726
+ /* next */
727
+ .b-next { padding-top: 6px; }
728
+ .next-label { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 8px; }
729
+ .next-label .i { color: var(--muted); width: 14px; height: 14px; }
730
+ .chips { display: flex; flex-wrap: wrap; gap: 6px; }
731
+ .chip {
732
+ padding: 6px 12px; border-radius: 8px; background: var(--surface); border: 1px solid var(--line-2); font-size: 13px; color: var(--ink-2);
733
+ transition: border-color 0.15s, background 0.15s, color 0.15s; animation: rise 0.4s var(--ease) calc(200ms + var(--k) * 50ms) both; text-align: left;
734
+ }
735
+ .chip:hover { border-color: var(--faint); color: var(--ink); background: var(--surface-2); }
736
+
737
+ /* trail */
738
+ .trail { margin-top: 18px; }
739
+ .trail-bar { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; padding: 8px 2px; border-top: 1px dashed var(--line); font-size: 12px; color: var(--faint); }
740
+ .tb { display: inline-flex; align-items: center; gap: 5px; font-variant-numeric: tabular-nums; }
741
+ .tb .i { width: 13px; height: 13px; }
742
+ .trail-bar .link { font-size: 12px; }
743
+ .trail-body { padding: 8px 0 0; animation: rise 0.4s var(--ease); }
744
+ .trail-body .presentation { gap: 10px; }
745
+
746
+ /* ---------- per-item composer ---------- */
747
+ .composer {
748
+ padding: 6px 8px 8px 12px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--line);
749
+ transition: box-shadow 0.15s, border-color 0.15s;
750
+ }
751
+ .composer:focus-within { background: var(--surface); border-color: color-mix(in srgb, var(--accent) 55%, var(--line-2)); box-shadow: 0 0 0 3px var(--accent-soft); }
752
+ .composer textarea { min-height: 26px; font-size: 14px; padding: 6px 2px; }
753
+ .composer textarea:disabled { cursor: not-allowed; }
754
+ .c-bar { display: flex; align-items: center; gap: 8px; }
755
+ .c-hint { flex: 1; font-size: 11.5px; color: var(--faint); }
756
+ .send { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px; background: var(--ink); color: var(--bg); transition: opacity 0.15s; }
757
+ .send:hover { opacity: 0.86; }
758
+ .send:disabled { opacity: 0.5; }
759
+ .c-done { color: var(--muted); }
760
+ .c-done:hover { color: var(--good); }
761
+
762
+ /* attachments tray */
763
+ .tray { display: flex; flex-wrap: wrap; gap: 8px; padding: 4px 0 8px; }
764
+ .att {
765
+ position: relative; display: flex; align-items: center; gap: 8px; height: 44px; padding: 0 30px 0 4px; border-radius: 10px;
766
+ background: var(--surface-2); border: 1px solid var(--line); max-width: 240px; animation: pop 0.35s var(--ease);
767
+ }
768
+ .att img { width: 36px; height: 36px; border-radius: 7px; object-fit: cover; }
769
+ .att-ic { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 7px; background: var(--bg-2); color: var(--muted); }
770
+ .att-name { font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
771
+ .att-size { font-size: 11px; color: var(--faint); white-space: nowrap; }
772
+ .att-x { position: absolute; right: 6px; top: 50%; translate: 0 -50%; display: grid; place-items: center; width: 20px; height: 20px; border-radius: 6px; color: var(--muted); }
773
+ .att-x:hover { background: var(--bg-2); color: var(--ink); }
774
+ .att-x .i { width: 12px; height: 12px; }
775
+ .att.uploading::after { content: ''; position: absolute; left: 6px; right: 6px; bottom: 3px; height: 2px; border-radius: 2px; background: linear-gradient(90deg, transparent, var(--accent), transparent); background-size: 200% 100%; animation: shimmer 1.1s linear infinite; }
776
+ .att.failed { border-color: var(--bad); }
777
+
778
+ /* ---------- overlay, modals, menus, toasts ---------- */
779
+ .overlay {
780
+ position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: 20px;
781
+ background: rgba(0, 0, 0, 0.28);
782
+ opacity: 0; transition: opacity 0.2s;
783
+ }
784
+ .overlay.on { opacity: 1; }
785
+ .modal {
786
+ width: min(600px, 100%); max-height: 86vh; overflow-y: auto; padding: 18px 20px 20px; border-radius: 14px;
787
+ background: var(--surface); border: 1px solid var(--line); box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.35); transform: translateY(4px); transition: transform 0.2s var(--ease);
788
+ }
789
+ .overlay.on .modal { transform: none; }
790
+ .modal header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
791
+ .modal h2 { margin: 0; font: 600 18px/1.2 var(--display); letter-spacing: -0.015em; }
792
+ .modal h4 { margin: 22px 0 8px; font-size: 13px; font-weight: 600; color: var(--ink); }
793
+ .modal .hint { margin: 8px 0 0; font-size: 12.5px; color: var(--muted); }
794
+ .modal .hint code { font-size: 11.5px; padding: 1px 5px; border-radius: 5px; background: var(--bg-2); }
795
+ .add-row { display: flex; gap: 8px; }
796
+ .path-input { position: relative; flex: 1; display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 12px; border-radius: 11px; border: 1px solid var(--line-2); background: var(--surface-2); }
797
+ .path-input:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
798
+ .path-input .i { color: var(--muted); }
799
+ .path-input .browse { display: grid; place-items: center; margin-left: -4px; width: 26px; height: 26px; border-radius: 7px; }
800
+ .path-input .browse:hover { background: var(--bg-2); }
801
+ .path-input .browse:hover .i { color: var(--accent); }
802
+ .path-input input { flex: 1; border: 0; outline: 0; background: transparent; font: 13px var(--mono); }
803
+ .suggest { position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 2; padding: 4px; border-radius: 12px; background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-2); }
804
+ .suggest button { display: block; width: 100%; text-align: left; padding: 6px 10px; border-radius: 8px; font: 12.5px var(--mono); color: var(--ink-2); }
805
+ .suggest button:hover, .suggest button.on { background: var(--accent-soft); color: var(--ink); }
806
+ .plist { margin-top: 18px; display: flex; flex-direction: column; gap: 4px; }
807
+ .prow { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: 11px; transition: background 0.15s; }
808
+ .prow:hover { background: var(--surface-2); }
809
+ .swatch { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; }
810
+ .swatch:hover { background: var(--bg-2); }
811
+ .swatch .p-dot { width: 12px; height: 12px; }
812
+ .prow-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
813
+ .pname { border: 0; background: transparent; outline: 0; font-weight: 600; padding: 0; border-radius: 4px; }
814
+ .pname:focus { box-shadow: 0 0 0 3px var(--accent-soft); }
815
+ .ppath { font: 11.5px var(--mono); color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
816
+ .pcount { font-size: 12px; color: var(--muted); }
817
+ .found { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 6px; }
818
+ .found-item { display: grid; grid-template-columns: 16px 1fr; column-gap: 8px; text-align: left; padding: 8px 10px; border-radius: 11px; border: 1px solid var(--line); transition: all 0.15s; }
819
+ .found-item:hover { border-color: var(--accent); background: var(--accent-soft); }
820
+ .found-item .i { grid-row: span 2; margin-top: 2px; color: var(--accent); }
821
+ .found-item b { font-weight: 600; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
822
+ .found-item span { font: 11px var(--mono); color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
823
+ .settings-modal label { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 1px solid var(--line); }
824
+ .settings-modal label > span { font-weight: 500; }
825
+ .settings-modal input { flex: 1; max-width: 340px; height: 30px; border-radius: 9px; border: 1px solid var(--line); background: var(--surface-2); padding: 0 10px; font: 12px var(--mono); outline: 0; }
826
+ .agents { margin-top: 18px; }
827
+ .agent-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; font-size: 13px; }
828
+ .keys-modal { width: min(380px, 100%); }
829
+ .krow { display: flex; align-items: center; gap: 14px; padding: 6px 0; }
830
+ .krow kbd { min-width: 56px; text-align: center; font-size: 11.5px; }
831
+
832
+ .menu { position: fixed; z-index: 40; min-width: 220px; padding: 5px; border-radius: 13px; background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-2); animation: pop 0.2s var(--ease); }
833
+ .menu button { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 10px; border-radius: 8px; font-size: 13.5px; color: var(--ink-2); }
834
+ .menu button:hover { background: var(--bg-2); color: var(--ink); }
835
+ .menu .danger:hover { color: var(--bad); background: var(--del-bg); }
836
+ .menu.models { width: 260px; }
837
+ .menu.models button { padding: 8px 10px; outline: 0; }
838
+ .menu.models button:focus-visible { background: var(--bg-2); color: var(--ink); }
839
+ .mm-text { flex: 1; display: flex; flex-direction: column; gap: 1px; text-align: left; min-width: 0; }
840
+ .mm-text b { font-weight: 500; font-size: 13.5px; color: var(--ink); }
841
+ .mm-text small { font-size: 12px; color: var(--muted); }
842
+ .mm-check { width: 15px; height: 15px; color: var(--accent); visibility: hidden; }
843
+ .menu.models .on .mm-check { visibility: visible; }
844
+
845
+ .toasts { position: fixed; bottom: 22px; left: 50%; translate: -50% 0; z-index: 60; display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; }
846
+ .toast {
847
+ pointer-events: auto; display: flex; align-items: center; gap: 14px; padding: 9px 12px 9px 16px; border-radius: 13px; max-width: min(560px, 92vw);
848
+ background: var(--ink); color: var(--bg); box-shadow: var(--shadow-2); font-size: 13.5px; animation: toast-in 0.35s var(--ease);
849
+ transition: opacity 0.35s, transform 0.35s;
850
+ }
851
+ .toast .i { vertical-align: -3px; margin-right: 4px; }
852
+ .toast .link { color: color-mix(in srgb, var(--bg) 75%, var(--accent)); white-space: nowrap; }
853
+ .toast.bad { background: var(--bad); color: #fff; }
854
+ .toast.out { opacity: 0; transform: translateY(8px); }
855
+ @keyframes toast-in { from { opacity: 0; transform: translateY(12px) scale(0.97); } }
856
+
857
+ .flying-wisp {
858
+ position: fixed; z-index: 70; width: 12px; height: 12px; border-radius: 50%; pointer-events: none;
859
+ background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
860
+ }
861
+
862
+ @keyframes pulse { 50% { opacity: 0.35; } }
863
+ @keyframes ring { from { transform: scale(0.6); opacity: 0.9; } to { transform: scale(1.7); opacity: 0; } }
864
+ @keyframes shimmer { from { background-position: 100% 0; } to { background-position: -200% 0; } }
865
+
866
+ /* ---------- responsive ---------- */
867
+ @media (max-width: 720px) {
868
+ .topbar { padding: 0 12px; gap: 10px; }
869
+ .agent-status { display: none; }
870
+ .feed-wrap { padding: 14px 16px 80px; }
871
+ .it-side .q-proj, .it-actions span, .c-done span { display: none; }
872
+ .turns { padding: 6px 14px 8px; }
873
+ .it-dock { padding: 4px 10px 10px; }
874
+ .b-hero h2 { font-size: 22px; }
875
+ .b-compare { grid-template-columns: 1fr; gap: 8px; }
876
+ .b-compare .arrow { transform: rotate(90deg); height: 20px; }
877
+ .cols { flex-direction: column; gap: 30px; align-items: stretch; }
878
+ .col { max-width: none; flex-direction: row; justify-content: center; }
879
+ .col .node { flex: 1; max-width: 260px; }
880
+ }
881
+
882
+ @media (prefers-reduced-motion: reduce) {
883
+ *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; animation-delay: 0ms !important; transition-duration: 0.01ms !important; }
884
+ }
885
+
886
+ /* ---------- desktop (Electron) ---------- */
887
+ /* Drag regions swallow clicks even under overlays: only the top bar drags,
888
+ and everything clickable in it (or floating above it) opts out. */
889
+ .drag-strip { display: none; }
890
+ body.electron .topbar { -webkit-app-region: drag; }
891
+ body.electron .topbar button, body.electron .topbar a, body.electron .topbar .projects { -webkit-app-region: no-drag; }
892
+ body.electron .overlay, body.electron .overlay *, body.electron .menu, body.electron .menu *, body.electron .toasts, body.electron .toast * { -webkit-app-region: no-drag; }
893
+ body.electron.mac .topbar { padding-left: 88px; }