nexus-agentd 0.2.5 → 0.2.6

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.
@@ -1,617 +1,747 @@
1
- export const styles = String.raw `
2
- /* 全局设计约定:间距用 --sp-*、字号用 --fs-*,扩展时不要引入散落的像素值。 */
3
-
4
- :root {
5
- color-scheme: light;
6
- --background: 0 0% 100%;
7
- --foreground: 0 0% 3.9%;
8
- --card: 0 0% 100%;
9
- --card-foreground: 0 0% 3.9%;
10
- --popover: 0 0% 100%;
11
- --popover-foreground: 0 0% 3.9%;
12
- --primary: 0 0% 9%;
13
- --primary-foreground: 0 0% 98%;
14
- --secondary: 0 0% 96.1%;
15
- --secondary-foreground: 0 0% 9%;
16
- --muted: 0 0% 96.1%;
17
- --muted-foreground: 0 0% 45.1%;
18
- --accent: 0 0% 96.1%;
19
- --accent-foreground: 0 0% 9%;
20
- --destructive: 0 84.2% 60.2%;
21
- --destructive-foreground: 0 0% 98%;
22
- --success: 142 76% 36%;
23
- --warning: 32 95% 44%;
24
- --info: 217 91% 60%;
25
- --border: 0 0% 89.8%;
26
- --input: 0 0% 89.8%;
27
- --ring: 0 0% 63.9%;
28
-
29
- --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
30
- --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;
31
-
32
- /* 字号阶梯,全站只用这六级:
33
- 2xs 大写微标签(表头 / badge)· xs 辅助说明 · sm 正文与表格
34
- md 面板与 drawer 标题 · lg 页面标题 · stat 统计数字 */
35
- --fs-2xs: 11px; --fs-xs: 12px; --fs-sm: 13px;
36
- --fs-md: 14px; --fs-lg: 16px; --fs-stat: 28px;
37
-
38
- --radius: 6px;
39
- --sidebar-width: 232px;
40
- --gutter: clamp(var(--sp-6), 4vw, 48px);
41
- }
42
-
43
- html[data-theme="dark"] {
44
- color-scheme: dark;
45
- --background: 0 0% 3.9%;
46
- --foreground: 0 0% 98%;
47
- --card: 0 0% 3.9%;
48
- --card-foreground: 0 0% 98%;
49
- --popover: 0 0% 3.9%;
50
- --popover-foreground: 0 0% 98%;
51
- --primary: 0 0% 98%;
52
- --primary-foreground: 0 0% 9%;
53
- --secondary: 0 0% 14.9%;
54
- --secondary-foreground: 0 0% 98%;
55
- --muted: 0 0% 14.9%;
56
- --muted-foreground: 0 0% 63.9%;
57
- --accent: 0 0% 14.9%;
58
- --accent-foreground: 0 0% 98%;
59
- --destructive: 0 62.8% 30.6%;
60
- --destructive-foreground: 0 0% 98%;
61
- --success: 142 71% 45%;
62
- --warning: 38 92% 50%;
63
- --info: 217 91% 65%;
64
- --border: 0 0% 14.9%;
65
- --input: 0 0% 14.9%;
66
- --ring: 0 0% 83.1%;
67
- }
68
-
69
- /* ── Base ─────────────────────────────────────────────────────────── */
70
- *, *::before, *::after { box-sizing: border-box; }
71
- html, body { height: 100%; }
72
- html { scrollbar-gutter: stable; }
73
- body {
74
- margin: 0;
75
- background: hsl(var(--background));
76
- color: hsl(var(--foreground));
77
- font: var(--fs-sm)/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans",
78
- "PingFang SC", "Microsoft YaHei", Helvetica, Arial, sans-serif;
79
- -webkit-font-smoothing: antialiased;
80
- text-rendering: optimizeLegibility;
81
- }
82
- h1, h2, h3, p { margin: 0; }
83
- button, input, select, textarea { font: inherit; color: inherit; }
84
- button { background: none; border: 0; cursor: pointer; padding: 0; }
85
- code, .mono { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; }
86
- .hidden { display: none !important; }
87
- .muted { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); }
88
-
89
- :focus-visible {
90
- outline: 2px solid hsl(var(--ring));
91
- outline-offset: 1px;
92
- border-radius: 2px;
93
- }
94
-
95
- ::selection { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
96
-
97
- /* Thin scrollbars */
98
- ::-webkit-scrollbar { width: 10px; height: 10px; }
99
- ::-webkit-scrollbar-thumb { background: hsl(var(--muted-foreground) / .35); border-radius: 8px; border: 3px solid transparent; background-clip: content-box; }
100
- ::-webkit-scrollbar-thumb:hover { background-color: hsl(var(--muted-foreground) / .55); }
101
- ::-webkit-scrollbar-track { background: transparent; }
102
-
103
- /* ── Brand ────────────────────────────────────────────────────────── */
104
- .brand-mark {
105
- width: 28px; height: 28px;
106
- display: grid; place-items: center;
107
- background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
108
- border-radius: var(--radius);
109
- font-weight: 700; font-size: var(--fs-sm); letter-spacing: -.02em;
110
- flex-shrink: 0;
111
- }
112
-
113
- /* ── Auth screens ─────────────────────────────────────────────────── */
114
- .auth-screen {
115
- min-height: 100vh;
116
- display: grid; place-items: center;
117
- padding: var(--sp-6);
118
- background: hsl(var(--muted) / .4);
119
- }
120
- .auth-card {
121
- width: min(400px, 100%);
122
- padding: var(--sp-6);
123
- background: hsl(var(--card));
124
- border: 1px solid hsl(var(--border));
125
- border-radius: calc(var(--radius) + 2px);
126
- box-shadow: 0 1px 2px rgb(0 0 0 / .05), 0 8px 24px -8px rgb(0 0 0 / .1);
127
- }
128
- .auth-card header { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-5); }
129
- .auth-card h1 { font-size: var(--fs-lg); font-weight: 600; letter-spacing: -.01em; }
130
- .auth-card > p { color: hsl(var(--muted-foreground)); font-size: var(--fs-sm); margin-bottom: var(--sp-5); }
131
- .auth-submit { width: 100%; height: 36px; }
132
- .avatar {
133
- width: 26px; height: 26px; flex-shrink: 0;
134
- display: grid; place-items: center;
135
- background: hsl(var(--secondary)); color: hsl(var(--secondary-foreground));
136
- border-radius: 50%;
137
- font-size: var(--fs-2xs); font-weight: 700;
138
- }
139
-
140
- /* ── Forms ────────────────────────────────────────────────────────── */
141
- .field { display: grid; gap: var(--sp-2); margin-bottom: var(--sp-4); font-size: var(--fs-sm); font-weight: 500; }
142
- .field > small, .field-help { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); font-weight: 400; line-height: 1.5; }
143
- .field-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-4); align-items: start; }
144
-
145
- input, select, textarea {
146
- width: 100%; height: 32px;
147
- padding: 0 var(--sp-3);
148
- background: transparent;
149
- border: 1px solid hsl(var(--input));
150
- border-radius: var(--radius);
151
- font-size: var(--fs-sm);
152
- transition: border-color .12s ease, box-shadow .12s ease;
153
- }
154
- textarea { height: auto; min-height: 72px; padding: var(--sp-2) var(--sp-3); resize: vertical; line-height: 1.5; }
155
- input:hover, select:hover, textarea:hover { border-color: hsl(var(--muted-foreground) / .6); }
156
- input:focus, select:focus, textarea:focus { outline: none; border-color: hsl(var(--ring)); box-shadow: 0 0 0 2px hsl(var(--ring) / .2); }
157
- input:disabled, select:disabled, textarea:disabled { opacity: .5; cursor: not-allowed; }
158
- input[type="checkbox"] { width: 14px; height: 14px; padding: 0; accent-color: hsl(var(--primary)); }
159
-
160
- .checkbox { display: flex; align-items: center; gap: var(--sp-2); height: 32px; font-weight: 500; cursor: pointer; }
161
- .checkbox input { flex-shrink: 0; }
162
-
163
- .form-error { min-height: 18px; margin-top: var(--sp-2); color: hsl(var(--destructive)); font-size: var(--fs-xs); font-weight: 500; }
164
- .confirm-text { color: hsl(var(--muted-foreground)); font-size: var(--fs-sm); line-height: 1.6; }
165
-
166
- /* ── Buttons ──────────────────────────────────────────────────────── */
167
- .button {
168
- display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
169
- height: 32px; padding: 0 var(--sp-3);
170
- border: 1px solid hsl(var(--input));
171
- border-radius: var(--radius);
172
- background: hsl(var(--card));
173
- font-size: var(--fs-sm); font-weight: 500; white-space: nowrap;
174
- box-shadow: 0 1px 2px rgb(0 0 0 / .04);
175
- transition: background-color .12s ease, border-color .12s ease;
176
- }
177
- .button:hover:not(:disabled) { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
178
- .button:disabled { opacity: .5; cursor: not-allowed; }
179
- .button.primary { background: hsl(var(--primary)); border-color: hsl(var(--primary)); color: hsl(var(--primary-foreground)); }
180
- .button.primary:hover:not(:disabled) { background: hsl(var(--primary) / .88); color: hsl(var(--primary-foreground)); }
181
- .button.danger { border-color: hsl(var(--destructive) / .5); color: hsl(var(--destructive)); }
182
- .button.danger:hover:not(:disabled) { background: hsl(var(--destructive) / .08); }
183
- .button.solid-danger { background: hsl(var(--destructive)); border-color: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); }
184
- .button.solid-danger:hover:not(:disabled) { background: hsl(var(--destructive) / .9); color: hsl(var(--destructive-foreground)); }
185
- .button.small { height: 26px; padding: 0 var(--sp-2); font-size: var(--fs-xs); }
186
- .button svg, .menu-button svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
187
-
188
- .icon-button {
189
- display: inline-flex; align-items: center; justify-content: center;
190
- width: 32px; height: 32px; flex-shrink: 0;
191
- border-radius: var(--radius);
192
- color: hsl(var(--muted-foreground));
193
- transition: background-color .12s ease, color .12s ease;
194
- }
195
- .icon-button:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
196
- .icon-button svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
197
-
198
- /* ── App shell ────────────────────────────────────────────────────── */
199
- .app-shell { min-height: 100vh; display: flex; }
200
-
201
- .sidebar {
202
- position: fixed; inset: 0 auto 0 0;
203
- width: var(--sidebar-width);
204
- padding: var(--sp-3) var(--sp-2);
205
- display: flex; flex-direction: column; gap: var(--sp-2);
206
- background: hsl(var(--card));
207
- border-right: 1px solid hsl(var(--border));
208
- z-index: 10;
209
- }
210
- .brand {
211
- display: flex; align-items: center; gap: var(--sp-2);
212
- height: 40px; padding: 0 var(--sp-2);
213
- font-weight: 600; font-size: var(--fs-sm); letter-spacing: -.01em;
214
- }
215
- nav { display: flex; flex-direction: column; gap: 2px; }
216
- .nav-item {
217
- width: 100%; height: 32px;
218
- display: flex; align-items: center; gap: var(--sp-2);
219
- padding: 0 var(--sp-2);
220
- border-radius: var(--radius);
221
- color: hsl(var(--muted-foreground));
222
- font-size: var(--fs-sm); font-weight: 500; text-align: left;
223
- transition: background-color .12s ease, color .12s ease;
224
- }
225
- .nav-item:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
226
- .nav-item.active { background: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); font-weight: 600; }
227
- .nav-item svg { width: 15px; height: 15px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
228
-
229
- .admin-menu-wrap { position: relative; margin-top: auto; }
230
- .admin-button {
231
- width: 100%; display: flex; align-items: center; gap: var(--sp-2);
232
- padding: var(--sp-2);
233
- border-radius: var(--radius);
234
- text-align: left;
235
- transition: background-color .12s ease;
236
- }
237
- .admin-button:hover { background: hsl(var(--accent)); }
238
- .admin-button > svg { width: 15px; height: 15px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
239
- .admin-meta { display: grid; min-width: 0; }
240
- .admin-button strong { font-size: var(--fs-sm); font-weight: 600; }
241
- .admin-popover {
242
- position: absolute; inset: auto 0 calc(100% + var(--sp-2));
243
- padding: var(--sp-2);
244
- background: hsl(var(--popover));
245
- border: 1px solid hsl(var(--border));
246
- border-radius: calc(var(--radius) + 2px);
247
- box-shadow: 0 8px 24px -4px rgb(0 0 0 / .12), 0 2px 8px -2px rgb(0 0 0 / .08);
248
- z-index: 20;
249
- }
250
- .admin-popover .field { margin-bottom: var(--sp-2); font-size: var(--fs-xs); }
251
- .menu-button {
252
- width: 100%; height: 30px;
253
- display: flex; align-items: center;
254
- padding: 0 var(--sp-2);
255
- border-radius: var(--radius);
256
- font-size: var(--fs-sm); font-weight: 500; text-align: left;
257
- transition: background-color .12s ease;
258
- }
259
- .menu-button:hover { background: hsl(var(--accent)); }
260
- .danger-text { color: hsl(var(--destructive)); }
261
-
262
- /* ── Main / page chrome ───────────────────────────────────────────── */
263
- .main {
264
- flex: 1; min-width: 0;
265
- margin-left: var(--sidebar-width);
266
- min-height: 100vh;
267
- display: flex; flex-direction: column;
268
- }
269
- .topbar {
270
- position: sticky; top: 0; z-index: 5;
271
- height: 56px;
272
- display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
273
- padding: 0 var(--gutter);
274
- background: hsl(var(--background));
275
- border-bottom: 1px solid hsl(var(--border));
276
- }
277
- .topbar h1 { font-size: var(--fs-lg); font-weight: 600; letter-spacing: -.01em; }
278
- .page-actions { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
279
-
280
- .page-content {
281
- flex: 1; width: 100%;
282
- padding: var(--sp-5) var(--gutter) var(--sp-6);
283
- display: flex; flex-direction: column; gap: var(--sp-4);
284
- }
285
-
286
- /* ── Cards / panels ───────────────────────────────────────────────── */
287
- .panel {
288
- background: hsl(var(--card));
289
- border: 1px solid hsl(var(--border));
290
- border-radius: calc(var(--radius) + 2px);
291
- }
292
- .panel-header {
293
- min-height: 44px;
294
- padding: 0 var(--sp-4);
295
- display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
296
- border-bottom: 1px solid hsl(var(--border));
297
- }
298
- .panel-header h2 { font-size: var(--fs-md); font-weight: 600; }
299
- .panel-body { padding: var(--sp-4); }
300
- .empty { padding: var(--sp-8) var(--sp-4); color: hsl(var(--muted-foreground)); text-align: center; font-size: var(--fs-sm); }
301
- .empty-state { display: grid; justify-items: center; gap: var(--sp-1); padding: var(--sp-8) var(--sp-4); text-align: center; }
302
- .empty-state > svg { width: 28px; height: 28px; margin-bottom: var(--sp-2); color: hsl(var(--muted-foreground)); fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
303
- .empty-state strong { font-size: var(--fs-md); font-weight: 600; color: hsl(var(--foreground)); }
304
- .empty-state span { font-size: var(--fs-xs); color: hsl(var(--muted-foreground)); }
305
- .empty-state .button { margin-top: var(--sp-3); }
306
-
307
- /* Stats */
308
- .stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-4); }
309
- .stat {
310
- padding: var(--sp-4) var(--sp-5);
311
- background: hsl(var(--card));
312
- border: 1px solid hsl(var(--border));
313
- border-radius: calc(var(--radius) + 2px);
314
- display: grid; gap: var(--sp-1);
315
- }
316
- .stat span { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); font-weight: 500; }
317
- .stat strong { font-size: var(--fs-stat); font-weight: 600; letter-spacing: -.02em; line-height: 1.2; font-variant-numeric: tabular-nums; }
318
-
319
- /* ── Toolbar ──────────────────────────────────────────────────────── */
320
- .toolbar { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
321
- .toolbar select { width: auto; min-width: 128px; }
322
- .search-box { position: relative; flex: 1; min-width: 160px; max-width: 280px; }
323
- .search-box svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; color: hsl(var(--muted-foreground)); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
324
- .search-box input { width: 100%; padding-left: 30px; }
325
-
326
- /* ── Tables ───────────────────────────────────────────────────────── */
327
- .table-wrap {
328
- overflow-x: auto;
329
- background: hsl(var(--card));
330
- border: 1px solid hsl(var(--border));
331
- border-radius: calc(var(--radius) + 2px);
332
- }
333
- table { width: 100%; border-collapse: collapse; min-width: 720px; }
334
- th, td { padding: 0 var(--sp-4); height: 40px; border-bottom: 1px solid hsl(var(--border)); text-align: left; vertical-align: middle; }
335
- th { height: 36px; color: hsl(var(--muted-foreground)); font-size: var(--fs-2xs); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; }
336
- tbody tr:last-child td { border-bottom: 0; }
337
- tbody tr:hover { background: hsl(var(--muted) / .5); }
338
- tr[data-run-detail] { cursor: pointer; }
339
-
340
- .agent-name { display: grid; gap: 2px; min-width: 0; }
341
- .agent-name strong { font-size: var(--fs-sm); font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
342
- .agent-name small { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
343
- .error-detail { color: hsl(var(--destructive)); font-size: var(--fs-sm); overflow-wrap: anywhere; line-height: 1.4; }
344
- .row-actions { display: flex; justify-content: flex-end; gap: var(--sp-2); }
345
-
346
- /* ── Badges & status ──────────────────────────────────────────────── */
347
- .badge {
348
- display: inline-flex; align-items: center;
349
- height: 20px; padding: 0 var(--sp-2);
350
- border: 1px solid hsl(var(--border));
351
- border-radius: 4px;
352
- background: hsl(var(--secondary));
353
- color: hsl(var(--secondary-foreground));
354
- font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
355
- }
356
- .status {
357
- display: inline-flex; align-items: center; gap: var(--sp-2);
358
- height: 22px; padding: 0 var(--sp-2);
359
- border-radius: 9999px;
360
- background: hsl(var(--secondary));
361
- color: hsl(var(--muted-foreground));
362
- font-size: var(--fs-xs); font-weight: 500; white-space: nowrap;
363
- }
364
- .status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: hsl(var(--muted-foreground) / .5); flex-shrink: 0; }
365
- .status.ready, .status.completed { color: hsl(var(--success)); background: hsl(var(--success) / .1); }
366
- .status.ready::before, .status.completed::before { background: hsl(var(--success)); }
367
- .status.failed { color: hsl(var(--destructive)); background: hsl(var(--destructive) / .1); }
368
- .status.failed::before { background: hsl(var(--destructive)); }
369
- .status.running { color: hsl(var(--info)); background: hsl(var(--info) / .1); }
370
- .status.running::before { background: hsl(var(--info)); animation: pulse 2s cubic-bezier(.4, 0, .6, 1) infinite; }
371
- .status.waiting { color: hsl(var(--warning)); background: hsl(var(--warning) / .12); }
372
- .status.waiting::before { background: hsl(var(--warning)); animation: pulse 2s cubic-bezier(.4, 0, .6, 1) infinite; }
373
- .status.checking::before { animation: pulse 2s cubic-bezier(.4, 0, .6, 1) infinite; }
374
- @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }
375
-
376
- /* ── Runs page ────────────────────────────────────────────────────── */
377
- .run-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-4); }
378
- .run-section { display: flex; flex-direction: column; gap: var(--sp-3); }
379
- .run-section-title { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); }
380
- .run-section-title h2 { font-size: var(--fs-md); font-weight: 600; }
381
- .run-section-title span { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); }
382
-
383
- .run-live-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--sp-3); }
384
- .run-card {
385
- position: relative;
386
- display: flex; flex-direction: column; gap: var(--sp-2);
387
- padding: var(--sp-3) var(--sp-4);
388
- background: hsl(var(--card));
389
- border: 1px solid hsl(var(--border));
390
- border-left: 3px solid hsl(var(--info));
391
- border-radius: calc(var(--radius) + 2px);
392
- cursor: pointer;
393
- transition: border-color .12s ease, box-shadow .12s ease;
394
- }
395
- .run-card:hover { border-color: hsl(var(--muted-foreground) / .4); box-shadow: 0 2px 8px -2px rgb(0 0 0 / .08); }
396
- .run-card.waiting { border-left-color: hsl(var(--warning)); }
397
- .run-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
398
- .run-card-agent { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
399
- .run-card-agent strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-sm); font-weight: 600; }
400
- .run-task {
401
- display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
402
- overflow: hidden;
403
- color: hsl(var(--foreground));
404
- font-size: var(--fs-sm); line-height: 1.5;
405
- white-space: pre-wrap;
406
- }
407
- .run-progress { display: grid; gap: 2px; }
408
- .run-progress strong { font-size: var(--fs-xs); font-weight: 600; }
409
- .run-progress small { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
410
- .run-meta {
411
- display: flex; align-items: center; justify-content: space-between;
412
- color: hsl(var(--muted-foreground));
413
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
414
- font-size: var(--fs-2xs); line-height: 1.4;
415
- font-variant-numeric: tabular-nums;
416
- }
417
- .run-table { min-width: 880px; }
418
- .run-table .run-task-cell { max-width: 360px; }
419
- .run-table th.num, .run-table td.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
420
- .run-task-cell strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; font-size: var(--fs-sm); }
421
- .run-task-cell small { display: block; margin-top: 2px; color: hsl(var(--muted-foreground)); font-size: var(--fs-2xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
422
-
423
- /* Run detail (drawer) */
424
- .run-detail-grid {
425
- display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
426
- margin-bottom: var(--sp-4);
427
- border: 1px solid hsl(var(--border));
428
- border-radius: calc(var(--radius) + 2px);
429
- overflow: hidden;
430
- background: hsl(var(--border));
431
- }
432
- .run-detail-item { padding: var(--sp-3); background: hsl(var(--card)); display: grid; gap: var(--sp-1); align-content: start; }
433
- .run-detail-item span { color: hsl(var(--muted-foreground)); font-size: var(--fs-2xs); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; }
434
- .run-detail-item strong { font-size: var(--fs-sm); font-weight: 500; overflow-wrap: anywhere; }
435
- .run-detail-block { margin-bottom: var(--sp-4); }
436
- .run-detail-block h3 { margin: 0 0 var(--sp-2); color: hsl(var(--muted-foreground)); font-size: var(--fs-2xs); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; }
437
- .run-detail-code {
438
- margin: 0; padding: var(--sp-3);
439
- max-height: 320px; overflow: auto;
440
- border: 1px solid hsl(var(--border));
441
- border-radius: var(--radius);
442
- background: hsl(var(--muted) / .4);
443
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
444
- font-size: var(--fs-xs); line-height: 1.6;
445
- overflow-wrap: anywhere; white-space: pre-wrap;
446
- }
447
- .run-id { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
448
-
449
- /* ── Lists (workspaces, overview, artifacts) ──────────────────────── */
450
- .workspace-list, .overview-list { display: grid; gap: var(--sp-2); }
451
- .list-row {
452
- min-height: 48px;
453
- display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
454
- padding: var(--sp-3) var(--sp-4);
455
- background: hsl(var(--card));
456
- border: 1px solid hsl(var(--border));
457
- border-radius: calc(var(--radius) + 2px);
458
- transition: border-color .12s ease;
459
- }
460
- .list-row:hover { border-color: hsl(var(--muted-foreground) / .4); }
461
- .list-row-main { display: grid; gap: 2px; min-width: 0; }
462
- .list-row-main strong, .path { font-size: var(--fs-sm); font-weight: 600; overflow-wrap: anywhere; }
463
- .list-row-main small { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); }
464
- .panel-body > .workspace-list, .panel-body > .overview-list { gap: var(--sp-2); }
465
- .panel-body .list-row { border-radius: var(--radius); }
466
-
467
- /* ── API keys ─────────────────────────────────────────────────────── */
468
- .key-table { min-width: 0; width: 100%; table-layout: fixed; }
469
- .key-table th:nth-child(1) { width: 21%; }
470
- .key-table th:nth-child(2) { width: 15%; }
471
- .key-table th:nth-child(3) { width: 20%; }
472
- .key-table th:nth-child(4) { width: 15%; }
473
- .key-table th:nth-child(5) { width: 15%; }
474
- .key-table th:nth-child(6) { width: 14%; }
475
- .key-table th, .key-table td { padding-left: 10px; padding-right: 10px; }
476
- .key-table-wrap { overflow-x: hidden; }
477
- .key-table th:last-child, .key-table td:last-child { text-align: right; }
478
- .key-secret-cell { display: flex; align-items: center; gap: var(--sp-2); white-space: nowrap; }
479
- .key-secret-cell code { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); letter-spacing: .02em; }
480
- .key-copy-button, .key-icon-button {
481
- display: inline-flex; align-items: center; justify-content: center;
482
- width: 28px; height: 28px;
483
- border-radius: var(--radius);
484
- color: hsl(var(--muted-foreground));
485
- cursor: pointer;
486
- transition: background-color .12s ease, color .12s ease, box-shadow .12s ease;
487
- }
488
- .key-copy-button:hover, .key-icon-button:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
489
- .key-icon-button[aria-expanded="true"] {
490
- background: hsl(var(--accent)); color: hsl(var(--accent-foreground));
491
- box-shadow: 0 0 0 2px hsl(var(--ring) / .35);
492
- }
493
- .key-copy-button svg, .key-icon-button svg, .key-action-menu svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
494
- .key-icon-button.danger-action { color: hsl(var(--destructive)); }
495
- .key-icon-button.danger-action:hover { background: hsl(var(--destructive) / .08); }
496
- .key-scope, .key-last-used { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); }
497
- .key-actions { display: inline-flex; align-items: center; justify-content: flex-end; gap: 2px; }
498
-
499
- .key-action-menu {
500
- position: fixed; z-index: 50;
501
- width: 188px; padding: var(--sp-1);
502
- background: hsl(var(--popover));
503
- border: 1px solid hsl(var(--border));
504
- border-radius: calc(var(--radius) + 2px);
505
- box-shadow: 0 8px 24px -4px rgb(0 0 0 / .12), 0 2px 8px -2px rgb(0 0 0 / .08);
506
- }
507
- .key-action-menu button {
508
- width: 100%; height: 30px;
509
- display: flex; align-items: center; gap: var(--sp-2);
510
- padding: 0 var(--sp-2);
511
- border-radius: var(--radius);
512
- font-size: var(--fs-sm); font-weight: 500; text-align: left;
513
- transition: background-color .12s ease;
514
- }
515
- .key-action-menu button:hover { background: hsl(var(--accent)); }
516
- .key-action-menu button.danger-text { margin-top: var(--sp-1); border-top: 1px solid hsl(var(--border)); border-radius: 0 0 var(--radius) var(--radius); height: 34px; }
517
- .key-action-menu button.danger-text:hover { background: hsl(var(--destructive) / .08); }
518
-
519
- .agent-scope {
520
- max-height: 168px; overflow: auto;
521
- display: grid; gap: 2px;
522
- padding: var(--sp-2);
523
- margin-bottom: var(--sp-4);
524
- border: 1px solid hsl(var(--border));
525
- border-radius: var(--radius);
526
- background: hsl(var(--muted) / .4);
527
- }
528
- .agent-scope .checkbox { height: 28px; padding: 0 var(--sp-2); border-radius: var(--radius); }
529
- .agent-scope .checkbox:hover { background: hsl(var(--accent)); }
530
- .secret-box { display: grid; gap: var(--sp-3); }
531
- .secret-value {
532
- display: block; padding: var(--sp-3);
533
- background: hsl(var(--muted) / .5);
534
- border: 1px solid hsl(var(--border));
535
- border-radius: var(--radius);
536
- overflow-wrap: anywhere;
537
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
538
- font-size: var(--fs-xs);
539
- }
540
-
541
- /* ── Drawer ───────────────────────────────────────────────────────── */
542
- .drawer-backdrop { position: fixed; inset: 0; background: rgb(0 0 0 / .4); z-index: 40; animation: fadeIn .18s ease-out; }
543
- .drawer {
544
- position: fixed; inset: 0 0 0 auto;
545
- width: min(480px, 100vw);
546
- display: flex; flex-direction: column;
547
- background: hsl(var(--card));
548
- border-left: 1px solid hsl(var(--border));
549
- box-shadow: -8px 0 32px -8px rgb(0 0 0 / .15);
550
- z-index: 41;
551
- animation: slideInRight .22s cubic-bezier(.32, .72, 0, 1);
552
- overflow: hidden;
553
- }
554
- .drawer-header {
555
- height: 52px; flex-shrink: 0;
556
- display: flex; align-items: center; justify-content: space-between;
557
- padding: 0 var(--sp-4);
558
- border-bottom: 1px solid hsl(var(--border));
559
- }
560
- .drawer-header h2 { font-size: var(--fs-md); font-weight: 600; }
561
- .drawer-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: var(--sp-4); }
562
- .drawer-footer {
563
- flex: 0 0 auto;
564
- display: flex; justify-content: flex-end; gap: var(--sp-2);
565
- padding: var(--sp-3) var(--sp-4) var(--sp-4);
566
- border-top: 1px solid hsl(var(--border));
567
- background: hsl(var(--card));
568
- }
569
- @keyframes fadeIn { from { opacity: 0; } }
570
- @keyframes slideInRight { from { transform: translateX(16px); opacity: 0; } }
571
-
572
- /* ── Settings ─────────────────────────────────────────────────────── */
573
- .settings-layout { width: 100%; max-width: 680px; }
574
- .settings-form .panel-header { min-height: 0; padding: var(--sp-4); }
575
- .settings-fields { display: grid; padding: var(--sp-4); }
576
- .settings-fields .field:last-child { margin-bottom: 0; }
577
- .settings-fields .field input { max-width: 240px; }
578
- .settings-actions { display: flex; justify-content: flex-end; padding: var(--sp-4); }
579
-
580
- /* ── Toast ────────────────────────────────────────────────────────── */
581
- .toast-region {
582
- position: fixed; right: var(--sp-6); bottom: var(--sp-6);
583
- z-index: 60;
584
- display: grid; gap: var(--sp-2);
585
- max-width: 360px;
586
- }
587
- .toast {
588
- padding: var(--sp-3) var(--sp-4);
589
- background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
590
- border-radius: var(--radius);
591
- box-shadow: 0 8px 24px -4px rgb(0 0 0 / .18);
592
- font-size: var(--fs-sm); font-weight: 500; line-height: 1.5;
593
- animation: slideInUp .2s ease;
594
- }
595
- .toast.error { background: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); }
596
- @keyframes slideInUp { from { opacity: 0; transform: translateY(8px); } }
597
-
598
- /* ── Responsive ───────────────────────────────────────────────────── */
599
- @media (max-width: 860px) {
600
- :root { --sidebar-width: 56px; --gutter: var(--sp-4); }
601
- .brand span:last-child, .nav-item span, .admin-meta { display: none; }
602
- .brand, .nav-item, .admin-button { justify-content: center; }
603
- .admin-popover { left: 0; right: auto; width: 200px; }
604
- }
605
- @media (max-width: 640px) {
606
- .page-content { padding: var(--sp-4) var(--gutter) var(--sp-4); }
607
- .search-box { max-width: none; }
608
- .stats { grid-template-columns: 1fr; }
609
- .run-summary { grid-template-columns: repeat(2, 1fr); }
610
- .run-live-grid { grid-template-columns: 1fr; }
611
- .toolbar input[type="search"], .toolbar select { max-width: none; width: 100%; }
612
- .field-row { grid-template-columns: 1fr; }
613
- .drawer { width: 100vw; }
614
- .run-detail-grid { grid-template-columns: 1fr; }
615
- .toast-region { right: var(--sp-4); bottom: var(--sp-4); left: var(--sp-4); max-width: none; }
616
- }
1
+ // This file is generated by scripts/generate-webui-sources.mjs — do not edit by hand.
2
+ // Edit src/webui/styles.css instead.
3
+ export const styles = String.raw `
4
+ /* 全局设计约定:间距用 --sp-*、字号用 --fs-*、投影用 --shadow-*、层级用 --z-*、
5
+ 动效用 --duration-* / --ease-*,扩展时不要引入散落的像素值或字面量。 */
6
+
7
+ :root {
8
+ color-scheme: light;
9
+ --background: 0 0% 100%;
10
+ --foreground: 0 0% 3.9%;
11
+ --card: 0 0% 100%;
12
+ --card-foreground: 0 0% 3.9%;
13
+ --popover: 0 0% 100%;
14
+ --popover-foreground: 0 0% 3.9%;
15
+ --primary: 0 0% 9%;
16
+ --primary-foreground: 0 0% 98%;
17
+ --secondary: 0 0% 96.1%;
18
+ --secondary-foreground: 0 0% 9%;
19
+ --muted: 0 0% 96.1%;
20
+ --muted-foreground: 0 0% 45.1%;
21
+ --accent: 0 0% 96.1%;
22
+ --accent-foreground: 0 0% 9%;
23
+ /* 状态色既作文字也作自己的 10% 染色底,取值按两种情况都过 AA 4.5:1 反解。
24
+ 下面是浏览器实测值(元素真实计算色 + alpha 合成后的背景),不是手算:
25
+ status failed 4.58 · ready 4.79 · waiting 4.63 · running 4.62 · solid-danger 白字 5.21
26
+ · form-error / danger-text / error-detail / button.danger 5.43。
27
+ --border 是装饰性分隔(WCAG 1.4.11 豁免,不动);--input 是识别输入框与按钮的唯一
28
+ 线索,需 ≥3:1,实测 3.15;--ring 焦点环需 ≥3:1,实测 3.15。调亮前先重测。 */
29
+ --destructive: 0 84.2% 45%;
30
+ --destructive-text: 0 84.2% 45%;
31
+ --destructive-foreground: 0 0% 98%;
32
+ --success: 142 76% 27%;
33
+ --warning: 32 95% 32%;
34
+ --info: 217 91% 48.5%;
35
+ --border: 0 0% 89.8%;
36
+ --input: 0 0% 57%;
37
+ --ring: 0 0% 56%;
38
+
39
+ --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
40
+ --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;
41
+
42
+ /* 字号阶梯,全站只用这六级:
43
+ 2xs 大写微标签(表头 / badge)· xs 辅助说明 · sm 正文与表格
44
+ md 面板与 drawer 标题 · lg 页面标题 · stat 统计数字 */
45
+ --fs-2xs: 11px; --fs-xs: 12px; --fs-sm: 13px;
46
+ --fs-md: 14px; --fs-lg: 16px; --fs-stat: 28px;
47
+
48
+ --radius: 6px;
49
+ --radius-lg: calc(var(--radius) + 2px);
50
+ --sidebar-width: 232px;
51
+ --gutter: clamp(var(--sp-6), 4vw, 48px);
52
+
53
+ /* 投影。--shadow-ring-* 是焦点环(用 ring 色描边),不是投影,不要与 elevation 混用。 */
54
+ --shadow-xs: 0 1px 2px rgb(0 0 0 / .04);
55
+ --shadow-sm: 0 2px 8px -2px rgb(0 0 0 / .08);
56
+ --shadow-md: 0 8px 24px -4px rgb(0 0 0 / .12), 0 2px 8px -2px rgb(0 0 0 / .08);
57
+ --shadow-card: 0 1px 2px rgb(0 0 0 / .05), 0 8px 24px -8px rgb(0 0 0 / .1);
58
+ --shadow-drawer: -8px 0 32px -8px rgb(0 0 0 / .15);
59
+ --shadow-toast: 0 8px 24px -4px rgb(0 0 0 / .18);
60
+ --shadow-ring-focus: 0 0 0 2px hsl(var(--ring) / .2);
61
+ --shadow-ring-selected: 0 0 0 2px hsl(var(--ring) / .35);
62
+
63
+ /* 层级。drawer 必须压在 backdrop 之上,menu 与 toast 再往上。 */
64
+ --z-topbar: 5;
65
+ --z-sidebar: 10;
66
+ --z-backdrop: 40;
67
+ --z-drawer: 41;
68
+ --z-menu: 50;
69
+ --z-toast: 60;
70
+
71
+ --duration-fast: .12s;
72
+ --duration-fade: .18s;
73
+ --duration-toast: .2s;
74
+ --duration-slide: .22s;
75
+ --duration-pulse: 2s;
76
+ --ease-standard: ease;
77
+ --ease-out: ease-out;
78
+ --ease-drawer: cubic-bezier(.32, .72, 0, 1);
79
+ --ease-pulse: cubic-bezier(.4, 0, .6, 1);
80
+ }
81
+
82
+ html[data-theme="dark"] {
83
+ color-scheme: dark;
84
+ --background: 0 0% 3.9%;
85
+ --foreground: 0 0% 98%;
86
+ --card: 0 0% 3.9%;
87
+ --card-foreground: 0 0% 98%;
88
+ --popover: 0 0% 3.9%;
89
+ --popover-foreground: 0 0% 98%;
90
+ --primary: 0 0% 98%;
91
+ --primary-foreground: 0 0% 9%;
92
+ --secondary: 0 0% 14.9%;
93
+ --secondary-foreground: 0 0% 98%;
94
+ --muted: 0 0% 14.9%;
95
+ --muted-foreground: 0 0% 63.9%;
96
+ --accent: 0 0% 14.9%;
97
+ --accent-foreground: 0 0% 98%;
98
+ /* destructive 是唯一「作按钮底要暗、作文字要亮」的颜色,所以暗色必须拆两个令牌:
99
+ 基色 30.6% 配白字 9.59,文字色 58% 在自己的染色底上 4.52;把基色提到 58% 会让
100
+ 实心危险按钮掉到 3.88。其余状态色在暗色染色底上已有 7.60 / 7.86 / 5.85,无需拆分。 */
101
+ --destructive: 0 62.8% 30.6%;
102
+ --destructive-text: 0 62.8% 58%;
103
+ --destructive-foreground: 0 0% 98%;
104
+ --success: 142 71% 45%;
105
+ --warning: 38 92% 50%;
106
+ --info: 217 91% 65%;
107
+ --border: 0 0% 14.9%;
108
+ --input: 0 0% 40%;
109
+ --ring: 0 0% 83.1%;
110
+ }
111
+
112
+ /* ── Base ─────────────────────────────────────────────────────────── */
113
+ *, *::before, *::after { box-sizing: border-box; }
114
+ html, body { height: 100%; }
115
+ html { scrollbar-gutter: stable; }
116
+ body {
117
+ margin: 0;
118
+ background: hsl(var(--background));
119
+ color: hsl(var(--foreground));
120
+ font: var(--fs-sm)/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans",
121
+ "PingFang SC", "Microsoft YaHei", Helvetica, Arial, sans-serif;
122
+ -webkit-font-smoothing: antialiased;
123
+ text-rendering: optimizeLegibility;
124
+ }
125
+ h1, h2, h3, p { margin: 0; }
126
+ button, input, select, textarea { font: inherit; color: inherit; }
127
+ button { background: none; border: 0; cursor: pointer; padding: 0; }
128
+ code, .mono { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; }
129
+ .hidden { display: none !important; }
130
+ .muted { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); }
131
+
132
+ :focus-visible {
133
+ outline: 2px solid hsl(var(--ring));
134
+ outline-offset: 1px;
135
+ }
136
+
137
+ ::selection { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
138
+
139
+ /* Thin scrollbars */
140
+ ::-webkit-scrollbar { width: 10px; height: 10px; }
141
+ ::-webkit-scrollbar-thumb { background: hsl(var(--muted-foreground) / .35); border-radius: 8px; border: 3px solid transparent; background-clip: content-box; }
142
+ ::-webkit-scrollbar-thumb:hover { background-color: hsl(var(--muted-foreground) / .55); }
143
+ ::-webkit-scrollbar-track { background: transparent; }
144
+
145
+ /* ── Brand ────────────────────────────────────────────────────────── */
146
+ .brand-mark {
147
+ width: 28px; height: 28px;
148
+ display: grid; place-items: center;
149
+ background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
150
+ border-radius: var(--radius);
151
+ font-weight: 700; font-size: var(--fs-sm); letter-spacing: -.02em;
152
+ flex-shrink: 0;
153
+ }
154
+
155
+ /* ── Auth screens ─────────────────────────────────────────────────── */
156
+ .auth-screen {
157
+ min-height: 100vh;
158
+ display: grid; place-items: center;
159
+ padding: var(--sp-6);
160
+ background: hsl(var(--muted) / .4);
161
+ }
162
+ .auth-card {
163
+ width: min(400px, 100%);
164
+ padding: var(--sp-6);
165
+ background: hsl(var(--card));
166
+ border: 1px solid hsl(var(--border));
167
+ border-radius: var(--radius-lg);
168
+ box-shadow: var(--shadow-card);
169
+ }
170
+ .auth-card header { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-5); }
171
+ .auth-card h1 { font-size: var(--fs-lg); font-weight: 600; letter-spacing: -.01em; }
172
+ .auth-card > p { color: hsl(var(--muted-foreground)); font-size: var(--fs-sm); margin-bottom: var(--sp-5); }
173
+ .auth-submit { width: 100%; height: 36px; }
174
+
175
+ /* ── Forms ────────────────────────────────────────────────────────── */
176
+ .field { display: grid; gap: var(--sp-2); margin-bottom: var(--sp-4); font-size: var(--fs-sm); font-weight: 500; }
177
+ .field > small, .field-help { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); font-weight: 400; line-height: 1.5; }
178
+ .field-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-4); align-items: start; margin-bottom: var(--sp-4); }
179
+ .field-row > .field { margin-bottom: 0; }
180
+
181
+ input, select, textarea {
182
+ width: 100%; height: 32px;
183
+ padding: 0 var(--sp-3);
184
+ background: transparent;
185
+ border: 1px solid hsl(var(--input));
186
+ border-radius: var(--radius);
187
+ font-size: var(--fs-sm);
188
+ transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
189
+ }
190
+ textarea { height: auto; min-height: 72px; padding: var(--sp-2) var(--sp-3); resize: vertical; line-height: 1.5; }
191
+ input:hover, select:hover, textarea:hover { border-color: hsl(var(--muted-foreground) / .6); }
192
+ input:focus, select:focus, textarea:focus { outline: none; border-color: hsl(var(--ring)); box-shadow: var(--shadow-ring-focus); }
193
+ input:disabled, select:disabled, textarea:disabled { opacity: .5; cursor: not-allowed; }
194
+ input[type="checkbox"] { width: 14px; height: 14px; padding: 0; accent-color: hsl(var(--primary)); }
195
+
196
+ .checkbox { display: flex; align-items: center; gap: var(--sp-2); height: 32px; font-weight: 500; cursor: pointer; }
197
+ .checkbox input { flex-shrink: 0; }
198
+
199
+ .form-error { min-height: 18px; margin-top: var(--sp-2); color: hsl(var(--destructive-text)); font-size: var(--fs-xs); font-weight: 500; }
200
+ .confirm-text { color: hsl(var(--muted-foreground)); font-size: var(--fs-sm); line-height: 1.6; }
201
+
202
+ /* ── Buttons ──────────────────────────────────────────────────────── */
203
+ .button {
204
+ display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
205
+ height: 32px; padding: 0 var(--sp-3);
206
+ border: 1px solid hsl(var(--input));
207
+ border-radius: var(--radius);
208
+ background: hsl(var(--card));
209
+ font-size: var(--fs-sm); font-weight: 500; white-space: nowrap;
210
+ box-shadow: var(--shadow-xs);
211
+ transition: background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard);
212
+ }
213
+ .button:hover:not(:disabled) { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
214
+ .button:disabled { opacity: .5; cursor: not-allowed; }
215
+ .button.primary { background: hsl(var(--primary)); border-color: hsl(var(--primary)); color: hsl(var(--primary-foreground)); }
216
+ .button.primary:hover:not(:disabled) { background: hsl(var(--primary) / .88); color: hsl(var(--primary-foreground)); }
217
+ .button.danger { color: hsl(var(--destructive-text)); }
218
+ .button.danger:hover:not(:disabled) { background: hsl(var(--destructive) / .08); }
219
+ .button.solid-danger { background: hsl(var(--destructive)); border-color: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); }
220
+ .button.solid-danger:hover:not(:disabled) { background: hsl(var(--destructive) / .9); color: hsl(var(--destructive-foreground)); }
221
+ .button.small { height: 26px; padding: 0 var(--sp-2); font-size: var(--fs-xs); }
222
+ .button svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
223
+
224
+ .icon-button {
225
+ display: inline-flex; align-items: center; justify-content: center;
226
+ width: 32px; height: 32px; flex-shrink: 0;
227
+ border-radius: var(--radius);
228
+ color: hsl(var(--muted-foreground));
229
+ transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);
230
+ }
231
+ .icon-button:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
232
+ .icon-button svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
233
+
234
+ /* ── App shell ────────────────────────────────────────────────────── */
235
+ .app-shell { min-height: 100vh; display: flex; }
236
+
237
+ .sidebar {
238
+ position: fixed; inset: 0 auto 0 0;
239
+ width: var(--sidebar-width);
240
+ padding: var(--sp-3) var(--sp-2);
241
+ display: flex; flex-direction: column; gap: var(--sp-2);
242
+ background: hsl(var(--card));
243
+ border-right: 1px solid hsl(var(--border));
244
+ z-index: var(--z-sidebar);
245
+ }
246
+ .brand {
247
+ display: flex; align-items: center; gap: var(--sp-2);
248
+ height: 40px; padding: 0 var(--sp-2);
249
+ font-weight: 600; font-size: var(--fs-sm); letter-spacing: -.01em;
250
+ }
251
+ nav { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
252
+ .nav-group { display: flex; flex-direction: column; gap: 2px; }
253
+ .nav-group-label {
254
+ padding: 0 var(--sp-2);
255
+ color: hsl(var(--muted-foreground));
256
+ font-size: var(--fs-2xs); font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
257
+ }
258
+ .nav-group-footer { margin-top: auto; }
259
+ .nav-item {
260
+ width: 100%; height: 32px;
261
+ display: flex; align-items: center; gap: var(--sp-2);
262
+ padding: 0 var(--sp-2);
263
+ border-radius: var(--radius);
264
+ color: hsl(var(--muted-foreground));
265
+ font-size: var(--fs-sm); font-weight: 500; text-align: left;
266
+ transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);
267
+ }
268
+ .nav-item:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
269
+ .nav-item.active { background: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); font-weight: 600; }
270
+ .nav-item-danger { color: hsl(var(--destructive-text)); }
271
+ .nav-item-danger:hover { background: hsl(var(--destructive) / .08); color: hsl(var(--destructive-text)); }
272
+ .nav-item svg { width: 15px; height: 15px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
273
+
274
+ .danger-text { color: hsl(var(--destructive-text)); }
275
+
276
+ /* ── Main / page chrome ───────────────────────────────────────────── */
277
+ .main {
278
+ flex: 1; min-width: 0;
279
+ margin-left: var(--sidebar-width);
280
+ min-height: 100vh;
281
+ display: flex; flex-direction: column;
282
+ }
283
+ .topbar {
284
+ position: sticky; top: 0; z-index: var(--z-topbar);
285
+ height: 56px;
286
+ display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
287
+ padding: 0 var(--gutter);
288
+ background: hsl(var(--background));
289
+ border-bottom: 1px solid hsl(var(--border));
290
+ }
291
+ .topbar h1 { font-size: var(--fs-lg); font-weight: 600; letter-spacing: -.01em; }
292
+ .page-actions { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
293
+
294
+ #page-results { display: flex; flex-direction: column; gap: var(--sp-4); }
295
+ .page-content > :empty { display: none; }
296
+ .visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
297
+
298
+ button[aria-busy="true"] { cursor: progress; }
299
+ button[aria-busy="true"]::after { content: '…'; margin-left: var(--sp-1); }
300
+
301
+ .page-content {
302
+ flex: 1; width: 100%;
303
+ padding: var(--sp-5) var(--gutter) var(--sp-6);
304
+ display: flex; flex-direction: column; gap: var(--sp-4);
305
+ }
306
+
307
+ /* ── Cards / panels ───────────────────────────────────────────────── */
308
+ .panel {
309
+ background: hsl(var(--card));
310
+ border: 1px solid hsl(var(--border));
311
+ border-radius: var(--radius-lg);
312
+ }
313
+ .panel-header {
314
+ min-height: 44px;
315
+ padding: 0 var(--sp-4);
316
+ display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
317
+ border-bottom: 1px solid hsl(var(--border));
318
+ }
319
+ .panel-header h2 { font-size: var(--fs-md); font-weight: 600; }
320
+ .panel-body { padding: var(--sp-4); }
321
+ .panel-note { padding: var(--sp-4); color: hsl(var(--muted-foreground)); font-size: var(--fs-sm); }
322
+ .empty { padding: var(--sp-8) var(--sp-4); color: hsl(var(--muted-foreground)); text-align: center; font-size: var(--fs-sm); }
323
+ .empty-state { display: grid; justify-items: center; gap: var(--sp-1); padding: var(--sp-8) var(--sp-4); text-align: center; }
324
+ .empty-state > svg { width: 28px; height: 28px; margin-bottom: var(--sp-2); color: hsl(var(--muted-foreground)); fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
325
+ .empty-state strong { font-size: var(--fs-md); font-weight: 600; color: hsl(var(--foreground)); }
326
+ .empty-state span { font-size: var(--fs-xs); color: hsl(var(--muted-foreground)); }
327
+ .empty-state .button { margin-top: var(--sp-3); }
328
+
329
+ /* Stats */
330
+ .stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-4); }
331
+ .stat {
332
+ padding: var(--sp-4) var(--sp-5);
333
+ background: hsl(var(--card));
334
+ border: 1px solid hsl(var(--border));
335
+ border-radius: var(--radius-lg);
336
+ display: grid; gap: var(--sp-1);
337
+ }
338
+ .stat span { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); font-weight: 500; }
339
+ .stat strong { font-size: var(--fs-stat); font-weight: 600; letter-spacing: -.02em; line-height: 1.2; font-variant-numeric: tabular-nums; }
340
+
341
+ /* ── Toolbar ──────────────────────────────────────────────────────── */
342
+ .toolbar { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
343
+ .toolbar select { width: auto; min-width: 128px; }
344
+ .search-box { position: relative; flex: 1; min-width: 160px; max-width: 280px; }
345
+ .search-box svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; color: hsl(var(--muted-foreground)); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
346
+ .search-box input { width: 100%; padding-left: 30px; }
347
+
348
+ /* ── Tables ───────────────────────────────────────────────────────── */
349
+ .table-wrap {
350
+ overflow-x: auto;
351
+ background: hsl(var(--card));
352
+ border: 1px solid hsl(var(--border));
353
+ border-radius: var(--radius-lg);
354
+ }
355
+ table { width: 100%; border-collapse: collapse; min-width: 720px; }
356
+ th, td { padding: 0 var(--sp-4); height: 40px; border-bottom: 1px solid hsl(var(--border)); text-align: left; vertical-align: middle; }
357
+ th { height: 36px; color: hsl(var(--muted-foreground)); font-size: var(--fs-2xs); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; }
358
+ tbody tr:last-child td { border-bottom: 0; }
359
+ tbody tr:hover { background: hsl(var(--muted) / .5); }
360
+ tr[data-run-detail] { cursor: pointer; }
361
+
362
+ .agent-name { display: grid; gap: 2px; min-width: 0; }
363
+ .agent-name strong { font-size: var(--fs-sm); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
364
+ .agent-name small { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
365
+ .error-detail { color: hsl(var(--destructive-text)); font-size: var(--fs-sm); overflow-wrap: anywhere; line-height: 1.4; }
366
+ .row-actions { display: flex; justify-content: flex-end; gap: var(--sp-2); }
367
+ .agent-table { min-width: 1050px; table-layout: fixed; }
368
+ .agent-table th:nth-child(1) { width: 22%; }
369
+ .agent-table th:nth-child(2) { width: 8%; }
370
+ .agent-table th:nth-child(3), .agent-table th:nth-child(4), .agent-table th:nth-child(6) { width: 10%; }
371
+ .agent-table th:nth-child(5) { width: 26%; }
372
+ .agent-table th:nth-child(7) { width: 14%; }
373
+ .agent-table td, .agent-table .agent-name small { overflow-wrap: anywhere; }
374
+
375
+ /* ── Badges & status ──────────────────────────────────────────────── */
376
+ .badge {
377
+ display: inline-flex; align-items: center;
378
+ height: 20px; padding: 0 var(--sp-2);
379
+ border: 1px solid hsl(var(--border));
380
+ border-radius: 4px;
381
+ background: hsl(var(--secondary));
382
+ color: hsl(var(--secondary-foreground));
383
+ font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
384
+ }
385
+ .status {
386
+ display: inline-flex; align-items: center; gap: var(--sp-2);
387
+ height: 22px; padding: 0 var(--sp-2);
388
+ border-radius: 9999px;
389
+ background: hsl(var(--secondary));
390
+ color: hsl(var(--muted-foreground));
391
+ font-size: var(--fs-xs); font-weight: 500; white-space: nowrap;
392
+ }
393
+ .status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: hsl(var(--muted-foreground) / .5); flex-shrink: 0; }
394
+ .status.ready, .status.completed { color: hsl(var(--success)); background: hsl(var(--success) / .1); }
395
+ .status.ready::before, .status.completed::before { background: hsl(var(--success)); }
396
+ .status.failed { color: hsl(var(--destructive-text)); background: hsl(var(--destructive) / .1); }
397
+ .status.failed::before { background: hsl(var(--destructive)); }
398
+ .status.running { color: hsl(var(--info)); background: hsl(var(--info) / .1); }
399
+ .status.running::before { background: hsl(var(--info)); animation: pulse var(--duration-pulse) var(--ease-pulse) infinite; }
400
+ .status.waiting { color: hsl(var(--warning)); background: hsl(var(--warning) / .12); }
401
+ .status.waiting::before { background: hsl(var(--warning)); animation: pulse var(--duration-pulse) var(--ease-pulse) infinite; }
402
+ .status.checking::before { animation: pulse var(--duration-pulse) var(--ease-pulse) infinite; }
403
+ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }
404
+
405
+ /* ── Runs page ────────────────────────────────────────────────────── */
406
+ .run-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-4); }
407
+ .run-section { display: flex; flex-direction: column; gap: var(--sp-3); }
408
+ .run-section-title { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); }
409
+ .run-section-title h2 { font-size: var(--fs-md); font-weight: 600; }
410
+ .run-section-title span { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); }
411
+
412
+ .run-live-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--sp-3); }
413
+ .run-card {
414
+ position: relative;
415
+ min-width: 0;
416
+ display: flex; flex-direction: column; gap: var(--sp-2);
417
+ padding: var(--sp-3) var(--sp-4);
418
+ background: hsl(var(--card));
419
+ border: 1px solid hsl(var(--border));
420
+ border-left: 3px solid hsl(var(--info));
421
+ border-radius: var(--radius-lg);
422
+ transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
423
+ }
424
+ .run-card:hover { border-color: hsl(var(--muted-foreground) / .4); box-shadow: var(--shadow-sm); }
425
+ .run-card.waiting { border-left-color: hsl(var(--warning)); }
426
+ .run-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
427
+ .run-card-agent { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
428
+ .run-card-head > .status, .run-card-agent > .badge { flex-shrink: 0; }
429
+ .run-card-agent strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-sm); font-weight: 600; }
430
+ .run-task {
431
+ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
432
+ overflow: hidden;
433
+ color: hsl(var(--foreground));
434
+ font-size: var(--fs-sm); line-height: 1.5;
435
+ white-space: pre-wrap;
436
+ overflow-wrap: anywhere;
437
+ }
438
+ .run-progress { display: grid; gap: 2px; }
439
+ .run-progress strong { font-size: var(--fs-xs); font-weight: 600; }
440
+ .run-progress small { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
441
+ .run-meta {
442
+ display: flex; align-items: center; justify-content: space-between;
443
+ color: hsl(var(--muted-foreground));
444
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
445
+ font-size: var(--fs-2xs); line-height: 1.4;
446
+ font-variant-numeric: tabular-nums;
447
+ }
448
+ .run-table { min-width: 1040px; table-layout: fixed; }
449
+ .run-table th:nth-child(1), .run-table th:nth-child(5) { width: 160px; }
450
+ .run-table th:nth-child(4) { width: 100px; }
451
+ .run-table th:nth-child(6) { width: 90px; }
452
+ .run-table th:nth-child(7) { width: 110px; }
453
+ .run-table .run-task-cell { max-width: 360px; }
454
+ .run-table th.num, .run-table td.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
455
+ .run-task-cell strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; font-size: var(--fs-sm); }
456
+ .run-task-cell small { display: block; margin-top: 2px; color: hsl(var(--muted-foreground)); font-size: var(--fs-2xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
457
+
458
+ /* Run detail (drawer) */
459
+ .run-detail-grid {
460
+ display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
461
+ margin-bottom: var(--sp-4);
462
+ border: 1px solid hsl(var(--border));
463
+ border-radius: var(--radius-lg);
464
+ overflow: hidden;
465
+ background: hsl(var(--border));
466
+ }
467
+ .run-detail-item { padding: var(--sp-3); background: hsl(var(--card)); display: grid; gap: var(--sp-1); align-content: start; }
468
+ .run-detail-item span { color: hsl(var(--muted-foreground)); font-size: var(--fs-2xs); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; }
469
+ .run-detail-item strong { font-size: var(--fs-sm); font-weight: 500; overflow-wrap: anywhere; }
470
+ .run-detail-block { margin-bottom: var(--sp-4); }
471
+ .run-detail-block h3 { margin: 0 0 var(--sp-2); color: hsl(var(--muted-foreground)); font-size: var(--fs-2xs); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; }
472
+ .run-detail-code {
473
+ margin: 0; padding: var(--sp-3);
474
+ max-height: 320px; overflow: auto;
475
+ border: 1px solid hsl(var(--border));
476
+ border-radius: var(--radius);
477
+ background: hsl(var(--muted) / .4);
478
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
479
+ font-size: var(--fs-xs); line-height: 1.6;
480
+ overflow-wrap: anywhere; white-space: pre-wrap;
481
+ }
482
+ .run-id { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
483
+
484
+ /* ── Lists (workspaces, overview, artifacts) ──────────────────────── */
485
+ .workspace-list, .overview-list { display: grid; gap: var(--sp-2); }
486
+ .list-row {
487
+ min-width: 0; min-height: 48px;
488
+ display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
489
+ padding: var(--sp-3) var(--sp-4);
490
+ background: hsl(var(--card));
491
+ border: 1px solid hsl(var(--border));
492
+ border-radius: var(--radius-lg);
493
+ transition: border-color var(--duration-fast) var(--ease-standard);
494
+ }
495
+ .list-row:hover { border-color: hsl(var(--muted-foreground) / .4); }
496
+ .list-row-main { display: grid; gap: 2px; min-width: 0; }
497
+ .list-row-main > * { min-width: 0; }
498
+ .list-row-main strong, .path { font-size: var(--fs-sm); font-weight: 600; overflow-wrap: anywhere; }
499
+ .list-row-main small { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); overflow-wrap: anywhere; }
500
+ .panel-body > .workspace-list, .panel-body > .overview-list { gap: var(--sp-2); }
501
+ .panel-body .list-row { border-radius: var(--radius); }
502
+
503
+ /* ── API keys ─────────────────────────────────────────────────────── */
504
+ .key-table { min-width: 760px; width: 100%; table-layout: fixed; }
505
+ .key-table th:nth-child(1) { width: 21%; }
506
+ .key-table th:nth-child(2) { width: 15%; }
507
+ .key-table th:nth-child(3) { width: 20%; }
508
+ .key-table th:nth-child(4) { width: 15%; }
509
+ .key-table th:nth-child(5) { width: 15%; }
510
+ .key-table th:nth-child(6) { width: 14%; }
511
+ .key-table th, .key-table td { padding-left: 10px; padding-right: 10px; }
512
+ .key-table-wrap { overflow-x: auto; }
513
+ .key-table th:last-child, .key-table td:last-child { text-align: right; }
514
+ .key-secret-cell { display: flex; align-items: center; gap: var(--sp-2); white-space: nowrap; }
515
+ .key-secret-cell code { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); letter-spacing: .02em; }
516
+ .key-copy-button, .key-icon-button {
517
+ display: inline-flex; align-items: center; justify-content: center;
518
+ width: 28px; height: 28px;
519
+ border-radius: var(--radius);
520
+ color: hsl(var(--muted-foreground));
521
+ cursor: pointer;
522
+ transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
523
+ }
524
+ .key-copy-button:hover, .key-icon-button:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
525
+ .key-icon-button[aria-expanded="true"] {
526
+ background: hsl(var(--accent)); color: hsl(var(--accent-foreground));
527
+ box-shadow: var(--shadow-ring-selected);
528
+ }
529
+ .key-copy-button svg, .key-icon-button svg, .key-action-menu svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
530
+ .key-icon-button.danger-action { color: hsl(var(--destructive-text)); }
531
+ .key-icon-button.danger-action:hover { background: hsl(var(--destructive) / .08); }
532
+ .key-scope, .key-last-used { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); }
533
+ .key-actions { display: inline-flex; align-items: center; justify-content: flex-end; gap: 2px; }
534
+
535
+ .key-action-menu {
536
+ position: fixed; z-index: var(--z-menu);
537
+ width: 188px; padding: var(--sp-1);
538
+ background: hsl(var(--popover));
539
+ border: 1px solid hsl(var(--border));
540
+ border-radius: var(--radius-lg);
541
+ box-shadow: var(--shadow-md);
542
+ }
543
+ .key-action-menu button {
544
+ width: 100%; height: 30px;
545
+ display: flex; align-items: center; gap: var(--sp-2);
546
+ padding: 0 var(--sp-2);
547
+ border-radius: var(--radius);
548
+ font-size: var(--fs-sm); font-weight: 500; text-align: left;
549
+ transition: background-color var(--duration-fast) var(--ease-standard);
550
+ }
551
+ .key-action-menu button:hover { background: hsl(var(--accent)); }
552
+ .key-action-menu button.danger-text { margin-top: var(--sp-1); border-top: 1px solid hsl(var(--border)); border-radius: 0 0 var(--radius) var(--radius); height: 34px; }
553
+ .key-action-menu button.danger-text:hover { background: hsl(var(--destructive) / .08); }
554
+
555
+ .agent-scope {
556
+ max-height: 168px; overflow: auto;
557
+ display: grid; gap: 2px;
558
+ padding: var(--sp-2);
559
+ margin-bottom: var(--sp-4);
560
+ border: 1px solid hsl(var(--border));
561
+ border-radius: var(--radius);
562
+ background: hsl(var(--muted) / .4);
563
+ }
564
+ .agent-scope .checkbox {
565
+ display: grid; grid-template-columns: 14px minmax(0, 1fr) auto;
566
+ align-items: start; height: auto; min-height: 32px;
567
+ padding: 6px var(--sp-2); border-radius: var(--radius);
568
+ }
569
+ .agent-scope .checkbox input { margin-top: 3px; }
570
+ .scope-name { overflow-wrap: anywhere; }
571
+ .agent-scope .checkbox:hover { background: hsl(var(--accent)); }
572
+ .secret-box { display: grid; gap: var(--sp-3); }
573
+ .secret-value {
574
+ display: block; padding: var(--sp-3);
575
+ background: hsl(var(--muted) / .5);
576
+ border: 1px solid hsl(var(--border));
577
+ border-radius: var(--radius);
578
+ overflow-wrap: anywhere;
579
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
580
+ font-size: var(--fs-xs);
581
+ }
582
+
583
+ /* ── Drawer ───────────────────────────────────────────────────────── */
584
+ .drawer-backdrop { position: fixed; inset: 0; background: rgb(0 0 0 / .4); z-index: var(--z-backdrop); animation: fadeIn var(--duration-fade) var(--ease-out); }
585
+ .drawer {
586
+ position: fixed; inset: 0 0 0 auto;
587
+ width: min(480px, 100%);
588
+ display: flex; flex-direction: column;
589
+ background: hsl(var(--card));
590
+ border-left: 1px solid hsl(var(--border));
591
+ box-shadow: var(--shadow-drawer);
592
+ z-index: var(--z-drawer);
593
+ animation: slideInRight var(--duration-slide) var(--ease-drawer);
594
+ overflow: hidden;
595
+ }
596
+ .drawer-header {
597
+ height: 52px; flex-shrink: 0;
598
+ display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
599
+ padding: 0 var(--sp-4);
600
+ border-bottom: 1px solid hsl(var(--border));
601
+ }
602
+ .drawer-header h2 { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-md); font-weight: 600; }
603
+ .drawer-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: var(--sp-4); }
604
+ .drawer-footer {
605
+ flex: 0 0 auto;
606
+ display: flex; justify-content: flex-end; gap: var(--sp-2);
607
+ padding: var(--sp-3) var(--sp-4) var(--sp-4);
608
+ border-top: 1px solid hsl(var(--border));
609
+ background: hsl(var(--card));
610
+ }
611
+ @keyframes fadeIn { from { opacity: 0; } }
612
+ @keyframes slideInRight { from { transform: translateX(16px); opacity: 0; } }
613
+
614
+ /* ── Settings ─────────────────────────────────────────────────────── */
615
+ .main.settings-page .topbar { padding-inline: 0; justify-content: flex-start; gap: 0; }
616
+ .main.settings-page .topbar h1 {
617
+ width: min(calc(100% - 2 * var(--gutter)), 820px);
618
+ margin-inline: auto;
619
+ padding-right: 100px;
620
+ }
621
+ .main.settings-page .page-actions { position: absolute; right: max(var(--gutter), calc((100% - 820px) / 2)); }
622
+ .main.settings-page .page-content { padding-top: var(--sp-8); }
623
+ .settings-layout { width: min(100%, 820px); margin-inline: auto; }
624
+ .settings-section { width: 100%; }
625
+ .settings-section + .settings-section {
626
+ margin-top: 48px;
627
+ padding-top: 48px;
628
+ border-top: 1px solid hsl(var(--border));
629
+ }
630
+ .settings-section-heading { display: grid; gap: var(--sp-2); margin-bottom: 28px; }
631
+ .settings-section-heading h2 { font-size: var(--fs-lg); font-weight: 600; letter-spacing: -.01em; }
632
+ /* 节说明写的是生效范围——这是界面自身无法表达的信息,不要当复述删掉 */
633
+ .settings-note { color: hsl(var(--muted-foreground)); font-size: var(--fs-sm); }
634
+ .settings-fields { display: grid; gap: 24px; width: min(100%, 520px); }
635
+ .settings-fields .field { margin-bottom: 0; }
636
+ .settings-fields .field input, .settings-fields .field select { max-width: none; }
637
+ .settings-actions { display: flex; justify-content: flex-end; gap: var(--sp-2); margin-top: 28px; }
638
+ .settings-form-error { width: min(100%, 520px); margin-top: 32px; }
639
+ .settings-account-row {
640
+ display: grid;
641
+ grid-template-columns: minmax(160px, 200px) minmax(0, 1fr);
642
+ align-items: start;
643
+ gap: 32px;
644
+ }
645
+ .settings-account-copy { display: grid; gap: var(--sp-1); }
646
+ .settings-account-copy strong { font-size: var(--fs-sm); font-weight: 600; }
647
+ .settings-account-copy p { color: hsl(var(--muted-foreground)); font-size: var(--fs-sm); }
648
+ .settings-account-fields { display: grid; gap: 24px; width: min(100%, 520px); }
649
+
650
+ /* ── Toast ────────────────────────────────────────────────────────── */
651
+ .toast-region {
652
+ position: fixed; right: var(--sp-6); bottom: var(--sp-6);
653
+ z-index: var(--z-toast);
654
+ display: grid; gap: var(--sp-2);
655
+ max-width: 360px;
656
+ }
657
+ .toast {
658
+ padding: var(--sp-3) var(--sp-4);
659
+ background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
660
+ border-radius: var(--radius);
661
+ box-shadow: var(--shadow-toast);
662
+ font-size: var(--fs-sm); font-weight: 500; line-height: 1.5;
663
+ animation: slideInUp var(--duration-toast) var(--ease-standard);
664
+ }
665
+ .toast-region > div { display: grid; gap: var(--sp-2); }
666
+ .toast-region > :empty { display: none; }
667
+ .drawer .toast-region { position: static; flex: 0 0 auto; max-width: none; max-height: min(30vh, 180px); overflow-y: auto; margin: 0 var(--sp-4); }
668
+ .drawer .toast { margin-bottom: var(--sp-3); }
669
+ .run-card .run-detail-button { align-self: flex-end; }
670
+ .agent-name > .badge { width: fit-content; }
671
+ .toast.error { background: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); }
672
+ @keyframes slideInUp { from { opacity: 0; transform: translateY(8px); } }
673
+
674
+ /* ── Responsive ───────────────────────────────────────────────────── */
675
+ @media (max-width: 1100px) {
676
+ /* Keep every key action visible when six columns no longer fit. The real
677
+ table headings stay in the accessibility tree while rows stack. */
678
+ .key-table { min-width: 0; }
679
+ .key-table thead {
680
+ position: absolute; width: 1px; height: 1px;
681
+ margin: -1px; padding: 0; overflow: hidden;
682
+ clip-path: inset(50%); white-space: nowrap;
683
+ }
684
+ .key-table tbody { display: grid; }
685
+ .key-table tbody tr {
686
+ display: grid; grid-template-columns: minmax(0, 1fr) auto;
687
+ gap: var(--sp-2) var(--sp-3); padding: var(--sp-4);
688
+ border-bottom: 1px solid hsl(var(--border));
689
+ }
690
+ .key-table tbody tr:last-child { border-bottom: 0; }
691
+ .key-table td { min-width: 0; height: auto; padding: 0; border: 0; }
692
+ .key-table td:nth-child(1) { grid-area: 1 / 1; }
693
+ .key-table td:nth-child(2) { grid-area: 2 / 1; }
694
+ .key-table td:nth-child(6) { grid-area: 1 / 2 / 3 / 3; }
695
+ .key-table td[data-label] { grid-column: 1 / -1; display: flex; align-items: baseline; gap: var(--sp-3); }
696
+ .key-table td[data-label]::before {
697
+ content: attr(data-label); flex: 0 0 60px;
698
+ color: hsl(var(--muted-foreground)); font-size: var(--fs-xs);
699
+ }
700
+ .key-table .agent-name strong {
701
+ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
702
+ overflow-wrap: anywhere; white-space: normal;
703
+ }
704
+ .key-secret-cell { align-items: center; }
705
+ .key-scope, .key-last-used { min-width: 0; white-space: normal; overflow-wrap: anywhere; }
706
+ }
707
+ @media (max-width: 860px) {
708
+ :root { --sidebar-width: 56px; --gutter: var(--sp-4); }
709
+ /* 视觉隐藏而不是 display:none:图标栏里按钮的可访问名来自 span,
710
+ display:none 会让 6 个导航按钮在无障碍树上变成无名按钮。 */
711
+ .brand span:last-child, .nav-item span, .nav-group-label {
712
+ position: absolute; width: 1px; height: 1px;
713
+ margin: -1px; padding: 0; overflow: hidden;
714
+ clip-path: inset(50%); white-space: nowrap;
715
+ }
716
+ .brand, .nav-item { justify-content: center; }
717
+ .nav-group + .nav-group { padding-top: var(--sp-2); border-top: 1px solid hsl(var(--border)); }
718
+ }
719
+ @media (max-width: 640px) {
720
+ .page-content { padding: var(--sp-4) var(--gutter) var(--sp-4); }
721
+ .main.settings-page .page-content { padding-top: var(--sp-6); }
722
+ .settings-section + .settings-section { margin-top: 40px; padding-top: 40px; }
723
+ .settings-section-heading { margin-bottom: 24px; }
724
+ .settings-account-row { grid-template-columns: 1fr; gap: var(--sp-4); }
725
+ .search-box { max-width: none; }
726
+ .stats { grid-template-columns: 1fr; }
727
+ .run-summary { grid-template-columns: repeat(2, 1fr); }
728
+ .run-live-grid { grid-template-columns: minmax(0, 1fr); }
729
+ .toolbar input[type="search"], .toolbar select { max-width: none; width: 100%; }
730
+ .field-row { grid-template-columns: 1fr; }
731
+ .field-spacer { display: none; }
732
+ .drawer { width: 100%; }
733
+ .run-detail-grid { grid-template-columns: 1fr; }
734
+ .toast-region { right: var(--sp-4); bottom: var(--sp-4); left: var(--sp-4); max-width: none; }
735
+ }
736
+
737
+ /* ── Reduced motion ───────────────────────────────────────────────── */
738
+ /* 统一压制而不是逐个列举消费者,这样以后新增的 transition 不会漏掉。
739
+ running/waiting 的 pulse 停下后,色点和文字标签仍然表达状态。 */
740
+ @media (prefers-reduced-motion: reduce) {
741
+ *, *::before, *::after {
742
+ animation-duration: .01ms !important;
743
+ animation-iteration-count: 1 !important;
744
+ transition-duration: .01ms !important;
745
+ }
746
+ }
617
747
  `;