@unity-china/codely-cli 1.0.0-rc.4 → 1.0.0-rc.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE +203 -0
  2. package/README.md +366 -0
  3. package/README.zh-CN.md +336 -0
  4. package/bundle/builtin/skill-creator/SKILL.md +381 -0
  5. package/bundle/builtin/skill-creator/scripts/init_skill.cjs +237 -0
  6. package/bundle/builtin/skill-creator/scripts/package_skill.cjs +140 -0
  7. package/bundle/builtin/skill-creator/scripts/validate_skill.cjs +137 -0
  8. package/bundle/builtin-agents/explore.toml +62 -0
  9. package/bundle/builtin-agents/general-purpose.toml +34 -0
  10. package/bundle/builtin-agents/plan.toml +69 -0
  11. package/bundle/example-prompts/README.md +56 -0
  12. package/bundle/example-prompts/analyze.toml +47 -0
  13. package/bundle/example-prompts/explain-code.toml +200 -0
  14. package/bundle/example-prompts/git-commit.toml +48 -0
  15. package/bundle/gemini.js +4577 -0
  16. package/bundle/gemini.js.LEGAL.txt +465 -0
  17. package/bundle/node_modules/@silvia-odwyer/photon-node/LICENSE.md +201 -0
  18. package/bundle/node_modules/@silvia-odwyer/photon-node/README.md +158 -0
  19. package/bundle/node_modules/@silvia-odwyer/photon-node/package.json +23 -0
  20. package/bundle/node_modules/@silvia-odwyer/photon-node/photon_rs.d.ts +3226 -0
  21. package/bundle/node_modules/@silvia-odwyer/photon-node/photon_rs.js +4521 -0
  22. package/bundle/node_modules/@silvia-odwyer/photon-node/photon_rs_bg.js +4270 -0
  23. package/bundle/node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm +0 -0
  24. package/bundle/policies/plan.toml +153 -0
  25. package/bundle/policies/read-only.toml +65 -0
  26. package/bundle/policies/write.toml +39 -0
  27. package/bundle/policies/yolo.toml +9 -0
  28. package/bundle/sandbox-macos-permissive-closed.sb +32 -0
  29. package/bundle/sandbox-macos-permissive-open.sb +25 -0
  30. package/bundle/sandbox-macos-permissive-proxied.sb +37 -0
  31. package/bundle/sandbox-macos-restrictive-closed.sb +93 -0
  32. package/bundle/sandbox-macos-restrictive-open.sb +96 -0
  33. package/bundle/sandbox-macos-restrictive-proxied.sb +98 -0
  34. package/bundle/tiktoken_bg.wasm +0 -0
  35. package/bundle/web-ui/dist/public/app.css +2923 -0
  36. package/bundle/web-ui/dist/public/app.js +140 -0
  37. package/bundle/web-ui/dist/public/index.html +17 -0
  38. package/package.json +102 -81
  39. package/dist/index.js +0 -19
@@ -0,0 +1,2923 @@
1
+ :root {
2
+ color-scheme: dark;
3
+
4
+ --bg: #0f111a;
5
+ --panel: #151a27;
6
+ --panel-2: #101521;
7
+ --border: rgba(255, 255, 255, 0.08);
8
+ --text: rgba(255, 255, 255, 0.92);
9
+ --muted: rgba(255, 255, 255, 0.62);
10
+ --subtle: rgba(255, 255, 255, 0.12);
11
+
12
+ --accent: #7aa2f7;
13
+ --accent-2: #bb9af7;
14
+ --ok: #9ece6a;
15
+ --warn: #e0af68;
16
+ --err: #f7768e;
17
+
18
+ --shadow: 0 16px 50px rgba(0, 0, 0, 0.45);
19
+ --radius: 8px;
20
+ --radius-sm: 6px;
21
+
22
+ --mono:
23
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
24
+ 'Courier New', monospace;
25
+ --sans:
26
+ ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial,
27
+ 'Apple Color Emoji', 'Segoe UI Emoji';
28
+ }
29
+
30
+ * {
31
+ box-sizing: border-box;
32
+ }
33
+
34
+ html,
35
+ body {
36
+ height: 100%;
37
+ }
38
+
39
+ #app {
40
+ height: 100%;
41
+ min-height: 0;
42
+ }
43
+
44
+ body {
45
+ margin: 0;
46
+ background:
47
+ radial-gradient(1200px 800px at 10% 0%, #1b2140 0%, transparent 60%),
48
+ radial-gradient(900px 700px at 90% 10%, #2a1b40 0%, transparent 55%),
49
+ var(--bg);
50
+ color: var(--text);
51
+ font-family: var(--sans);
52
+ overflow: hidden;
53
+ }
54
+
55
+ a {
56
+ color: var(--accent);
57
+ text-decoration: none;
58
+ }
59
+ a:hover {
60
+ text-decoration: underline;
61
+ }
62
+
63
+ button,
64
+ input,
65
+ textarea {
66
+ font-family: inherit;
67
+ }
68
+
69
+ .app {
70
+ height: 100%;
71
+ display: flex;
72
+ padding: 12px;
73
+ min-height: 0;
74
+ min-width: 0;
75
+ position: relative;
76
+ overflow: hidden;
77
+ }
78
+
79
+ .main,
80
+ .cp-main {
81
+ flex: 1;
82
+ background:
83
+ linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent),
84
+ var(--panel-2);
85
+ border: 1px solid var(--border);
86
+ border-radius: var(--radius);
87
+ box-shadow: var(--shadow);
88
+ overflow: hidden;
89
+ display: flex;
90
+ flex-direction: column;
91
+ min-height: 0;
92
+ min-width: 0;
93
+ position: relative;
94
+ }
95
+
96
+ .btn {
97
+ display: inline-flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ gap: 8px;
101
+ padding: 8px 12px;
102
+ border-radius: var(--radius-sm);
103
+ border: 1px solid var(--border);
104
+ background: rgba(255, 255, 255, 0.03);
105
+ color: var(--text);
106
+ cursor: pointer;
107
+ font-size: 13px;
108
+ }
109
+ .btn:hover {
110
+ background: rgba(255, 255, 255, 0.06);
111
+ }
112
+ .btn:active {
113
+ transform: translateY(1px);
114
+ }
115
+ .btn.primary {
116
+ background: linear-gradient(
117
+ 135deg,
118
+ rgba(122, 162, 247, 0.2),
119
+ rgba(187, 154, 247, 0.16)
120
+ );
121
+ border-color: rgba(122, 162, 247, 0.35);
122
+ }
123
+ .btn.danger {
124
+ background: rgba(247, 118, 142, 0.12);
125
+ border-color: rgba(247, 118, 142, 0.28);
126
+ }
127
+
128
+ .content {
129
+ flex: 1;
130
+ overflow-y: auto;
131
+ padding: 10px 18px 80px;
132
+ min-height: 0;
133
+ min-width: 0;
134
+ overflow-anchor: auto;
135
+ scroll-padding-bottom: 80px;
136
+ }
137
+
138
+ .content > * {
139
+ margin-bottom: 8px;
140
+ }
141
+
142
+ .content > * {
143
+ margin-bottom: 12px;
144
+ }
145
+
146
+ .session-notice {
147
+ position: sticky;
148
+ top: 0;
149
+ z-index: 4;
150
+ padding: 10px 12px;
151
+ border: 1px solid rgba(224, 175, 104, 0.3);
152
+ border-radius: var(--radius-md);
153
+ background: rgba(224, 175, 104, 0.08);
154
+ color: var(--warn);
155
+ white-space: pre-wrap;
156
+ line-height: 1.45;
157
+ backdrop-filter: blur(18px);
158
+ }
159
+
160
+ .user-message {
161
+ padding: 4px 0;
162
+ color: var(--text);
163
+ font-weight: 500;
164
+ }
165
+
166
+ .assistant-message {
167
+ padding: 4px 0;
168
+ }
169
+
170
+ .md {
171
+ font-size: 14px;
172
+ line-height: 1.55;
173
+ color: var(--text);
174
+ }
175
+ .md p {
176
+ margin: 0 0 10px;
177
+ white-space: pre-wrap;
178
+ }
179
+ .md h1,
180
+ .md h2,
181
+ .md h3,
182
+ .md h4 {
183
+ margin: 14px 0 8px;
184
+ line-height: 1.25;
185
+ }
186
+ .md h1 {
187
+ font-size: 20px;
188
+ }
189
+ .md h2 {
190
+ font-size: 17px;
191
+ }
192
+ .md h3 {
193
+ font-size: 15px;
194
+ }
195
+ .md h4 {
196
+ font-size: 14px;
197
+ color: rgba(255, 255, 255, 0.86);
198
+ }
199
+ .md ul,
200
+ .md ol {
201
+ margin: 0 0 10px 18px;
202
+ padding: 0;
203
+ }
204
+ .md li {
205
+ margin: 4px 0;
206
+ white-space: pre-wrap;
207
+ }
208
+ .md code.inline {
209
+ font-family: var(--mono);
210
+ font-size: 13px;
211
+ padding: 2px 6px;
212
+ border-radius: 8px;
213
+ border: 1px solid var(--border);
214
+ background: rgba(255, 255, 255, 0.04);
215
+ color: rgba(187, 154, 247, 0.95);
216
+ }
217
+ .md pre {
218
+ margin: 10px 0;
219
+ padding: 12px;
220
+ border-radius: 14px;
221
+ border: 1px solid var(--border);
222
+ background: rgba(0, 0, 0, 0.3);
223
+ overflow: auto;
224
+ font-family: var(--mono);
225
+ font-size: 13px;
226
+ line-height: 1.5;
227
+ }
228
+ .md pre code {
229
+ font-family: var(--mono);
230
+ }
231
+ .md hr {
232
+ border: none;
233
+ border-top: 1px solid var(--border);
234
+ margin: 14px 0;
235
+ }
236
+ .md table {
237
+ width: 100%;
238
+ border-collapse: collapse;
239
+ margin: 10px 0;
240
+ font-size: 12px;
241
+ }
242
+ .md th,
243
+ .md td {
244
+ border: 1px solid var(--border);
245
+ padding: 8px 10px;
246
+ vertical-align: top;
247
+ }
248
+ .md th {
249
+ background: rgba(255, 255, 255, 0.03);
250
+ color: rgba(255, 255, 255, 0.86);
251
+ }
252
+ .md blockquote {
253
+ margin: 10px 0;
254
+ padding: 8px 10px;
255
+ border-left: 3px solid rgba(122, 162, 247, 0.5);
256
+ background: rgba(122, 162, 247, 0.06);
257
+ border-radius: 10px;
258
+ color: rgba(255, 255, 255, 0.86);
259
+ }
260
+
261
+ .think {
262
+ margin: 12px 0;
263
+ }
264
+ .think summary {
265
+ cursor: pointer;
266
+ padding: 4px 0;
267
+ color: rgba(255, 255, 255, 0.7);
268
+ font-size: 11px;
269
+ font-weight: 600;
270
+ user-select: none;
271
+ opacity: 0.8;
272
+ letter-spacing: 0.05em;
273
+ }
274
+ .think summary:hover {
275
+ opacity: 1;
276
+ }
277
+ .think.active {
278
+ margin: 12px 0;
279
+ }
280
+ .think-body {
281
+ margin-top: 6px;
282
+ padding: 10px 12px;
283
+ border-left: 3px solid rgba(122, 162, 247, 0.55);
284
+ background: rgba(122, 162, 247, 0.06);
285
+ border-radius: 10px;
286
+ }
287
+ .think-content,
288
+ .think pre {
289
+ margin: 0;
290
+ padding: 0;
291
+ border: none;
292
+ background: transparent;
293
+ color: rgba(255, 255, 255, 0.86);
294
+ font-family: var(--sans);
295
+ font-size: 12px;
296
+ line-height: 1.45;
297
+ white-space: pre-wrap;
298
+ word-break: break-all;
299
+ }
300
+
301
+ .tool-card {
302
+ margin: 12px 0;
303
+ border-radius: var(--radius);
304
+ border: 1px solid var(--border);
305
+ background: rgba(255, 255, 255, 0.02);
306
+ overflow: hidden;
307
+ }
308
+
309
+ .tool-compact {
310
+ margin: 6px 0;
311
+ display: flex;
312
+ align-items: center;
313
+ gap: 8px;
314
+ font-family: var(--mono);
315
+ font-size: 12px;
316
+ color: rgba(255, 255, 255, 0.78);
317
+ opacity: 0.95;
318
+ }
319
+
320
+ .tool-compact-arrow {
321
+ color: rgba(255, 255, 255, 0.55);
322
+ }
323
+
324
+ .tool-compact-kind {
325
+ color: rgba(187, 154, 247, 0.95);
326
+ }
327
+
328
+ .tool-compact-title {
329
+ color: rgba(255, 255, 255, 0.86);
330
+ overflow: hidden;
331
+ text-overflow: ellipsis;
332
+ white-space: nowrap;
333
+ flex: 1;
334
+ min-width: 0;
335
+ }
336
+
337
+ .tool-compact-status {
338
+ font-family: var(--sans);
339
+ font-size: 11px;
340
+ color: var(--muted);
341
+ }
342
+
343
+ .planning-indicator {
344
+ font-size: 11px;
345
+ color: var(--muted);
346
+ margin: 12px 0;
347
+ font-style: italic;
348
+ background: linear-gradient(90deg, var(--muted), var(--text), var(--muted));
349
+ background-size: 200% 100%;
350
+ -webkit-background-clip: text;
351
+ -webkit-text-fill-color: transparent;
352
+ animation: shimmer-text 2s infinite linear;
353
+ opacity: 0.6;
354
+ }
355
+
356
+ @keyframes shimmer-text {
357
+ 0% {
358
+ background-position: 200% 0;
359
+ }
360
+ 100% {
361
+ background-position: -200% 0;
362
+ }
363
+ }
364
+
365
+ .shimmer {
366
+ display: none;
367
+ }
368
+
369
+ @keyframes shimmer-pulse {
370
+ 0% {
371
+ background-position: 200% 0;
372
+ transform: scale(0.9);
373
+ opacity: 0.4;
374
+ }
375
+ 50% {
376
+ transform: scale(1.1);
377
+ opacity: 0.8;
378
+ }
379
+ 100% {
380
+ background-position: -200% 0;
381
+ transform: scale(0.9);
382
+ opacity: 0.4;
383
+ }
384
+ }
385
+ .tool-card-header {
386
+ display: flex;
387
+ align-items: center;
388
+ justify-content: space-between;
389
+ gap: 10px;
390
+ padding: 6px 10px;
391
+ background: rgba(255, 255, 255, 0.03);
392
+ border-bottom: 1px solid var(--border);
393
+ }
394
+ .tool-card-title {
395
+ display: flex;
396
+ align-items: center;
397
+ gap: 10px;
398
+ min-width: 0;
399
+ }
400
+ .tool-kind {
401
+ font-family: var(--mono);
402
+ font-size: 11px;
403
+ padding: 3px 7px;
404
+ border-radius: 999px;
405
+ border: 1px solid var(--border);
406
+ color: var(--muted);
407
+ background: rgba(255, 255, 255, 0.03);
408
+ }
409
+ .tool-status {
410
+ font-size: 11px;
411
+ color: var(--muted);
412
+ }
413
+ .tool-card-body {
414
+ padding: 10px 12px;
415
+ }
416
+ .diff {
417
+ border-radius: var(--radius-sm);
418
+ border: 1px solid var(--border);
419
+ background: rgba(0, 0, 0, 0.26);
420
+ overflow: auto;
421
+ max-height: 420px;
422
+ }
423
+ .diff pre {
424
+ margin: 0;
425
+ padding: 10px 12px;
426
+ font-family: var(--mono);
427
+ font-size: 12px;
428
+ line-height: 1.45;
429
+ }
430
+ .diff .add {
431
+ color: rgba(158, 206, 106, 0.95);
432
+ }
433
+ .diff .del {
434
+ color: rgba(247, 118, 142, 0.95);
435
+ }
436
+ .diff .meta {
437
+ color: rgba(122, 162, 247, 0.92);
438
+ }
439
+ .diff .hunk {
440
+ color: rgba(224, 175, 104, 0.95);
441
+ }
442
+
443
+ .composer {
444
+ border-top: 1px solid var(--border);
445
+ padding: 12px;
446
+ background: var(--panel-2);
447
+ position: relative;
448
+ z-index: 10;
449
+ flex-shrink: 0;
450
+ }
451
+ .composer-inner {
452
+ display: block;
453
+ }
454
+ .input-wrap {
455
+ position: relative;
456
+ border: 1px solid var(--border);
457
+ border-radius: var(--radius);
458
+ background: rgba(255, 255, 255, 0.03);
459
+ /* Allow the slash command autocomplete popover to render outside the input. */
460
+ overflow: visible;
461
+ transition: all 0.2s;
462
+ }
463
+ .input-wrap:focus-within {
464
+ border-color: rgba(122, 162, 247, 0.5);
465
+ box-shadow: 0 0 0 4px rgba(122, 162, 247, 0.12);
466
+ }
467
+ textarea {
468
+ width: 100%;
469
+ min-height: 44px;
470
+ max-height: 180px;
471
+ resize: none;
472
+ padding: 11px 44px 11px 12px;
473
+ border: none;
474
+ background: transparent;
475
+ color: var(--text);
476
+ outline: none;
477
+ font-size: 13px;
478
+ line-height: 1.45;
479
+ display: block;
480
+ }
481
+
482
+ .composer-references {
483
+ display: flex;
484
+ flex-wrap: wrap;
485
+ gap: 6px;
486
+ padding: 8px 12px 0;
487
+ background: transparent;
488
+ }
489
+
490
+ .ref-chip {
491
+ display: inline-flex;
492
+ align-items: center;
493
+ gap: 6px;
494
+ padding: 4px 10px;
495
+ background: rgba(255, 255, 255, 0.05);
496
+ border: 1px solid var(--border);
497
+ border-radius: 6px;
498
+ font-size: 11px;
499
+ font-weight: 500;
500
+ color: var(--muted);
501
+ max-width: 200px;
502
+ }
503
+
504
+ .ref-label {
505
+ overflow: hidden;
506
+ text-overflow: ellipsis;
507
+ white-space: nowrap;
508
+ }
509
+
510
+ .ref-chip.file {
511
+ background: rgba(255, 255, 255, 0.08);
512
+ }
513
+
514
+ .ref-chip.link {
515
+ background: rgba(255, 255, 255, 0.08);
516
+ }
517
+
518
+ .ref-chip.default {
519
+ background: rgba(255, 255, 255, 0.04);
520
+ }
521
+
522
+ .ref-remove {
523
+ background: none;
524
+ border: none;
525
+ color: inherit;
526
+ cursor: pointer;
527
+ padding: 0;
528
+ font-size: 14px;
529
+ display: flex;
530
+ align-items: center;
531
+ justify-content: center;
532
+ opacity: 0.5;
533
+ width: 14px;
534
+ height: 14px;
535
+ }
536
+
537
+ .ref-remove:hover {
538
+ opacity: 1;
539
+ }
540
+
541
+ .composer-submit {
542
+ position: absolute;
543
+ right: 8px;
544
+ bottom: 8px;
545
+ width: 28px;
546
+ height: 28px;
547
+ border-radius: 6px;
548
+ border: none;
549
+ background: rgba(255, 255, 255, 0.1);
550
+ color: var(--text);
551
+ display: flex;
552
+ align-items: center;
553
+ justify-content: center;
554
+ cursor: pointer;
555
+ transition: all 0.2s;
556
+ z-index: 20;
557
+ opacity: 0.8;
558
+ }
559
+
560
+ .composer-submit:hover {
561
+ opacity: 1;
562
+ background: rgba(255, 255, 255, 0.15);
563
+ }
564
+
565
+ .composer-submit:active {
566
+ transform: scale(0.92);
567
+ }
568
+
569
+ .composer-submit.busy {
570
+ background: rgba(255, 255, 255, 0.15);
571
+ opacity: 1;
572
+ color: var(--err);
573
+ }
574
+
575
+ .composer-submit svg {
576
+ display: block;
577
+ }
578
+ .composer-footer {
579
+ display: flex;
580
+ align-items: center;
581
+ justify-content: space-between;
582
+ margin-top: 8px;
583
+ gap: 12px;
584
+ }
585
+
586
+ .composer-footer-right {
587
+ display: flex;
588
+ align-items: center;
589
+ gap: 12px;
590
+ }
591
+
592
+ .workspace-info {
593
+ font-size: 11px;
594
+ color: rgba(255, 255, 255, 0.35);
595
+ overflow: hidden;
596
+ text-overflow: ellipsis;
597
+ white-space: nowrap;
598
+ max-width: 50%;
599
+ }
600
+
601
+ .hint {
602
+ font-size: 11px;
603
+ color: rgba(255, 255, 255, 0.35);
604
+ font-weight: normal;
605
+ white-space: nowrap;
606
+ }
607
+
608
+ .status-bar {
609
+ display: flex;
610
+ align-items: center;
611
+ gap: 8px;
612
+ cursor: pointer;
613
+ padding: 4px 8px;
614
+ border-radius: var(--radius-sm);
615
+ transition: background 0.2s;
616
+ }
617
+ .status-bar:hover {
618
+ background: rgba(255, 255, 255, 0.04);
619
+ }
620
+
621
+ .status-text {
622
+ font-size: 11px;
623
+ color: var(--err);
624
+ opacity: 0.9;
625
+ }
626
+
627
+ .status-dot {
628
+ width: 10px;
629
+ height: 10px;
630
+ border-radius: 50%;
631
+ background: var(--subtle);
632
+ box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.04);
633
+ }
634
+ .status-dot.connected {
635
+ background: var(--ok);
636
+ box-shadow: 0 0 8px rgba(158, 206, 106, 0.4);
637
+ }
638
+ .status-dot.connecting {
639
+ background: var(--warn);
640
+ animation: pulse 1.5s infinite ease-in-out;
641
+ }
642
+ .status-dot.disconnected {
643
+ background: var(--err);
644
+ box-shadow: 0 0 8px rgba(247, 118, 142, 0.4);
645
+ }
646
+
647
+ @keyframes pulse {
648
+ 0% {
649
+ opacity: 0.4;
650
+ transform: scale(0.85);
651
+ }
652
+ 50% {
653
+ opacity: 1;
654
+ transform: scale(1.05);
655
+ }
656
+ 100% {
657
+ opacity: 0.4;
658
+ transform: scale(0.85);
659
+ }
660
+ }
661
+
662
+ .autocomplete {
663
+ position: absolute;
664
+ left: 0;
665
+ right: 0;
666
+ bottom: calc(100% + 8px);
667
+ z-index: 50;
668
+ border: 1px solid var(--border);
669
+ background: rgba(20, 24, 35, 0.95);
670
+ backdrop-filter: blur(12px);
671
+ border-radius: 12px;
672
+ overflow: hidden;
673
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
674
+ max-height: 320px;
675
+ display: flex;
676
+ flex-direction: column;
677
+ }
678
+
679
+ .ac-header {
680
+ padding: 8px 12px;
681
+ font-size: 11px;
682
+ font-weight: 700;
683
+ color: var(--muted);
684
+ text-transform: uppercase;
685
+ letter-spacing: 0.1em;
686
+ border-bottom: 1px solid var(--border);
687
+ background: rgba(255, 255, 255, 0.02);
688
+ }
689
+
690
+ .ac-item {
691
+ padding: 8px 12px;
692
+ display: flex;
693
+ flex-direction: column;
694
+ gap: 2px;
695
+ cursor: pointer;
696
+ border-bottom: 1px solid rgba(255, 255, 255, 0.03);
697
+ }
698
+
699
+ .ac-item:last-child {
700
+ border-bottom: none;
701
+ }
702
+
703
+ .ac-item:hover,
704
+ .ac-item.active {
705
+ background: rgba(122, 162, 247, 0.12);
706
+ }
707
+
708
+ .ac-name code {
709
+ font-family: var(--mono);
710
+ font-size: 13px;
711
+ font-weight: 600;
712
+ color: var(--accent);
713
+ }
714
+
715
+ .ac-desc {
716
+ font-size: 12px;
717
+ color: var(--muted);
718
+ overflow: hidden;
719
+ text-overflow: ellipsis;
720
+ white-space: nowrap;
721
+ }
722
+
723
+ .ac-item.active .ac-desc {
724
+ color: var(--text);
725
+ }
726
+
727
+ .modal-backdrop {
728
+ position: fixed;
729
+ inset: 0;
730
+ background: rgba(0, 0, 0, 0.55);
731
+ display: flex;
732
+ align-items: center;
733
+ justify-content: center;
734
+ padding: 18px;
735
+ z-index: 9999;
736
+ }
737
+ .modal {
738
+ width: min(1100px, 96vw);
739
+ max-height: 90vh;
740
+ overflow: hidden;
741
+ border-radius: 18px;
742
+ border: 1px solid var(--border);
743
+ background: rgba(16, 21, 33, 0.96);
744
+ box-shadow: var(--shadow);
745
+ display: flex;
746
+ flex-direction: column;
747
+ }
748
+ .modal-header {
749
+ padding: 12px 14px;
750
+ border-bottom: 1px solid var(--border);
751
+ display: flex;
752
+ align-items: center;
753
+ justify-content: space-between;
754
+ gap: 10px;
755
+ }
756
+ .modal-header h2 {
757
+ margin: 0;
758
+ font-size: 13px;
759
+ font-weight: 650;
760
+ }
761
+ .modal-body {
762
+ display: grid;
763
+ grid-template-columns: 1fr 1fr;
764
+ gap: 12px;
765
+ padding: 12px;
766
+ overflow: auto;
767
+ }
768
+ .modal-pane {
769
+ border: 1px solid var(--border);
770
+ border-radius: 14px;
771
+ overflow: hidden;
772
+ background: rgba(0, 0, 0, 0.18);
773
+ }
774
+ .modal-pane .pane-title {
775
+ padding: 10px 12px;
776
+ border-bottom: 1px solid var(--border);
777
+ font-size: 12px;
778
+ color: var(--muted);
779
+ }
780
+ .modal-pane textarea {
781
+ border: none;
782
+ border-radius: 0;
783
+ background: transparent;
784
+ padding: 12px;
785
+ min-height: 320px;
786
+ max-height: none;
787
+ outline: none;
788
+ font-family: var(--mono);
789
+ font-size: 12px;
790
+ }
791
+ .modal-footer {
792
+ padding: 12px 14px;
793
+ border-top: 1px solid var(--border);
794
+ display: flex;
795
+ justify-content: flex-end;
796
+ gap: 10px;
797
+ }
798
+
799
+ .ask-user-countdown {
800
+ display: grid;
801
+ grid-template-columns: 1fr auto;
802
+ gap: 4px 12px;
803
+ align-items: center;
804
+ padding: 10px 12px;
805
+ border: 1px solid rgba(224, 175, 104, 0.58);
806
+ border-radius: 12px;
807
+ background: rgba(224, 175, 104, 0.12);
808
+ box-shadow: inset 0 0 0 1px rgba(224, 175, 104, 0.08);
809
+ }
810
+ .ask-user-countdown-label {
811
+ color: var(--warn);
812
+ font-size: 12px;
813
+ font-weight: 700;
814
+ text-transform: uppercase;
815
+ letter-spacing: 0.06em;
816
+ }
817
+ .ask-user-countdown-time {
818
+ grid-row: span 2;
819
+ min-width: 56px;
820
+ padding: 6px 10px;
821
+ border: 1px solid rgba(224, 175, 104, 0.6);
822
+ border-radius: 999px;
823
+ color: #ffd089;
824
+ background: rgba(224, 175, 104, 0.16);
825
+ font-family: var(--mono);
826
+ font-size: 16px;
827
+ font-weight: 800;
828
+ text-align: center;
829
+ }
830
+ .ask-user-countdown-message {
831
+ color: var(--muted);
832
+ font-size: 12px;
833
+ }
834
+ .ask-user-option {
835
+ position: relative;
836
+ gap: 8px;
837
+ }
838
+ .ask-user-option-default {
839
+ border-color: rgba(224, 175, 104, 0.85) !important;
840
+ background: rgba(224, 175, 104, 0.12) !important;
841
+ box-shadow: inset 0 0 0 1px rgba(224, 175, 104, 0.25);
842
+ }
843
+ .ask-user-option-checkbox {
844
+ display: flex;
845
+ align-items: center;
846
+ gap: 8px;
847
+ padding: 8px 10px;
848
+ border: 1px solid var(--border);
849
+ border-radius: var(--radius-sm);
850
+ }
851
+ .ask-user-default-badge {
852
+ padding: 2px 6px;
853
+ border: 1px solid rgba(224, 175, 104, 0.68);
854
+ border-radius: 999px;
855
+ color: var(--warn);
856
+ background: rgba(224, 175, 104, 0.1);
857
+ font-size: 11px;
858
+ font-weight: 700;
859
+ line-height: 1;
860
+ }
861
+
862
+ /* Subagent card styles */
863
+ .subagent-card {
864
+ background: linear-gradient(
865
+ 135deg,
866
+ rgba(122, 162, 247, 0.04),
867
+ rgba(187, 154, 247, 0.03)
868
+ );
869
+ border-color: rgba(122, 162, 247, 0.2);
870
+ }
871
+
872
+ .subagent-header {
873
+ display: flex;
874
+ align-items: center;
875
+ justify-content: space-between;
876
+ padding: 10px 14px;
877
+ background: rgba(122, 162, 247, 0.06);
878
+ border-bottom: 1px solid rgba(122, 162, 247, 0.15);
879
+ }
880
+
881
+ .subagent-header.running {
882
+ background: linear-gradient(
883
+ 90deg,
884
+ rgba(122, 162, 247, 0.08),
885
+ rgba(187, 154, 247, 0.08),
886
+ rgba(122, 162, 247, 0.08)
887
+ );
888
+ background-size: 200% 100%;
889
+ animation: shimmer-bg 3s infinite linear;
890
+ }
891
+
892
+ @keyframes shimmer-bg {
893
+ 0% {
894
+ background-position: 200% 0;
895
+ }
896
+ 100% {
897
+ background-position: -200% 0;
898
+ }
899
+ }
900
+
901
+ .subagent-title {
902
+ display: flex;
903
+ align-items: center;
904
+ gap: 10px;
905
+ }
906
+
907
+ .subagent-label {
908
+ font-family: var(--mono);
909
+ font-size: 10px;
910
+ text-transform: uppercase;
911
+ letter-spacing: 0.08em;
912
+ padding: 4px 8px;
913
+ border-radius: 999px;
914
+ background: linear-gradient(
915
+ 135deg,
916
+ rgba(122, 162, 247, 0.25),
917
+ rgba(187, 154, 247, 0.2)
918
+ );
919
+ border: 1px solid rgba(122, 162, 247, 0.4);
920
+ color: var(--accent);
921
+ font-weight: 700;
922
+ }
923
+
924
+ .subagent-name {
925
+ font-size: 13px;
926
+ font-weight: 600;
927
+ color: var(--text);
928
+ }
929
+
930
+ .subagent-status-wrap {
931
+ display: flex;
932
+ align-items: center;
933
+ gap: 8px;
934
+ }
935
+
936
+ .subagent-spinner {
937
+ width: 14px;
938
+ height: 14px;
939
+ border: 2px solid rgba(122, 162, 247, 0.2);
940
+ border-top-color: var(--accent);
941
+ border-radius: 50%;
942
+ animation: spin 1s linear infinite;
943
+ }
944
+
945
+ @keyframes spin {
946
+ to {
947
+ transform: rotate(360deg);
948
+ }
949
+ }
950
+
951
+ .subagent-status {
952
+ font-size: 11px;
953
+ color: var(--muted);
954
+ font-weight: 500;
955
+ }
956
+
957
+ .subagent-task {
958
+ padding: 10px 14px;
959
+ background: rgba(0, 0, 0, 0.15);
960
+ border-bottom: 1px solid var(--border);
961
+ }
962
+
963
+ .subagent-task-label {
964
+ font-size: 10px;
965
+ text-transform: uppercase;
966
+ letter-spacing: 0.06em;
967
+ color: var(--muted);
968
+ margin-bottom: 4px;
969
+ font-weight: 600;
970
+ }
971
+
972
+ .subagent-task-text {
973
+ font-size: 13px;
974
+ line-height: 1.5;
975
+ color: var(--text);
976
+ white-space: pre-wrap;
977
+ word-break: break-word;
978
+ }
979
+
980
+ .subagent-params {
981
+ padding: 8px 14px;
982
+ background: rgba(0, 0, 0, 0.1);
983
+ border-bottom: 1px solid var(--border);
984
+ display: flex;
985
+ flex-direction: column;
986
+ gap: 4px;
987
+ }
988
+
989
+ .subagent-param {
990
+ font-family: var(--mono);
991
+ font-size: 11px;
992
+ color: rgba(255, 255, 255, 0.7);
993
+ padding: 4px 8px;
994
+ background: rgba(255, 255, 255, 0.03);
995
+ border-radius: 4px;
996
+ border: 1px solid rgba(255, 255, 255, 0.08);
997
+ }
998
+
999
+ .subagent-result {
1000
+ padding: 10px 14px;
1001
+ }
1002
+
1003
+ @media (max-width: 980px) {
1004
+ .app {
1005
+ grid-template-columns: 1fr;
1006
+ }
1007
+ .sidebar {
1008
+ display: none;
1009
+ }
1010
+ .modal-body {
1011
+ grid-template-columns: 1fr;
1012
+ }
1013
+ }
1014
+
1015
+ /* =============================================
1016
+ Control Plane — shared base styles
1017
+ ============================================= */
1018
+
1019
+ .control-plane {
1020
+ display: flex;
1021
+ flex-direction: column;
1022
+ gap: 0;
1023
+ height: 100%;
1024
+ min-height: 0;
1025
+ }
1026
+
1027
+ /* Top header bar */
1028
+ .cp-header {
1029
+ display: flex;
1030
+ align-items: center;
1031
+ justify-content: space-between;
1032
+ gap: 12px;
1033
+ padding: 12px 16px;
1034
+ border-bottom: 1px solid var(--border);
1035
+ flex-shrink: 0;
1036
+ }
1037
+
1038
+ .cp-header h1 {
1039
+ margin: 0;
1040
+ font-size: 16px;
1041
+ }
1042
+
1043
+ .cp-header-actions {
1044
+ display: flex;
1045
+ gap: 8px;
1046
+ }
1047
+
1048
+ .cp-subtitle {
1049
+ font-size: 13px;
1050
+ color: var(--muted);
1051
+ margin-top: 3px;
1052
+ }
1053
+
1054
+ /* Body area below header — sidebar + main */
1055
+ .cp-body {
1056
+ display: flex;
1057
+ flex: 1;
1058
+ min-height: 0;
1059
+ overflow: hidden;
1060
+ }
1061
+
1062
+ /* =============================================
1063
+ PC Sidebar
1064
+ ============================================= */
1065
+
1066
+ .cp-sidebar {
1067
+ width: 260px;
1068
+ flex-shrink: 0;
1069
+ border-right: 1px solid var(--border);
1070
+ display: flex;
1071
+ flex-direction: column;
1072
+ overflow: hidden;
1073
+ background: var(--panel-2);
1074
+ }
1075
+
1076
+ .cp-sidebar-section-label {
1077
+ padding: 10px 12px 6px;
1078
+ font-size: 11px;
1079
+ font-weight: 700;
1080
+ color: var(--muted);
1081
+ text-transform: uppercase;
1082
+ letter-spacing: 0.08em;
1083
+ flex-shrink: 0;
1084
+ display: flex;
1085
+ align-items: center;
1086
+ gap: 6px;
1087
+ }
1088
+
1089
+ .cp-sidebar-workers-label {
1090
+ border-top: 1px solid var(--border);
1091
+ }
1092
+
1093
+ .cp-sidebar-workers-count {
1094
+ background: rgba(255, 255, 255, 0.08);
1095
+ border-radius: 999px;
1096
+ padding: 1px 7px;
1097
+ font-size: 11px;
1098
+ font-weight: 600;
1099
+ color: var(--muted);
1100
+ }
1101
+
1102
+ /* Broadcast summary section in sidebar */
1103
+ .cp-sidebar-broadcast-section {
1104
+ padding: 10px 12px 12px;
1105
+ border-bottom: 1px solid var(--border);
1106
+ flex-shrink: 0;
1107
+ display: flex;
1108
+ flex-direction: column;
1109
+ gap: 8px;
1110
+ }
1111
+
1112
+ .cp-sidebar-broadcast-target {
1113
+ font-size: 12px;
1114
+ color: var(--muted);
1115
+ }
1116
+
1117
+ .cp-sidebar-broadcast-btn {
1118
+ width: 100%;
1119
+ justify-content: center;
1120
+ }
1121
+
1122
+ /* Worker nav list inside sidebar */
1123
+ .cp-sidebar-workers {
1124
+ flex: 1;
1125
+ overflow-y: auto;
1126
+ padding: 4px 0 8px;
1127
+ }
1128
+
1129
+ .cp-sidebar-worker-item {
1130
+ display: flex;
1131
+ align-items: flex-start;
1132
+ gap: 8px;
1133
+ padding: 8px 12px;
1134
+ cursor: pointer;
1135
+ transition: background 0.12s;
1136
+ border-left: 2px solid transparent;
1137
+ }
1138
+
1139
+ .cp-sidebar-worker-item:hover {
1140
+ background: rgba(255, 255, 255, 0.04);
1141
+ }
1142
+
1143
+ .cp-sidebar-worker-item.active {
1144
+ background: rgba(122, 162, 247, 0.08);
1145
+ border-left-color: var(--accent);
1146
+ }
1147
+
1148
+ .cp-sidebar-worker-item input[type='checkbox'] {
1149
+ width: 14px;
1150
+ height: 14px;
1151
+ flex-shrink: 0;
1152
+ cursor: pointer;
1153
+ margin-top: 3px;
1154
+ }
1155
+
1156
+ .cp-sidebar-worker-info {
1157
+ flex: 1;
1158
+ min-width: 0;
1159
+ display: flex;
1160
+ flex-direction: column;
1161
+ gap: 2px;
1162
+ }
1163
+
1164
+ .cp-sidebar-worker-name {
1165
+ font-size: 13px;
1166
+ font-weight: 500;
1167
+ line-height: 1.4;
1168
+ word-break: break-word;
1169
+ }
1170
+
1171
+ .cp-sidebar-worker-url {
1172
+ font-family: var(--mono);
1173
+ font-size: 11px;
1174
+ color: var(--muted);
1175
+ word-break: break-all;
1176
+ line-height: 1.4;
1177
+ }
1178
+
1179
+ .cp-sidebar-worker-tags {
1180
+ font-size: 11px;
1181
+ color: rgba(187, 154, 247, 0.7);
1182
+ line-height: 1.4;
1183
+ }
1184
+
1185
+ .cp-sidebar-worker-status {
1186
+ flex-shrink: 0;
1187
+ margin-top: 2px;
1188
+ }
1189
+
1190
+ /* =============================================
1191
+ PC Broadcast Modal
1192
+ ============================================= */
1193
+
1194
+ .cp-broadcast-modal-backdrop {
1195
+ position: fixed;
1196
+ inset: 0;
1197
+ background: rgba(0, 0, 0, 0.6);
1198
+ z-index: 300;
1199
+ display: flex;
1200
+ align-items: center;
1201
+ justify-content: center;
1202
+ padding: 20px;
1203
+ backdrop-filter: blur(3px);
1204
+ }
1205
+
1206
+ .cp-broadcast-modal {
1207
+ width: min(860px, 96vw);
1208
+ max-height: 88vh;
1209
+ background: rgba(16, 21, 33, 0.98);
1210
+ border: 1px solid var(--border);
1211
+ border-radius: 16px;
1212
+ box-shadow: var(--shadow);
1213
+ display: flex;
1214
+ flex-direction: column;
1215
+ overflow: hidden;
1216
+ }
1217
+
1218
+ .cp-broadcast-modal-header {
1219
+ display: flex;
1220
+ align-items: center;
1221
+ justify-content: space-between;
1222
+ padding: 14px 18px;
1223
+ border-bottom: 1px solid var(--border);
1224
+ flex-shrink: 0;
1225
+ }
1226
+
1227
+ .cp-broadcast-modal-title {
1228
+ font-size: 15px;
1229
+ font-weight: 650;
1230
+ }
1231
+
1232
+ .cp-broadcast-modal-close {
1233
+ background: none;
1234
+ border: none;
1235
+ color: var(--muted);
1236
+ font-size: 16px;
1237
+ cursor: pointer;
1238
+ padding: 4px 8px;
1239
+ border-radius: 6px;
1240
+ line-height: 1;
1241
+ }
1242
+
1243
+ .cp-broadcast-modal-close:hover {
1244
+ background: rgba(255, 255, 255, 0.06);
1245
+ color: var(--text);
1246
+ }
1247
+
1248
+ .cp-broadcast-modal-body {
1249
+ display: grid;
1250
+ grid-template-columns: 1fr 320px;
1251
+ gap: 0;
1252
+ flex: 1;
1253
+ min-height: 0;
1254
+ overflow: hidden;
1255
+ }
1256
+
1257
+ .cp-broadcast-modal-left {
1258
+ display: flex;
1259
+ flex-direction: column;
1260
+ padding: 14px 18px;
1261
+ gap: 10px;
1262
+ border-right: 1px solid var(--border);
1263
+ min-height: 0;
1264
+ }
1265
+
1266
+ .cp-broadcast-modal-right {
1267
+ display: flex;
1268
+ flex-direction: column;
1269
+ min-height: 0;
1270
+ overflow: hidden;
1271
+ }
1272
+
1273
+ .cp-broadcast-modal-label {
1274
+ font-size: 11px;
1275
+ font-weight: 700;
1276
+ color: var(--muted);
1277
+ text-transform: uppercase;
1278
+ letter-spacing: 0.08em;
1279
+ display: flex;
1280
+ align-items: center;
1281
+ justify-content: space-between;
1282
+ gap: 8px;
1283
+ flex-shrink: 0;
1284
+ }
1285
+
1286
+ .cp-broadcast-modal-node-actions {
1287
+ display: flex;
1288
+ gap: 6px;
1289
+ }
1290
+
1291
+ .cp-broadcast-modal-textarea {
1292
+ flex: 1;
1293
+ min-height: 160px;
1294
+ resize: none;
1295
+ border: 1px solid var(--border);
1296
+ border-radius: var(--radius-sm);
1297
+ background: rgba(255, 255, 255, 0.03);
1298
+ color: var(--text);
1299
+ padding: 10px 12px;
1300
+ font-size: 14px;
1301
+ line-height: 1.5;
1302
+ }
1303
+
1304
+ .cp-broadcast-modal-textarea:focus {
1305
+ outline: none;
1306
+ border-color: rgba(122, 162, 247, 0.5);
1307
+ box-shadow: 0 0 0 3px rgba(122, 162, 247, 0.1);
1308
+ }
1309
+
1310
+ .cp-broadcast-modal-footer {
1311
+ display: flex;
1312
+ align-items: center;
1313
+ justify-content: space-between;
1314
+ gap: 10px;
1315
+ flex-shrink: 0;
1316
+ }
1317
+
1318
+ .cp-broadcast-modal-target {
1319
+ font-size: 12px;
1320
+ color: var(--muted);
1321
+ }
1322
+
1323
+ .cp-broadcast-modal-node-list {
1324
+ flex: 1;
1325
+ overflow-y: auto;
1326
+ padding: 8px 0;
1327
+ }
1328
+
1329
+ .cp-broadcast-modal-node-item {
1330
+ display: flex;
1331
+ align-items: flex-start;
1332
+ gap: 10px;
1333
+ padding: 8px 16px;
1334
+ cursor: pointer;
1335
+ transition: background 0.1s;
1336
+ }
1337
+
1338
+ .cp-broadcast-modal-node-item:hover {
1339
+ background: rgba(255, 255, 255, 0.04);
1340
+ }
1341
+
1342
+ .cp-broadcast-modal-node-item input[type='checkbox'] {
1343
+ width: 15px;
1344
+ height: 15px;
1345
+ flex-shrink: 0;
1346
+ cursor: pointer;
1347
+ margin-top: 2px;
1348
+ }
1349
+
1350
+ .cp-broadcast-modal-node-info {
1351
+ display: flex;
1352
+ flex-direction: column;
1353
+ gap: 2px;
1354
+ min-width: 0;
1355
+ }
1356
+
1357
+ .cp-broadcast-modal-node-name {
1358
+ font-size: 13px;
1359
+ font-weight: 500;
1360
+ line-height: 1.4;
1361
+ word-break: break-word;
1362
+ }
1363
+
1364
+ .cp-broadcast-modal-node-url {
1365
+ font-family: var(--mono);
1366
+ font-size: 11px;
1367
+ color: var(--muted);
1368
+ word-break: break-all;
1369
+ }
1370
+
1371
+ .cp-broadcast-modal-node-tags {
1372
+ font-size: 11px;
1373
+ color: rgba(187, 154, 247, 0.7);
1374
+ }
1375
+
1376
+ /* =============================================
1377
+ PC Main area — worker grid
1378
+ ============================================= */
1379
+
1380
+ .cp-main {
1381
+ flex: 1;
1382
+ min-width: 0;
1383
+ display: flex;
1384
+ flex-direction: column;
1385
+ overflow: hidden;
1386
+ }
1387
+
1388
+ .cp-workers {
1389
+ flex: 1;
1390
+ overflow: auto;
1391
+ display: flex;
1392
+ flex-direction: column;
1393
+ }
1394
+
1395
+ .cp-workers-header {
1396
+ padding: 12px 16px 0;
1397
+ font-size: 11px;
1398
+ color: var(--muted);
1399
+ text-transform: uppercase;
1400
+ letter-spacing: 0.08em;
1401
+ flex-shrink: 0;
1402
+ display: flex;
1403
+ align-items: center;
1404
+ justify-content: space-between;
1405
+ }
1406
+
1407
+ .cp-workers-header .btn {
1408
+ text-transform: none;
1409
+ letter-spacing: normal;
1410
+ font-size: 11px;
1411
+ padding: 2px 8px;
1412
+ }
1413
+
1414
+ .cp-worker-grid {
1415
+ display: grid;
1416
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
1417
+ gap: 12px;
1418
+ padding: 12px 16px 16px;
1419
+ align-content: start;
1420
+ }
1421
+
1422
+ /* =============================================
1423
+ Worker task cards
1424
+ ============================================= */
1425
+
1426
+ .cp-task-card {
1427
+ border: 2px solid var(--border);
1428
+ border-radius: var(--radius);
1429
+ background: rgba(255, 255, 255, 0.02);
1430
+ overflow: hidden;
1431
+ display: flex;
1432
+ flex-direction: column;
1433
+ cursor: pointer;
1434
+ transition: border-color 0.15s ease;
1435
+ max-height: 30vh;
1436
+ min-height: 180px;
1437
+ }
1438
+
1439
+ .cp-task-card:hover {
1440
+ border-color: rgba(255, 255, 255, 0.2);
1441
+ }
1442
+
1443
+ .cp-task-card.selected {
1444
+ border-color: var(--ok);
1445
+ }
1446
+
1447
+ .cp-task-card.error {
1448
+ border-color: var(--err);
1449
+ }
1450
+
1451
+ .cp-task-card.selected.error {
1452
+ border-color: var(--err);
1453
+ }
1454
+
1455
+ .cp-task-header {
1456
+ display: flex;
1457
+ flex-direction: column;
1458
+ gap: 6px;
1459
+ padding: 8px 10px;
1460
+ border-bottom: 1px solid var(--border);
1461
+ flex-shrink: 0;
1462
+ }
1463
+
1464
+ .cp-task-header-top {
1465
+ display: flex;
1466
+ align-items: flex-start;
1467
+ justify-content: space-between;
1468
+ gap: 8px;
1469
+ }
1470
+
1471
+ .cp-task-header-left {
1472
+ display: flex;
1473
+ align-items: flex-start;
1474
+ gap: 8px;
1475
+ min-width: 0;
1476
+ flex: 1;
1477
+ }
1478
+
1479
+ .cp-task-header-info {
1480
+ min-width: 0;
1481
+ flex: 1;
1482
+ display: flex;
1483
+ flex-direction: column;
1484
+ gap: 2px;
1485
+ /* Keep title + URL as two explicit lines; do not clip the link row away */
1486
+ overflow: visible;
1487
+ }
1488
+
1489
+ .cp-task-name {
1490
+ font-weight: 600;
1491
+ font-size: 13px;
1492
+ line-height: 1.35;
1493
+ /* Line 1: title only; URL is always the next sibling on line 2 */
1494
+ overflow: hidden;
1495
+ text-overflow: ellipsis;
1496
+ white-space: nowrap;
1497
+ }
1498
+
1499
+ .cp-task-url {
1500
+ font-size: 11px;
1501
+ color: var(--muted);
1502
+ display: block;
1503
+ line-height: 1.35;
1504
+ word-break: break-all;
1505
+ /* Second line dedicated to link; wrap instead of single-line ellipsis */
1506
+ overflow-wrap: anywhere;
1507
+ }
1508
+
1509
+ .cp-task-meta {
1510
+ display: flex;
1511
+ flex-direction: row;
1512
+ align-items: center;
1513
+ gap: 6px;
1514
+ font-size: 11px;
1515
+ color: var(--muted);
1516
+ flex-shrink: 0;
1517
+ margin-left: auto;
1518
+ }
1519
+
1520
+ .cp-conn {
1521
+ padding: 2px 6px;
1522
+ border-radius: 6px;
1523
+ border: 1px solid var(--border);
1524
+ font-size: 10px;
1525
+ color: var(--muted);
1526
+ text-transform: uppercase;
1527
+ }
1528
+
1529
+ .cp-conn.connected {
1530
+ color: var(--ok);
1531
+ border-color: rgba(158, 206, 106, 0.4);
1532
+ }
1533
+
1534
+ .cp-conn.disconnected {
1535
+ color: var(--err);
1536
+ border-color: rgba(247, 118, 142, 0.4);
1537
+ }
1538
+
1539
+ .cp-queue,
1540
+ .cp-activity {
1541
+ font-size: 11px;
1542
+ }
1543
+
1544
+ /* One row: Cancel / Refresh / Retry + idle activity timestamp */
1545
+ .cp-task-actions-row {
1546
+ display: flex;
1547
+ flex-direction: row;
1548
+ flex-wrap: wrap;
1549
+ align-items: center;
1550
+ gap: 8px;
1551
+ }
1552
+
1553
+ .cp-task-actions {
1554
+ display: flex;
1555
+ flex-direction: row;
1556
+ gap: 6px;
1557
+ flex-shrink: 0;
1558
+ flex-wrap: wrap;
1559
+ }
1560
+
1561
+ .cp-task-actions-time {
1562
+ flex-shrink: 0;
1563
+ }
1564
+
1565
+ .cp-task-actions .btn {
1566
+ padding: 2px 8px;
1567
+ font-size: 11px;
1568
+ }
1569
+
1570
+ .cp-task-error {
1571
+ padding: 6px 12px;
1572
+ font-size: 12px;
1573
+ color: var(--err);
1574
+ border-bottom: 1px solid var(--border);
1575
+ flex-shrink: 0;
1576
+ }
1577
+
1578
+ .cp-task-notice {
1579
+ padding: 6px 12px;
1580
+ font-size: 12px;
1581
+ color: var(--warn);
1582
+ border-bottom: 1px solid var(--border);
1583
+ background: rgba(224, 175, 104, 0.06);
1584
+ white-space: pre-wrap;
1585
+ flex-shrink: 0;
1586
+ }
1587
+
1588
+ .cp-task-body {
1589
+ padding: 10px 12px;
1590
+ overflow: auto;
1591
+ flex: 1;
1592
+ min-height: 60px;
1593
+ }
1594
+
1595
+ .cp-task-message,
1596
+ .cp-task-tool {
1597
+ margin-bottom: 10px;
1598
+ }
1599
+
1600
+ .cp-task-input {
1601
+ display: flex;
1602
+ gap: 8px;
1603
+ padding: 10px 12px;
1604
+ border-top: 1px solid var(--border);
1605
+ background: rgba(0, 0, 0, 0.1);
1606
+ flex-shrink: 0;
1607
+ }
1608
+
1609
+ .cp-task-textarea {
1610
+ flex: 1;
1611
+ min-height: 40px;
1612
+ max-height: 80px;
1613
+ resize: vertical;
1614
+ border: 1px solid var(--border);
1615
+ border-radius: var(--radius-sm);
1616
+ background: rgba(255, 255, 255, 0.03);
1617
+ color: var(--text);
1618
+ padding: 8px 10px;
1619
+ font-size: 13px;
1620
+ line-height: 1.4;
1621
+ }
1622
+
1623
+ .cp-task-input .btn {
1624
+ align-self: flex-end;
1625
+ }
1626
+
1627
+ /* =============================================
1628
+ Endpoint registry Drawer (right side)
1629
+ ============================================= */
1630
+
1631
+ .cp-drawer {
1632
+ position: fixed;
1633
+ top: 0;
1634
+ right: 0;
1635
+ bottom: 0;
1636
+ width: 600px;
1637
+ max-width: 100%;
1638
+ z-index: 100;
1639
+ background: var(--panel-2);
1640
+ border-left: 1px solid var(--border);
1641
+ box-shadow: -4px 0 20px rgba(0, 0, 0, 0.5);
1642
+ transform: translateX(100%);
1643
+ transition: transform 0.2s ease;
1644
+ display: flex;
1645
+ flex-direction: column;
1646
+ }
1647
+
1648
+ .cp-drawer.open {
1649
+ transform: translateX(0);
1650
+ }
1651
+
1652
+ .cp-drawer-backdrop {
1653
+ position: fixed;
1654
+ inset: 0;
1655
+ background: rgba(0, 0, 0, 0.5);
1656
+ z-index: 90;
1657
+ backdrop-filter: blur(2px);
1658
+ }
1659
+
1660
+ .cp-drawer-header {
1661
+ display: flex;
1662
+ align-items: center;
1663
+ justify-content: space-between;
1664
+ gap: 12px;
1665
+ padding: 14px 16px;
1666
+ border-bottom: 1px solid var(--border);
1667
+ position: sticky;
1668
+ top: 0;
1669
+ background: var(--panel-2);
1670
+ z-index: 10;
1671
+ }
1672
+
1673
+ .cp-drawer-header h2 {
1674
+ margin: 0;
1675
+ font-size: 14px;
1676
+ }
1677
+
1678
+ .cp-drawer-toolbar {
1679
+ display: flex;
1680
+ flex-direction: column;
1681
+ gap: 8px;
1682
+ padding: 12px 16px;
1683
+ border-bottom: 1px solid var(--border);
1684
+ }
1685
+
1686
+ .cp-drawer-content {
1687
+ flex: 1;
1688
+ overflow: auto;
1689
+ padding: 12px 16px;
1690
+ }
1691
+
1692
+ /* =============================================
1693
+ Shared form elements
1694
+ ============================================= */
1695
+
1696
+ .cp-input,
1697
+ .cp-select {
1698
+ background: rgba(255, 255, 255, 0.03);
1699
+ border: 1px solid var(--border);
1700
+ color: var(--text);
1701
+ border-radius: var(--radius-sm);
1702
+ padding: 8px 10px;
1703
+ font-size: 13px;
1704
+ width: 100%;
1705
+ }
1706
+
1707
+ .cp-select {
1708
+ min-width: 100px;
1709
+ }
1710
+
1711
+ .cp-content {
1712
+ padding: 12px 16px;
1713
+ overflow: auto;
1714
+ flex: 1;
1715
+ }
1716
+
1717
+ .cp-list {
1718
+ display: flex;
1719
+ flex-direction: column;
1720
+ gap: 10px;
1721
+ }
1722
+
1723
+ .cp-row {
1724
+ display: flex;
1725
+ justify-content: space-between;
1726
+ gap: 12px;
1727
+ padding: 10px 12px;
1728
+ border: 1px solid var(--border);
1729
+ border-radius: var(--radius);
1730
+ background: rgba(255, 255, 255, 0.03);
1731
+ }
1732
+
1733
+ .cp-select-box {
1734
+ display: flex;
1735
+ align-items: flex-start;
1736
+ padding-top: 3px;
1737
+ }
1738
+
1739
+ .cp-select-box input {
1740
+ width: 15px;
1741
+ height: 15px;
1742
+ }
1743
+
1744
+ .cp-row-main {
1745
+ flex: 1;
1746
+ min-width: 0;
1747
+ }
1748
+
1749
+ .cp-row-title {
1750
+ display: flex;
1751
+ flex-direction: column;
1752
+ gap: 3px;
1753
+ }
1754
+
1755
+ .cp-name {
1756
+ font-weight: 600;
1757
+ font-size: 13px;
1758
+ }
1759
+
1760
+ .cp-url {
1761
+ font-family: var(--mono);
1762
+ font-size: 11px;
1763
+ color: var(--muted);
1764
+ word-break: break-all;
1765
+ }
1766
+
1767
+ .cp-row-meta {
1768
+ display: flex;
1769
+ align-items: center;
1770
+ gap: 10px;
1771
+ flex-wrap: wrap;
1772
+ margin-top: 6px;
1773
+ }
1774
+
1775
+ .cp-tags {
1776
+ display: flex;
1777
+ gap: 6px;
1778
+ flex-wrap: wrap;
1779
+ }
1780
+
1781
+ .cp-tag {
1782
+ padding: 2px 6px;
1783
+ border: 1px solid var(--border);
1784
+ border-radius: 6px;
1785
+ font-size: 11px;
1786
+ color: var(--muted);
1787
+ }
1788
+
1789
+ .cp-tag.muted {
1790
+ opacity: 0.6;
1791
+ }
1792
+
1793
+ .cp-actions {
1794
+ display: flex;
1795
+ gap: 6px;
1796
+ align-items: center;
1797
+ }
1798
+
1799
+ .cp-health {
1800
+ font-size: 11px;
1801
+ padding: 2px 6px;
1802
+ border-radius: 6px;
1803
+ border: 1px solid var(--border);
1804
+ color: var(--muted);
1805
+ }
1806
+
1807
+ .cp-health.ok {
1808
+ color: var(--ok);
1809
+ border-color: rgba(158, 206, 106, 0.4);
1810
+ }
1811
+
1812
+ .cp-health.err {
1813
+ color: var(--err);
1814
+ border-color: rgba(247, 118, 142, 0.4);
1815
+ }
1816
+
1817
+ .cp-health.pending {
1818
+ color: var(--muted);
1819
+ }
1820
+
1821
+ .cp-health-ms {
1822
+ margin-left: 6px;
1823
+ color: var(--muted);
1824
+ font-size: 11px;
1825
+ }
1826
+
1827
+ .cp-pagination {
1828
+ display: flex;
1829
+ align-items: center;
1830
+ justify-content: space-between;
1831
+ gap: 10px;
1832
+ padding: 10px 16px;
1833
+ border-top: 1px solid var(--border);
1834
+ }
1835
+
1836
+ .cp-page-info,
1837
+ .cp-page-number {
1838
+ font-size: 12px;
1839
+ color: var(--muted);
1840
+ }
1841
+
1842
+ .cp-page-controls {
1843
+ display: flex;
1844
+ align-items: center;
1845
+ gap: 8px;
1846
+ }
1847
+
1848
+ .cp-modal-body {
1849
+ display: flex;
1850
+ flex-direction: column;
1851
+ gap: 10px;
1852
+ padding: 12px;
1853
+ }
1854
+
1855
+ .cp-label {
1856
+ display: flex;
1857
+ flex-direction: column;
1858
+ gap: 6px;
1859
+ font-size: 13px;
1860
+ color: var(--muted);
1861
+ }
1862
+
1863
+ .cp-modal-actions {
1864
+ display: flex;
1865
+ gap: 8px;
1866
+ }
1867
+
1868
+ .cp-error {
1869
+ color: var(--err);
1870
+ font-size: 13px;
1871
+ margin-top: 6px;
1872
+ }
1873
+
1874
+ .cp-loading,
1875
+ .cp-empty {
1876
+ color: var(--muted);
1877
+ font-size: 13px;
1878
+ padding: 10px 0;
1879
+ }
1880
+
1881
+ /* =============================================
1882
+ Mobile — Worker compact list card
1883
+ ============================================= */
1884
+
1885
+ .cp-task-card-compact {
1886
+ display: flex;
1887
+ align-items: center;
1888
+ gap: 10px;
1889
+ padding: 12px 14px;
1890
+ border: 1px solid var(--border);
1891
+ border-radius: var(--radius);
1892
+ background: rgba(255, 255, 255, 0.02);
1893
+ cursor: pointer;
1894
+ transition: background 0.12s;
1895
+ -webkit-tap-highlight-color: transparent;
1896
+ }
1897
+
1898
+ .cp-task-card-compact:active {
1899
+ background: rgba(255, 255, 255, 0.05);
1900
+ }
1901
+
1902
+ .cp-task-card-compact.error {
1903
+ border-color: rgba(247, 118, 142, 0.35);
1904
+ }
1905
+
1906
+ .cp-task-card-compact input[type='checkbox'] {
1907
+ width: 18px;
1908
+ height: 18px;
1909
+ flex-shrink: 0;
1910
+ cursor: pointer;
1911
+ }
1912
+
1913
+ .cp-task-card-compact-body {
1914
+ flex: 1;
1915
+ min-width: 0;
1916
+ }
1917
+
1918
+ .cp-task-card-compact-top {
1919
+ display: flex;
1920
+ align-items: center;
1921
+ gap: 8px;
1922
+ margin-bottom: 4px;
1923
+ }
1924
+
1925
+ .cp-task-card-compact-name {
1926
+ font-size: 14px;
1927
+ font-weight: 600;
1928
+ flex: 1;
1929
+ min-width: 0;
1930
+ overflow: hidden;
1931
+ text-overflow: ellipsis;
1932
+ white-space: nowrap;
1933
+ }
1934
+
1935
+ .cp-task-card-compact-meta {
1936
+ font-size: 11px;
1937
+ color: var(--muted);
1938
+ display: flex;
1939
+ gap: 8px;
1940
+ }
1941
+
1942
+ .cp-task-card-compact-preview {
1943
+ font-size: 12px;
1944
+ color: var(--muted);
1945
+ overflow: hidden;
1946
+ text-overflow: ellipsis;
1947
+ white-space: nowrap;
1948
+ }
1949
+
1950
+ .cp-task-card-compact-chevron {
1951
+ color: var(--muted);
1952
+ flex-shrink: 0;
1953
+ font-size: 16px;
1954
+ opacity: 0.5;
1955
+ }
1956
+
1957
+ /* =============================================
1958
+ Mobile — Detail view
1959
+ ============================================= */
1960
+
1961
+ .cp-mobile-detail {
1962
+ display: flex;
1963
+ flex-direction: column;
1964
+ flex: 1;
1965
+ min-height: 0;
1966
+ overflow: hidden;
1967
+ }
1968
+
1969
+ .cp-mobile-header-title {
1970
+ font-size: 16px;
1971
+ font-weight: 700;
1972
+ margin: 0;
1973
+ }
1974
+
1975
+ .cp-mobile-back-btn {
1976
+ display: flex;
1977
+ align-items: center;
1978
+ gap: 4px;
1979
+ background: none;
1980
+ border: none;
1981
+ color: var(--accent);
1982
+ font-size: 15px;
1983
+ cursor: pointer;
1984
+ padding: 4px 0;
1985
+ flex-shrink: 0;
1986
+ }
1987
+
1988
+ .cp-mobile-detail-title {
1989
+ font-size: 15px;
1990
+ font-weight: 600;
1991
+ overflow: hidden;
1992
+ text-overflow: ellipsis;
1993
+ white-space: nowrap;
1994
+ }
1995
+
1996
+ .cp-mobile-detail-feed {
1997
+ flex: 1;
1998
+ overflow: auto;
1999
+ padding: 10px 14px;
2000
+ min-height: 0;
2001
+ }
2002
+
2003
+ .cp-mobile-detail-input {
2004
+ display: flex;
2005
+ gap: 8px;
2006
+ padding: 10px 14px;
2007
+ border-top: 1px solid var(--border);
2008
+ background: rgba(0, 0, 0, 0.1);
2009
+ flex-shrink: 0;
2010
+ }
2011
+
2012
+ .cp-mobile-detail-textarea {
2013
+ flex: 1;
2014
+ min-height: 44px;
2015
+ max-height: 120px;
2016
+ resize: none;
2017
+ border: 1px solid var(--border);
2018
+ border-radius: var(--radius-sm);
2019
+ background: rgba(255, 255, 255, 0.03);
2020
+ color: var(--text);
2021
+ padding: 10px 12px;
2022
+ font-size: 14px;
2023
+ line-height: 1.4;
2024
+ }
2025
+
2026
+ .cp-mobile-detail-send {
2027
+ align-self: flex-end;
2028
+ min-height: 44px;
2029
+ padding: 0 18px;
2030
+ }
2031
+
2032
+ /* =============================================
2033
+ Mobile — Bottom Tab Bar
2034
+ ============================================= */
2035
+
2036
+ .cp-mobile-tab-bar {
2037
+ display: none;
2038
+ flex-shrink: 0;
2039
+ border-top: 1px solid var(--border);
2040
+ background: var(--panel-2);
2041
+ padding-bottom: env(safe-area-inset-bottom, 0px);
2042
+ }
2043
+
2044
+ .cp-mobile-tab {
2045
+ flex: 1;
2046
+ display: flex;
2047
+ flex-direction: column;
2048
+ align-items: center;
2049
+ justify-content: center;
2050
+ gap: 4px;
2051
+ padding: 10px 4px;
2052
+ background: none;
2053
+ border: none;
2054
+ color: var(--muted);
2055
+ font-size: 11px;
2056
+ cursor: pointer;
2057
+ position: relative;
2058
+ -webkit-tap-highlight-color: transparent;
2059
+ transition: color 0.12s;
2060
+ }
2061
+
2062
+ .cp-mobile-tab.active {
2063
+ color: var(--accent);
2064
+ }
2065
+
2066
+ .cp-mobile-tab svg {
2067
+ flex-shrink: 0;
2068
+ }
2069
+
2070
+ .cp-mobile-tab-broadcast {
2071
+ color: var(--muted);
2072
+ }
2073
+
2074
+ .cp-mobile-tab-badge {
2075
+ position: absolute;
2076
+ top: 6px;
2077
+ right: calc(50% - 18px);
2078
+ background: var(--accent);
2079
+ color: #0f111a;
2080
+ font-size: 10px;
2081
+ font-weight: 700;
2082
+ border-radius: 999px;
2083
+ padding: 1px 5px;
2084
+ min-width: 16px;
2085
+ text-align: center;
2086
+ line-height: 1.4;
2087
+ }
2088
+
2089
+ /* =============================================
2090
+ Mobile — Broadcast tab (inline, full height)
2091
+ ============================================= */
2092
+
2093
+ .cp-mobile-broadcast-tab {
2094
+ flex: 1;
2095
+ display: flex;
2096
+ flex-direction: column;
2097
+ overflow: hidden;
2098
+ min-height: 0;
2099
+ }
2100
+
2101
+ .cp-broadcast-sheet-nodes {
2102
+ border-bottom: 1px solid var(--border);
2103
+ overflow: hidden;
2104
+ flex: 1;
2105
+ display: flex;
2106
+ flex-direction: column;
2107
+ min-height: 0;
2108
+ }
2109
+
2110
+ .cp-broadcast-sheet-nodes-header {
2111
+ display: flex;
2112
+ align-items: center;
2113
+ justify-content: space-between;
2114
+ gap: 8px;
2115
+ padding: 10px 16px;
2116
+ border-bottom: 1px solid var(--border);
2117
+ background: rgba(255, 255, 255, 0.02);
2118
+ flex-shrink: 0;
2119
+ }
2120
+
2121
+ .cp-broadcast-sheet-subtitle {
2122
+ font-size: 13px;
2123
+ color: var(--muted);
2124
+ }
2125
+
2126
+ .cp-broadcast-sheet-node-list {
2127
+ overflow-y: auto;
2128
+ flex: 1;
2129
+ }
2130
+
2131
+ .cp-broadcast-sheet-node-item {
2132
+ display: flex;
2133
+ align-items: flex-start;
2134
+ gap: 12px;
2135
+ padding: 12px 16px;
2136
+ cursor: pointer;
2137
+ border-bottom: 1px solid rgba(255, 255, 255, 0.04);
2138
+ -webkit-tap-highlight-color: transparent;
2139
+ }
2140
+
2141
+ .cp-broadcast-sheet-node-item:active {
2142
+ background: rgba(255, 255, 255, 0.04);
2143
+ }
2144
+
2145
+ .cp-broadcast-sheet-node-item:last-child {
2146
+ border-bottom: none;
2147
+ }
2148
+
2149
+ .cp-broadcast-sheet-node-item input[type='checkbox'] {
2150
+ width: 18px;
2151
+ height: 18px;
2152
+ flex-shrink: 0;
2153
+ margin-top: 2px;
2154
+ cursor: pointer;
2155
+ }
2156
+
2157
+ .cp-broadcast-sheet-node-info {
2158
+ display: flex;
2159
+ flex-direction: column;
2160
+ gap: 3px;
2161
+ min-width: 0;
2162
+ }
2163
+
2164
+ .cp-broadcast-sheet-node-name {
2165
+ font-size: 14px;
2166
+ font-weight: 500;
2167
+ word-break: break-word;
2168
+ line-height: 1.4;
2169
+ }
2170
+
2171
+ .cp-broadcast-sheet-node-url {
2172
+ font-family: var(--mono);
2173
+ font-size: 12px;
2174
+ color: var(--muted);
2175
+ word-break: break-all;
2176
+ }
2177
+
2178
+ .cp-broadcast-sheet-compose {
2179
+ padding: 12px 16px;
2180
+ border-top: 1px solid var(--border);
2181
+ display: flex;
2182
+ flex-direction: column;
2183
+ gap: 10px;
2184
+ flex-shrink: 0;
2185
+ padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
2186
+ }
2187
+
2188
+ .cp-broadcast-sheet-textarea {
2189
+ width: 100%;
2190
+ min-height: 80px;
2191
+ max-height: 160px;
2192
+ resize: none;
2193
+ border: 1px solid var(--border);
2194
+ border-radius: var(--radius-sm);
2195
+ background: rgba(255, 255, 255, 0.03);
2196
+ color: var(--text);
2197
+ padding: 10px 12px;
2198
+ font-size: 14px;
2199
+ line-height: 1.4;
2200
+ }
2201
+
2202
+ .cp-broadcast-sheet-footer {
2203
+ display: flex;
2204
+ gap: 10px;
2205
+ }
2206
+
2207
+ .cp-broadcast-sheet-footer .btn {
2208
+ flex: 1;
2209
+ min-height: 44px;
2210
+ font-size: 14px;
2211
+ }
2212
+
2213
+ /* =============================================
2214
+ Mobile — Worker list view
2215
+ ============================================= */
2216
+
2217
+ .cp-mobile-list {
2218
+ flex: 1;
2219
+ overflow-y: auto;
2220
+ padding: 10px 12px;
2221
+ display: flex;
2222
+ flex-direction: column;
2223
+ gap: 8px;
2224
+ }
2225
+
2226
+ /* =============================================
2227
+ Mobile — Endpoints tab
2228
+ ============================================= */
2229
+
2230
+ .cp-mobile-endpoints-tab {
2231
+ flex: 1;
2232
+ display: flex;
2233
+ flex-direction: column;
2234
+ overflow: hidden;
2235
+ min-height: 0;
2236
+ }
2237
+
2238
+ .cp-mobile-endpoints-toolbar {
2239
+ padding: 10px 14px;
2240
+ border-bottom: 1px solid var(--border);
2241
+ flex-shrink: 0;
2242
+ }
2243
+
2244
+ /* =============================================
2245
+ Responsive breakpoints
2246
+ ============================================= */
2247
+
2248
+ /* Desktop: sidebar + broadcast modal, no mobile elements */
2249
+ @media (min-width: 769px) {
2250
+ .cp-sidebar {
2251
+ display: flex;
2252
+ }
2253
+ .cp-header-mobile,
2254
+ .cp-mobile-list,
2255
+ .cp-mobile-detail,
2256
+ .cp-mobile-tab-bar,
2257
+ .cp-mobile-endpoints-tab,
2258
+ .cp-mobile-broadcast-tab {
2259
+ display: none !important;
2260
+ }
2261
+ .cp-header-pc {
2262
+ display: flex;
2263
+ }
2264
+ }
2265
+
2266
+ /* Mobile: bottom tabs, no sidebar */
2267
+ @media (max-width: 768px) {
2268
+ .app {
2269
+ padding: 0;
2270
+ }
2271
+
2272
+ .cp-header-pc {
2273
+ display: none !important;
2274
+ }
2275
+
2276
+ .cp-header-mobile {
2277
+ display: flex;
2278
+ }
2279
+
2280
+ .cp-sidebar {
2281
+ display: none;
2282
+ }
2283
+
2284
+ .cp-main {
2285
+ display: none;
2286
+ }
2287
+
2288
+ .cp-mobile-tab-bar {
2289
+ display: flex;
2290
+ }
2291
+
2292
+ /* Body fills between header and tab bar */
2293
+ .cp-body {
2294
+ flex: 1;
2295
+ min-height: 0;
2296
+ overflow: hidden;
2297
+ position: relative;
2298
+ }
2299
+
2300
+ /* Drawer goes full screen on mobile */
2301
+ .cp-drawer {
2302
+ inset: 0;
2303
+ width: 100%;
2304
+ max-width: none;
2305
+ border-radius: 0;
2306
+ border: none;
2307
+ }
2308
+ .cp-drawer.open {
2309
+ width: 100%;
2310
+ }
2311
+
2312
+ /* Endpoint list rows stack vertically */
2313
+ .cp-row {
2314
+ flex-direction: column;
2315
+ gap: 8px;
2316
+ }
2317
+ .cp-actions {
2318
+ margin-top: 0;
2319
+ justify-content: flex-start;
2320
+ flex-wrap: wrap;
2321
+ gap: 8px;
2322
+ }
2323
+ .cp-actions .btn {
2324
+ min-height: 40px;
2325
+ flex: 1;
2326
+ }
2327
+
2328
+ .cp-input,
2329
+ .cp-select {
2330
+ min-height: 40px;
2331
+ font-size: 14px;
2332
+ }
2333
+
2334
+ .btn {
2335
+ min-height: 38px;
2336
+ }
2337
+
2338
+ /* Broadcast modal hidden on mobile (use sheet instead) */
2339
+ .cp-broadcast-modal-backdrop {
2340
+ display: none !important;
2341
+ }
2342
+ }
2343
+
2344
+ /* ─── Rollout Page ──────────────────────────────────────────────────────────── */
2345
+
2346
+ .rollout-app {
2347
+ display: flex;
2348
+ flex-direction: column;
2349
+ height: 100%;
2350
+ background: var(--bg);
2351
+ }
2352
+
2353
+ .rollout-stats {
2354
+ display: flex;
2355
+ gap: 20px;
2356
+ padding: 14px 24px;
2357
+ border-bottom: 1px solid var(--border);
2358
+ background: var(--panel);
2359
+ }
2360
+ .rollout-stat {
2361
+ text-align: center;
2362
+ min-width: 72px;
2363
+ }
2364
+ .rollout-stat-value {
2365
+ font-size: 22px;
2366
+ font-weight: 700;
2367
+ font-variant-numeric: tabular-nums;
2368
+ color: var(--text);
2369
+ }
2370
+ .rollout-stat-label {
2371
+ font-size: 11px;
2372
+ color: var(--muted);
2373
+ text-transform: uppercase;
2374
+ letter-spacing: 0.5px;
2375
+ margin-top: 2px;
2376
+ }
2377
+ .rollout-running {
2378
+ color: var(--accent);
2379
+ }
2380
+ .rollout-queued {
2381
+ color: var(--warn);
2382
+ }
2383
+ .rollout-completed {
2384
+ color: var(--ok);
2385
+ }
2386
+ .rollout-failed {
2387
+ color: var(--err);
2388
+ }
2389
+
2390
+ .rollout-body {
2391
+ display: flex;
2392
+ flex: 1;
2393
+ min-height: 0;
2394
+ overflow: hidden;
2395
+ }
2396
+
2397
+ .rollout-sidebar {
2398
+ width: 320px;
2399
+ border-right: 1px solid var(--border);
2400
+ background: var(--panel);
2401
+ display: flex;
2402
+ flex-direction: column;
2403
+ overflow-y: auto;
2404
+ }
2405
+ .rollout-sidebar-section {
2406
+ padding: 14px 16px;
2407
+ border-bottom: 1px solid var(--border);
2408
+ }
2409
+ .rollout-sidebar-queue {
2410
+ flex: 1;
2411
+ min-height: 0;
2412
+ display: flex;
2413
+ flex-direction: column;
2414
+ padding: 10px 16px;
2415
+ }
2416
+ .rollout-label {
2417
+ display: block;
2418
+ font-size: 12px;
2419
+ color: var(--muted);
2420
+ margin-bottom: 8px;
2421
+ text-transform: uppercase;
2422
+ letter-spacing: 0.5px;
2423
+ }
2424
+ .rollout-row {
2425
+ display: flex;
2426
+ gap: 8px;
2427
+ align-items: center;
2428
+ }
2429
+ .rollout-input,
2430
+ .rollout-textarea,
2431
+ .rollout-select {
2432
+ background: var(--panel-2);
2433
+ border: 1px solid var(--border);
2434
+ color: var(--text);
2435
+ padding: 7px 10px;
2436
+ border-radius: var(--radius-sm);
2437
+ font-size: 13px;
2438
+ font-family: var(--sans);
2439
+ outline: none;
2440
+ width: 100%;
2441
+ }
2442
+ .rollout-input:focus,
2443
+ .rollout-textarea:focus {
2444
+ border-color: var(--accent);
2445
+ }
2446
+ .rollout-input-sm {
2447
+ width: 70px;
2448
+ flex: 0 0 auto;
2449
+ }
2450
+ .rollout-textarea {
2451
+ resize: vertical;
2452
+ min-height: 80px;
2453
+ }
2454
+ .rollout-select {
2455
+ cursor: pointer;
2456
+ }
2457
+ .rollout-add-form {
2458
+ display: flex;
2459
+ flex-direction: column;
2460
+ gap: 8px;
2461
+ }
2462
+ .rollout-badge {
2463
+ background: var(--subtle);
2464
+ padding: 1px 7px;
2465
+ border-radius: 10px;
2466
+ font-size: 11px;
2467
+ font-weight: 600;
2468
+ }
2469
+ .rollout-queue-list {
2470
+ flex: 1;
2471
+ overflow-y: auto;
2472
+ display: flex;
2473
+ flex-direction: column;
2474
+ gap: 6px;
2475
+ }
2476
+ .rollout-queue-empty {
2477
+ color: var(--muted);
2478
+ font-size: 12px;
2479
+ padding: 8px 0;
2480
+ }
2481
+ .rollout-queue-item {
2482
+ background: var(--panel-2);
2483
+ border: 1px solid var(--border);
2484
+ border-radius: var(--radius-sm);
2485
+ padding: 8px 10px;
2486
+ }
2487
+ .rollout-queue-item-header {
2488
+ display: flex;
2489
+ justify-content: space-between;
2490
+ align-items: center;
2491
+ }
2492
+ .rollout-queue-item-prompt {
2493
+ font-size: 12px;
2494
+ color: var(--muted);
2495
+ margin-top: 4px;
2496
+ overflow: hidden;
2497
+ text-overflow: ellipsis;
2498
+ white-space: nowrap;
2499
+ }
2500
+
2501
+ .rollout-main {
2502
+ flex: 1;
2503
+ display: flex;
2504
+ flex-direction: column;
2505
+ min-width: 0;
2506
+ overflow: hidden;
2507
+ }
2508
+ .rollout-main-header {
2509
+ display: flex;
2510
+ align-items: center;
2511
+ justify-content: space-between;
2512
+ padding: 12px 20px;
2513
+ border-bottom: 1px solid var(--border);
2514
+ }
2515
+ .rollout-main-title {
2516
+ font-size: 15px;
2517
+ font-weight: 600;
2518
+ }
2519
+ .rollout-main-controls {
2520
+ display: flex;
2521
+ gap: 8px;
2522
+ align-items: center;
2523
+ }
2524
+ .rollout-main-controls .rollout-select {
2525
+ width: auto;
2526
+ min-width: 100px;
2527
+ }
2528
+ .rollout-task-list {
2529
+ flex: 1;
2530
+ overflow-y: auto;
2531
+ padding: 16px 20px;
2532
+ display: flex;
2533
+ flex-direction: column;
2534
+ gap: 12px;
2535
+ }
2536
+ .rollout-empty {
2537
+ text-align: center;
2538
+ padding: 40px;
2539
+ color: var(--muted);
2540
+ }
2541
+ .rollout-task-card {
2542
+ background: var(--panel);
2543
+ border: 1px solid var(--border);
2544
+ border-radius: var(--radius);
2545
+ padding: 14px 16px;
2546
+ transition: border-color 0.15s;
2547
+ }
2548
+ .rollout-task-card:hover {
2549
+ border-color: var(--muted);
2550
+ }
2551
+ .rollout-task-card-header {
2552
+ display: flex;
2553
+ align-items: center;
2554
+ justify-content: space-between;
2555
+ margin-bottom: 8px;
2556
+ }
2557
+ .rollout-task-card-left {
2558
+ display: flex;
2559
+ gap: 8px;
2560
+ align-items: center;
2561
+ flex-wrap: wrap;
2562
+ }
2563
+ .rollout-task-id {
2564
+ font-family: var(--mono);
2565
+ font-size: 12px;
2566
+ color: var(--muted);
2567
+ }
2568
+ .rollout-task-model {
2569
+ font-size: 11px;
2570
+ padding: 2px 8px;
2571
+ border-radius: 10px;
2572
+ background: var(--subtle);
2573
+ color: var(--muted);
2574
+ }
2575
+ .rollout-task-tags {
2576
+ font-size: 11px;
2577
+ color: var(--accent-2);
2578
+ }
2579
+ .rollout-task-status {
2580
+ font-size: 12px;
2581
+ font-weight: 600;
2582
+ padding: 2px 10px;
2583
+ border-radius: 10px;
2584
+ }
2585
+ .rollout-task-status.queued {
2586
+ background: rgba(224, 175, 104, 0.15);
2587
+ color: var(--warn);
2588
+ }
2589
+ .rollout-task-status.running {
2590
+ background: rgba(122, 162, 247, 0.15);
2591
+ color: var(--accent);
2592
+ }
2593
+ .rollout-task-status.completed {
2594
+ background: rgba(158, 206, 106, 0.15);
2595
+ color: var(--ok);
2596
+ }
2597
+ .rollout-task-status.failed,
2598
+ .rollout-task-status.stopped {
2599
+ background: rgba(247, 118, 142, 0.15);
2600
+ color: var(--err);
2601
+ }
2602
+ .rollout-task-status.cancelled {
2603
+ background: var(--subtle);
2604
+ color: var(--muted);
2605
+ }
2606
+
2607
+ .rollout-task-prompt {
2608
+ font-size: 13px;
2609
+ line-height: 1.5;
2610
+ color: var(--text);
2611
+ margin-bottom: 4px;
2612
+ word-break: break-word;
2613
+ }
2614
+ .rollout-task-command {
2615
+ font-family: var(--mono);
2616
+ font-size: 11px;
2617
+ line-height: 1.4;
2618
+ color: var(--muted);
2619
+ background: var(--subtle);
2620
+ padding: 3px 8px;
2621
+ border-radius: 4px;
2622
+ margin-bottom: 8px;
2623
+ word-break: break-all;
2624
+ white-space: nowrap;
2625
+ overflow: hidden;
2626
+ text-overflow: ellipsis;
2627
+ }
2628
+ .rollout-task-meta {
2629
+ display: flex;
2630
+ gap: 12px;
2631
+ align-items: center;
2632
+ font-size: 11px;
2633
+ color: var(--muted);
2634
+ }
2635
+ .rollout-task-actions {
2636
+ display: flex;
2637
+ gap: 6px;
2638
+ margin-top: 10px;
2639
+ }
2640
+ .rollout-btn-sm {
2641
+ font-size: 12px !important;
2642
+ padding: 4px 10px !important;
2643
+ }
2644
+ .rollout-btn-xs {
2645
+ font-size: 11px !important;
2646
+ padding: 2px 8px !important;
2647
+ }
2648
+
2649
+ /* Tabs */
2650
+ .rollout-tabs {
2651
+ display: flex;
2652
+ gap: 0;
2653
+ align-items: center;
2654
+ padding: 0 20px;
2655
+ border-bottom: 1px solid var(--border);
2656
+ background: var(--panel);
2657
+ }
2658
+ .rollout-tab {
2659
+ background: none;
2660
+ border: none;
2661
+ border-bottom: 2px solid transparent;
2662
+ padding: 10px 18px;
2663
+ font-size: 13px;
2664
+ font-weight: 500;
2665
+ color: var(--muted);
2666
+ cursor: pointer;
2667
+ transition: all 0.15s;
2668
+ }
2669
+ .rollout-tab:hover {
2670
+ color: var(--text);
2671
+ }
2672
+ .rollout-tab.active {
2673
+ color: var(--accent);
2674
+ border-bottom-color: var(--accent);
2675
+ }
2676
+ .rollout-hint {
2677
+ font-size: 12px;
2678
+ color: var(--muted);
2679
+ font-weight: 400;
2680
+ }
2681
+ .rollout-task-card.is-running {
2682
+ border-left: 3px solid var(--accent);
2683
+ }
2684
+
2685
+ /* Detail / Log panel */
2686
+ .rollout-log-backdrop {
2687
+ position: fixed;
2688
+ inset: 0;
2689
+ background: rgba(0, 0, 0, 0.5);
2690
+ z-index: 99;
2691
+ }
2692
+ .rollout-log-panel {
2693
+ position: fixed;
2694
+ right: 0;
2695
+ top: 0;
2696
+ width: 55vw;
2697
+ min-width: 500px;
2698
+ height: 100vh;
2699
+ background: var(--panel);
2700
+ border-left: 1px solid var(--border);
2701
+ display: flex;
2702
+ flex-direction: column;
2703
+ z-index: 100;
2704
+ animation: rollout-slide-in 0.2s ease;
2705
+ }
2706
+ @keyframes rollout-slide-in {
2707
+ from {
2708
+ transform: translateX(100%);
2709
+ }
2710
+ to {
2711
+ transform: translateX(0);
2712
+ }
2713
+ }
2714
+ .rollout-log-header {
2715
+ display: flex;
2716
+ align-items: center;
2717
+ justify-content: space-between;
2718
+ padding: 14px 16px;
2719
+ border-bottom: 1px solid var(--border);
2720
+ }
2721
+ .rollout-log-header h3 {
2722
+ font-size: 14px;
2723
+ margin: 0;
2724
+ white-space: nowrap;
2725
+ overflow: hidden;
2726
+ text-overflow: ellipsis;
2727
+ max-width: 60%;
2728
+ }
2729
+ .rollout-detail-tabs {
2730
+ display: flex;
2731
+ border-bottom: 1px solid var(--border);
2732
+ padding: 0 16px;
2733
+ }
2734
+ .rollout-detail-tab {
2735
+ background: none;
2736
+ border: none;
2737
+ border-bottom: 2px solid transparent;
2738
+ padding: 8px 14px;
2739
+ font-size: 12px;
2740
+ font-weight: 500;
2741
+ color: var(--muted);
2742
+ cursor: pointer;
2743
+ }
2744
+ .rollout-detail-tab:hover {
2745
+ color: var(--text);
2746
+ }
2747
+ .rollout-detail-tab.active {
2748
+ color: var(--accent);
2749
+ border-bottom-color: var(--accent);
2750
+ }
2751
+ .rollout-log-content {
2752
+ flex: 1;
2753
+ overflow-y: auto;
2754
+ padding: 16px;
2755
+ margin: 0;
2756
+ font-family: var(--mono);
2757
+ font-size: 12px;
2758
+ line-height: 1.6;
2759
+ white-space: pre-wrap;
2760
+ color: var(--muted);
2761
+ }
2762
+ .rollout-log-content.loading {
2763
+ opacity: 0.5;
2764
+ }
2765
+ .rollout-live-dot {
2766
+ color: var(--ok);
2767
+ font-size: 11px;
2768
+ font-weight: 600;
2769
+ animation: rollout-blink 1s infinite;
2770
+ }
2771
+ @keyframes rollout-blink {
2772
+ 0%,
2773
+ 100% {
2774
+ opacity: 1;
2775
+ }
2776
+ 50% {
2777
+ opacity: 0.3;
2778
+ }
2779
+ }
2780
+
2781
+ /* Artifacts list */
2782
+ .rollout-artifact-list {
2783
+ flex: 1;
2784
+ overflow-y: auto;
2785
+ padding: 12px 16px;
2786
+ display: flex;
2787
+ flex-direction: column;
2788
+ gap: 4px;
2789
+ }
2790
+ .rollout-artifact-item {
2791
+ display: flex;
2792
+ align-items: center;
2793
+ gap: 8px;
2794
+ padding: 8px 12px;
2795
+ background: var(--subtle);
2796
+ border-radius: var(--radius);
2797
+ color: var(--text);
2798
+ text-decoration: none;
2799
+ font-family: var(--mono);
2800
+ font-size: 12px;
2801
+ transition: background 0.15s;
2802
+ }
2803
+ .rollout-artifact-item:hover {
2804
+ background: var(--border);
2805
+ }
2806
+ .rollout-artifact-icon {
2807
+ font-size: 14px;
2808
+ }
2809
+
2810
+ /* Resolution badge */
2811
+ .rollout-task-resolution {
2812
+ font-size: 10px;
2813
+ padding: 1px 6px;
2814
+ border-radius: 8px;
2815
+ background: rgba(187, 154, 247, 0.15);
2816
+ color: #bb9af7;
2817
+ font-weight: 600;
2818
+ }
2819
+
2820
+ /* Config info */
2821
+ .rollout-config-info {
2822
+ font-size: 12px;
2823
+ line-height: 1.8;
2824
+ color: var(--muted);
2825
+ }
2826
+ .rollout-config-info code {
2827
+ font-family: var(--mono);
2828
+ font-size: 11px;
2829
+ background: var(--subtle);
2830
+ padding: 1px 5px;
2831
+ border-radius: 3px;
2832
+ }
2833
+
2834
+ /* New Task Dialog */
2835
+ .rollout-dialog {
2836
+ position: fixed;
2837
+ top: 50%;
2838
+ left: 50%;
2839
+ transform: translate(-50%, -50%);
2840
+ width: 680px;
2841
+ max-width: 90vw;
2842
+ max-height: 85vh;
2843
+ background: var(--panel);
2844
+ border: 1px solid var(--border);
2845
+ border-radius: 12px;
2846
+ display: flex;
2847
+ flex-direction: column;
2848
+ z-index: 100;
2849
+ animation: rollout-dialog-in 0.2s ease;
2850
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
2851
+ }
2852
+ @keyframes rollout-dialog-in {
2853
+ from {
2854
+ opacity: 0;
2855
+ transform: translate(-50%, -48%);
2856
+ }
2857
+ to {
2858
+ opacity: 1;
2859
+ transform: translate(-50%, -50%);
2860
+ }
2861
+ }
2862
+ .rollout-dialog-header {
2863
+ display: flex;
2864
+ align-items: center;
2865
+ justify-content: space-between;
2866
+ padding: 16px 20px 12px;
2867
+ border-bottom: 1px solid var(--border);
2868
+ }
2869
+ .rollout-dialog-header h3 {
2870
+ font-size: 16px;
2871
+ margin: 0;
2872
+ }
2873
+ .rollout-dialog-body {
2874
+ flex: 1;
2875
+ overflow-y: auto;
2876
+ padding: 16px 20px;
2877
+ display: flex;
2878
+ flex-direction: column;
2879
+ gap: 12px;
2880
+ }
2881
+ .rollout-dialog-footer {
2882
+ display: flex;
2883
+ align-items: center;
2884
+ justify-content: space-between;
2885
+ padding-top: 12px;
2886
+ border-top: 1px solid var(--border);
2887
+ margin-top: 4px;
2888
+ }
2889
+
2890
+ /* Form groups */
2891
+ .rollout-form-group {
2892
+ display: flex;
2893
+ flex-direction: column;
2894
+ gap: 4px;
2895
+ }
2896
+ .rollout-form-row {
2897
+ display: flex;
2898
+ gap: 12px;
2899
+ align-items: flex-end;
2900
+ }
2901
+ .rollout-form-details {
2902
+ border: 1px solid var(--border);
2903
+ border-radius: var(--radius);
2904
+ padding: 8px 12px;
2905
+ }
2906
+ .rollout-form-details[open] {
2907
+ padding-bottom: 4px;
2908
+ }
2909
+
2910
+ /* JSON editor */
2911
+ .rollout-json-editor {
2912
+ font-family: var(--mono) !important;
2913
+ font-size: 13px !important;
2914
+ line-height: 1.5 !important;
2915
+ min-height: 300px;
2916
+ resize: vertical;
2917
+ tab-size: 2;
2918
+ }
2919
+ .rollout-json-error {
2920
+ color: var(--err);
2921
+ font-size: 12px;
2922
+ padding: 4px 0;
2923
+ }