claude-controller 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1942 @@
1
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
2
+
3
+ :root {
4
+ --bg: #0f1117;
5
+ --surface: #1a1d27;
6
+ --surface-hover: #222531;
7
+ --surface-active: #2a2d3a;
8
+ --border: #2e3140;
9
+ --border-light: #3a3d4a;
10
+ --text: #e4e6ed;
11
+ --text-secondary: #8b8fa3;
12
+ --text-muted: #5c5f73;
13
+ --accent: #6c8cff;
14
+ --accent-hover: #8aa4ff;
15
+ --accent-glow: rgba(108, 140, 255, 0.15);
16
+ --green: #34d399;
17
+ --green-dim: rgba(52, 211, 153, 0.15);
18
+ --red: #f87171;
19
+ --red-dim: rgba(248, 113, 113, 0.15);
20
+ --yellow: #fbbf24;
21
+ --yellow-dim: rgba(251, 191, 36, 0.15);
22
+ --blue: #60a5fa;
23
+ --blue-dim: rgba(96, 165, 250, 0.15);
24
+ --radius: 8px;
25
+ --radius-lg: 12px;
26
+ --font: 'Noto Sans KR', system-ui, -apple-system, sans-serif;
27
+ --font-mono: 'JetBrains Mono', 'SF Mono', 'Consolas', monospace;
28
+ --transition: 0.2s ease;
29
+ --shadow: 0 2px 8px rgba(0,0,0,0.3);
30
+ }
31
+
32
+ html { font-size: 14px; }
33
+
34
+ body {
35
+ font-family: var(--font);
36
+ background: var(--bg);
37
+ color: var(--text);
38
+ min-height: 100vh;
39
+ line-height: 1.6;
40
+ -webkit-font-smoothing: antialiased;
41
+ max-width: 100vw;
42
+ overflow-x: hidden;
43
+ }
44
+
45
+ /* ── Scrollbar ── */
46
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
47
+ ::-webkit-scrollbar-track { background: transparent; }
48
+ ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
49
+ ::-webkit-scrollbar-thumb:hover { background: var(--border-light); }
50
+
51
+ /* ── Header ── */
52
+
53
+ /* ── Buttons ── */
54
+ button {
55
+ font-family: var(--font);
56
+ cursor: pointer;
57
+ border: none;
58
+ outline: none;
59
+ transition: all var(--transition);
60
+ }
61
+
62
+ .btn {
63
+ display: inline-flex;
64
+ align-items: center;
65
+ gap: 6px;
66
+ padding: 7px 14px;
67
+ border-radius: var(--radius);
68
+ font-size: 0.82rem;
69
+ font-weight: 500;
70
+ background: var(--surface-hover);
71
+ color: var(--text-secondary);
72
+ border: 1px solid var(--border);
73
+ }
74
+
75
+ .btn:hover {
76
+ background: var(--surface-active);
77
+ color: var(--text);
78
+ border-color: var(--border-light);
79
+ }
80
+
81
+ .btn:active { transform: scale(0.97); }
82
+
83
+ .btn-primary {
84
+ background: var(--accent);
85
+ color: #fff;
86
+ border-color: var(--accent);
87
+ }
88
+
89
+ .btn-primary:hover {
90
+ background: var(--accent-hover);
91
+ border-color: var(--accent-hover);
92
+ box-shadow: 0 0 20px var(--accent-glow);
93
+ }
94
+
95
+ .btn-danger {
96
+ color: var(--red);
97
+ }
98
+
99
+ .btn-danger:hover {
100
+ background: var(--red-dim);
101
+ border-color: var(--red);
102
+ }
103
+
104
+ .btn-success {
105
+ color: var(--green);
106
+ }
107
+
108
+ .btn-success:hover {
109
+ background: var(--green-dim);
110
+ border-color: var(--green);
111
+ }
112
+
113
+ .btn-sm {
114
+ padding: 4px 10px;
115
+ font-size: 0.75rem;
116
+ }
117
+
118
+ .btn-icon {
119
+ padding: 7px;
120
+ display: inline-flex;
121
+ align-items: center;
122
+ justify-content: center;
123
+ }
124
+
125
+ /* ── Context Toolbar ── */
126
+ .ctx-toolbar-wrap {
127
+ position: relative;
128
+ flex-shrink: 0;
129
+ }
130
+
131
+ .ctx-toolbar {
132
+ display: flex;
133
+ align-items: center;
134
+ gap: 2px;
135
+ flex-shrink: 0;
136
+ }
137
+
138
+ .ctx-btn {
139
+ padding: 4px 10px;
140
+ border-radius: var(--radius);
141
+ font-size: 0.72rem;
142
+ font-weight: 600;
143
+ font-family: var(--font-mono);
144
+ background: transparent;
145
+ color: var(--text-muted);
146
+ border: 1px solid transparent;
147
+ letter-spacing: 0.02em;
148
+ text-transform: lowercase;
149
+ }
150
+
151
+ .ctx-btn:hover {
152
+ background: var(--surface-hover);
153
+ color: var(--text-secondary);
154
+ border-color: var(--border);
155
+ }
156
+
157
+ .ctx-btn.active {
158
+ background: var(--accent-glow);
159
+ color: var(--accent);
160
+ border-color: var(--accent);
161
+ }
162
+
163
+ .ctx-btn-x {
164
+ padding: 4px 6px;
165
+ border-radius: var(--radius);
166
+ font-size: 0.78rem;
167
+ font-weight: 500;
168
+ background: transparent;
169
+ color: var(--text-muted);
170
+ border: 1px solid transparent;
171
+ line-height: 1;
172
+ display: inline-flex;
173
+ align-items: center;
174
+ justify-content: center;
175
+ }
176
+
177
+ .ctx-btn-x:hover {
178
+ background: var(--red-dim);
179
+ color: var(--red);
180
+ border-color: var(--red);
181
+ }
182
+
183
+ .ctx-session-label {
184
+ display: none;
185
+ padding: 2px 8px;
186
+ border-radius: 12px;
187
+ font-size: 0.7rem;
188
+ font-family: var(--font-mono);
189
+ background: var(--blue-dim);
190
+ color: var(--blue);
191
+ overflow: hidden;
192
+ text-overflow: ellipsis;
193
+ white-space: nowrap;
194
+ line-height: 1.6;
195
+ min-width: 0;
196
+ }
197
+
198
+ .ctx-session-label.visible {
199
+ display: inline;
200
+ }
201
+
202
+ .session-picker {
203
+ display: none;
204
+ position: absolute;
205
+ top: 100%;
206
+ right: 0;
207
+ margin-top: 4px;
208
+ width: 520px;
209
+ max-width: calc(100vw - 32px);
210
+ max-height: 420px;
211
+ background: var(--surface);
212
+ border: 1px solid var(--border);
213
+ border-radius: var(--radius-lg);
214
+ box-shadow: 0 8px 32px rgba(0,0,0,0.4);
215
+ z-index: 200;
216
+ display: none;
217
+ flex-direction: column;
218
+ }
219
+
220
+ .session-picker.open { display: flex; }
221
+
222
+ .session-picker-header {
223
+ display: flex;
224
+ align-items: center;
225
+ justify-content: space-between;
226
+ padding: 10px 14px;
227
+ border-bottom: 1px solid var(--border);
228
+ flex-shrink: 0;
229
+ }
230
+
231
+ .session-picker-title {
232
+ font-size: 0.78rem;
233
+ font-weight: 600;
234
+ color: var(--text-secondary);
235
+ }
236
+
237
+ .session-picker-search {
238
+ padding: 8px 14px;
239
+ border-bottom: 1px solid var(--border);
240
+ flex-shrink: 0;
241
+ }
242
+
243
+ .session-picker-search input {
244
+ width: 100%;
245
+ padding: 6px 10px;
246
+ border: 1px solid var(--border);
247
+ border-radius: var(--radius);
248
+ background: var(--bg);
249
+ color: var(--text);
250
+ font-size: 0.78rem;
251
+ font-family: var(--font);
252
+ outline: none;
253
+ transition: border-color var(--transition);
254
+ }
255
+
256
+ .session-picker-search input:focus {
257
+ border-color: var(--accent);
258
+ }
259
+
260
+ .session-picker-search input::placeholder {
261
+ color: var(--text-muted);
262
+ }
263
+
264
+ .session-picker-list {
265
+ overflow-y: auto;
266
+ flex: 1;
267
+ }
268
+
269
+ .session-item {
270
+ display: flex;
271
+ flex-direction: column;
272
+ gap: 4px;
273
+ padding: 10px 14px;
274
+ cursor: pointer;
275
+ border-bottom: 1px solid var(--border);
276
+ transition: background var(--transition);
277
+ }
278
+
279
+ .session-item:hover { background: var(--surface-hover); }
280
+ .session-item:last-child { border-bottom: none; }
281
+
282
+ .session-item-row {
283
+ display: flex;
284
+ align-items: center;
285
+ gap: 8px;
286
+ }
287
+
288
+ .session-item-status {
289
+ display: inline-block;
290
+ width: 7px;
291
+ height: 7px;
292
+ border-radius: 50%;
293
+ flex-shrink: 0;
294
+ }
295
+ .session-item-status.done { background: var(--green); }
296
+ .session-item-status.failed { background: var(--red); }
297
+ .session-item-status.running { background: var(--yellow); animation: pulse 1.5s infinite; }
298
+ .session-item-status.unknown { background: var(--text-muted); }
299
+
300
+ @keyframes pulse {
301
+ 0%, 100% { opacity: 1; }
302
+ 50% { opacity: 0.4; }
303
+ }
304
+
305
+ .session-item-id {
306
+ font-family: var(--font-mono);
307
+ font-size: 0.7rem;
308
+ color: var(--accent);
309
+ flex-shrink: 0;
310
+ }
311
+
312
+ .session-item-slug {
313
+ font-size: 0.7rem;
314
+ color: var(--text-muted);
315
+ flex-shrink: 0;
316
+ font-style: italic;
317
+ }
318
+
319
+ .session-item-job {
320
+ font-family: var(--font-mono);
321
+ font-size: 0.65rem;
322
+ color: var(--text-muted);
323
+ flex-shrink: 0;
324
+ }
325
+
326
+ .session-item-prompt {
327
+ font-size: 0.78rem;
328
+ color: var(--text);
329
+ flex: 1;
330
+ overflow: hidden;
331
+ text-overflow: ellipsis;
332
+ white-space: nowrap;
333
+ }
334
+
335
+ .session-item-meta {
336
+ display: flex;
337
+ align-items: center;
338
+ gap: 12px;
339
+ padding-left: 15px;
340
+ }
341
+
342
+ .session-item-time {
343
+ font-size: 0.68rem;
344
+ color: var(--text-muted);
345
+ flex-shrink: 0;
346
+ }
347
+
348
+ .session-item-cwd {
349
+ font-size: 0.65rem;
350
+ color: var(--text-muted);
351
+ font-family: var(--font-mono);
352
+ overflow: hidden;
353
+ text-overflow: ellipsis;
354
+ white-space: nowrap;
355
+ }
356
+
357
+ .session-item-cost {
358
+ font-size: 0.65rem;
359
+ color: var(--green);
360
+ font-family: var(--font-mono);
361
+ flex-shrink: 0;
362
+ }
363
+
364
+ .session-filter-bar {
365
+ display: flex;
366
+ align-items: center;
367
+ gap: 6px;
368
+ padding: 6px 14px;
369
+ border-bottom: 1px solid var(--border);
370
+ flex-shrink: 0;
371
+ }
372
+
373
+ .session-filter-toggle {
374
+ display: inline-flex;
375
+ align-items: center;
376
+ gap: 4px;
377
+ padding: 3px 8px;
378
+ border: 1px solid var(--border);
379
+ border-radius: 4px;
380
+ background: transparent;
381
+ color: var(--text-muted);
382
+ font-size: 0.68rem;
383
+ font-family: var(--font);
384
+ cursor: pointer;
385
+ transition: all var(--transition);
386
+ white-space: nowrap;
387
+ }
388
+
389
+ .session-filter-toggle:hover { border-color: var(--accent); color: var(--text-secondary); }
390
+ .session-filter-toggle.active { background: var(--accent-glow); border-color: var(--accent); color: var(--accent); }
391
+
392
+ .session-filter-project {
393
+ font-size: 0.68rem;
394
+ color: var(--text-muted);
395
+ overflow: hidden;
396
+ text-overflow: ellipsis;
397
+ white-space: nowrap;
398
+ flex: 1;
399
+ }
400
+
401
+ .session-group-header {
402
+ display: flex;
403
+ align-items: center;
404
+ gap: 6px;
405
+ padding: 6px 14px;
406
+ background: var(--bg);
407
+ font-size: 0.68rem;
408
+ font-weight: 600;
409
+ color: var(--text-secondary);
410
+ border-bottom: 1px solid var(--border);
411
+ position: sticky;
412
+ top: 0;
413
+ z-index: 1;
414
+ }
415
+
416
+ .session-group-header svg {
417
+ width: 12px;
418
+ height: 12px;
419
+ flex-shrink: 0;
420
+ opacity: 0.6;
421
+ }
422
+
423
+ .session-group-count {
424
+ font-weight: 400;
425
+ color: var(--text-muted);
426
+ margin-left: auto;
427
+ }
428
+
429
+ .session-empty {
430
+ padding: 24px 14px;
431
+ text-align: center;
432
+ font-size: 0.78rem;
433
+ color: var(--text-muted);
434
+ }
435
+
436
+ .session-empty-icon {
437
+ font-size: 1.5rem;
438
+ margin-bottom: 8px;
439
+ opacity: 0.5;
440
+ }
441
+
442
+ /* ── Layout ── */
443
+ .layout {
444
+ min-height: 100vh;
445
+ width: 100%;
446
+ max-width: 100vw;
447
+ }
448
+
449
+ .main {
450
+ flex: 1;
451
+ padding: 8px 0;
452
+ overflow-x: hidden;
453
+ width: 100%;
454
+ max-width: 100vw;
455
+ }
456
+
457
+ /* ── CWD badge ── */
458
+ .cwd-badge {
459
+ display: inline-flex;
460
+ align-items: center;
461
+ gap: 4px;
462
+ padding: 2px 8px;
463
+ border-radius: 12px;
464
+ font-size: 0.7rem;
465
+ font-weight: 500;
466
+ background: var(--accent-glow);
467
+ color: var(--accent);
468
+ margin-left: 8px;
469
+ max-width: 180px;
470
+ overflow: hidden;
471
+ text-overflow: ellipsis;
472
+ white-space: nowrap;
473
+ vertical-align: middle;
474
+ }
475
+
476
+ .cwd-badge:empty { display: none; }
477
+
478
+ /* ── Directory Picker ── */
479
+ .dir-picker {
480
+ display: flex;
481
+ align-items: center;
482
+ gap: 8px;
483
+ }
484
+
485
+ .dir-picker-display {
486
+ flex: 1;
487
+ display: flex;
488
+ align-items: center;
489
+ gap: 8px;
490
+ padding: 8px 12px;
491
+ border-radius: var(--radius);
492
+ background: var(--bg);
493
+ border: 1px solid var(--border);
494
+ color: var(--text-muted);
495
+ font-size: 0.85rem;
496
+ font-family: var(--font-mono);
497
+ min-height: 38px;
498
+ overflow: hidden;
499
+ text-overflow: ellipsis;
500
+ white-space: nowrap;
501
+ cursor: pointer;
502
+ transition: all var(--transition);
503
+ }
504
+
505
+ .dir-picker-display:hover {
506
+ border-color: var(--border-light);
507
+ background: var(--surface);
508
+ }
509
+
510
+ .dir-picker-display.has-value {
511
+ color: var(--text);
512
+ }
513
+
514
+ .dir-picker-display .dir-icon {
515
+ flex-shrink: 0;
516
+ color: var(--text-muted);
517
+ }
518
+
519
+ .dir-picker-clear {
520
+ flex-shrink: 0;
521
+ padding: 4px;
522
+ border-radius: 4px;
523
+ background: transparent;
524
+ color: var(--text-muted);
525
+ border: none;
526
+ cursor: pointer;
527
+ display: none;
528
+ }
529
+
530
+ .dir-picker-clear:hover {
531
+ background: var(--red-dim);
532
+ color: var(--red);
533
+ }
534
+
535
+ .dir-picker-clear.visible { display: inline-flex; }
536
+
537
+ /* ── Recent Directory Chips ── */
538
+ .recent-dirs {
539
+ display: flex;
540
+ align-items: center;
541
+ gap: 6px;
542
+ flex-wrap: wrap;
543
+ margin-bottom: 10px;
544
+ }
545
+
546
+ .recent-dirs:empty { display: none; }
547
+
548
+ .recent-dirs-label {
549
+ font-size: 0.72rem;
550
+ color: var(--text-muted);
551
+ font-weight: 500;
552
+ flex-shrink: 0;
553
+ margin-right: 2px;
554
+ }
555
+
556
+ .recent-chip {
557
+ display: inline-flex;
558
+ align-items: center;
559
+ gap: 4px;
560
+ padding: 3px 10px;
561
+ border-radius: 14px;
562
+ background: var(--surface);
563
+ border: 1px solid var(--border);
564
+ color: var(--text-secondary);
565
+ font-size: 0.75rem;
566
+ font-family: var(--font-mono);
567
+ cursor: pointer;
568
+ transition: all var(--transition);
569
+ max-width: 200px;
570
+ }
571
+
572
+ .recent-chip:hover {
573
+ border-color: var(--accent);
574
+ color: var(--accent);
575
+ background: var(--accent-glow);
576
+ }
577
+
578
+ .recent-chip.active {
579
+ border-color: var(--accent);
580
+ color: var(--accent);
581
+ background: var(--accent-glow);
582
+ font-weight: 500;
583
+ }
584
+
585
+ .recent-chip-name {
586
+ overflow: hidden;
587
+ text-overflow: ellipsis;
588
+ white-space: nowrap;
589
+ }
590
+
591
+ .recent-chip-remove {
592
+ flex-shrink: 0;
593
+ width: 14px;
594
+ height: 14px;
595
+ padding: 0;
596
+ margin-left: 2px;
597
+ border: none;
598
+ background: transparent;
599
+ color: var(--text-muted);
600
+ cursor: pointer;
601
+ border-radius: 50%;
602
+ display: inline-flex;
603
+ align-items: center;
604
+ justify-content: center;
605
+ transition: all var(--transition);
606
+ }
607
+
608
+ .recent-chip-remove:hover {
609
+ background: var(--red-dim);
610
+ color: var(--red);
611
+ }
612
+
613
+ /* ── Inline Directory Browser Panel ── */
614
+ .dir-browser-panel {
615
+ display: none;
616
+ border: 1px solid var(--border);
617
+ border-radius: var(--radius);
618
+ background: var(--surface);
619
+ margin-top: 8px;
620
+ overflow: hidden;
621
+ animation: panel-slide 0.15s ease-out;
622
+ }
623
+
624
+ .dir-browser-panel.open { display: block; }
625
+
626
+ @keyframes panel-slide {
627
+ from { opacity: 0; transform: translateY(-4px); }
628
+ to { opacity: 1; transform: translateY(0); }
629
+ }
630
+
631
+ .dir-modal-header {
632
+ display: flex;
633
+ align-items: center;
634
+ justify-content: space-between;
635
+ padding: 10px 12px;
636
+ border-bottom: 1px solid var(--border);
637
+ }
638
+
639
+ .dir-modal-title {
640
+ font-size: 0.82rem;
641
+ font-weight: 600;
642
+ color: var(--text);
643
+ }
644
+
645
+ .dir-modal-close {
646
+ padding: 4px;
647
+ border-radius: 4px;
648
+ background: transparent;
649
+ color: var(--text-muted);
650
+ border: none;
651
+ cursor: pointer;
652
+ }
653
+
654
+ .dir-modal-close:hover { background: var(--surface-active); color: var(--text); }
655
+
656
+ .dir-modal-path {
657
+ display: flex;
658
+ align-items: center;
659
+ gap: 4px;
660
+ padding: 8px 12px;
661
+ background: var(--bg);
662
+ border-bottom: 1px solid var(--border);
663
+ font-family: var(--font-mono);
664
+ font-size: 0.75rem;
665
+ color: var(--text-secondary);
666
+ overflow-x: auto;
667
+ white-space: nowrap;
668
+ }
669
+
670
+ .dir-modal-path .breadcrumb-seg {
671
+ padding: 2px 6px;
672
+ border-radius: 4px;
673
+ cursor: pointer;
674
+ color: var(--accent);
675
+ transition: background var(--transition);
676
+ }
677
+
678
+ .dir-modal-path .breadcrumb-seg:hover {
679
+ background: var(--accent-glow);
680
+ }
681
+
682
+ .dir-modal-path .breadcrumb-sep {
683
+ color: var(--text-muted);
684
+ }
685
+
686
+ .dir-modal-list {
687
+ flex: 1;
688
+ overflow-y: auto;
689
+ padding: 4px 0;
690
+ max-height: 240px;
691
+ }
692
+
693
+ .dir-item {
694
+ display: flex;
695
+ align-items: center;
696
+ gap: 10px;
697
+ padding: 8px 16px;
698
+ cursor: pointer;
699
+ font-size: 0.85rem;
700
+ color: var(--text);
701
+ transition: background var(--transition);
702
+ }
703
+
704
+ .dir-item:hover { background: var(--surface-hover); }
705
+
706
+ .dir-item-icon {
707
+ flex-shrink: 0;
708
+ width: 18px;
709
+ height: 18px;
710
+ color: var(--text-muted);
711
+ }
712
+
713
+ .dir-item-icon.is-dir { color: var(--yellow); }
714
+ .dir-item-icon.is-parent { color: var(--accent); }
715
+
716
+ .dir-item-name {
717
+ flex: 1;
718
+ overflow: hidden;
719
+ text-overflow: ellipsis;
720
+ white-space: nowrap;
721
+ }
722
+
723
+ .dir-item-name.is-dir { font-weight: 500; }
724
+
725
+ .dir-modal-footer {
726
+ display: flex;
727
+ align-items: center;
728
+ justify-content: space-between;
729
+ padding: 10px 12px;
730
+ border-top: 1px solid var(--border);
731
+ gap: 8px;
732
+ }
733
+
734
+ .dir-modal-current {
735
+ flex: 1;
736
+ font-family: var(--font-mono);
737
+ font-size: 0.78rem;
738
+ color: var(--text-secondary);
739
+ overflow: hidden;
740
+ text-overflow: ellipsis;
741
+ white-space: nowrap;
742
+ }
743
+
744
+ .dir-modal-loading {
745
+ display: flex;
746
+ align-items: center;
747
+ justify-content: center;
748
+ padding: 32px;
749
+ color: var(--text-muted);
750
+ font-size: 0.85rem;
751
+ gap: 8px;
752
+ }
753
+
754
+ /* ── Cards / Sections ── */
755
+ .section {
756
+ margin-bottom: 24px;
757
+ animation: fadeIn 0.3s ease forwards;
758
+ animation-iteration-count: 1;
759
+ }
760
+
761
+ @keyframes fadeIn {
762
+ from { opacity: 0; transform: translateY(8px); }
763
+ to { opacity: 1; transform: translateY(0); }
764
+ }
765
+
766
+ .card {
767
+ background: var(--surface);
768
+ border: 1px solid var(--border);
769
+ border-left: none;
770
+ border-right: none;
771
+ border-radius: 0;
772
+ overflow: visible;
773
+ }
774
+
775
+ .card-header {
776
+ display: flex;
777
+ align-items: center;
778
+ justify-content: space-between;
779
+ padding: 14px 18px;
780
+ border-bottom: 1px solid var(--border);
781
+ gap: 8px;
782
+ flex-wrap: wrap;
783
+ }
784
+
785
+ .card-title {
786
+ font-size: 0.92rem;
787
+ font-weight: 600;
788
+ color: var(--text);
789
+ display: flex;
790
+ align-items: center;
791
+ gap: 8px;
792
+ min-width: 0;
793
+ flex: 1 1 0;
794
+ }
795
+
796
+ .card-title svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--accent); }
797
+
798
+ .card-header-actions {
799
+ display: flex;
800
+ align-items: center;
801
+ gap: 8px;
802
+ flex-shrink: 0;
803
+ }
804
+
805
+ .card-body { padding: 18px; }
806
+
807
+ /* ── Send Task Form ── */
808
+ .form-group { margin-bottom: 14px; }
809
+
810
+ .form-label {
811
+ display: flex;
812
+ align-items: center;
813
+ font-size: 0.78rem;
814
+ font-weight: 500;
815
+ color: var(--text-secondary);
816
+ margin-bottom: 6px;
817
+ }
818
+
819
+ textarea, input[type="text"] {
820
+ width: 100%;
821
+ padding: 10px 14px;
822
+ background: var(--bg);
823
+ border: 1px solid var(--border);
824
+ border-radius: var(--radius);
825
+ color: var(--text);
826
+ font-family: var(--font);
827
+ font-size: 0.85rem;
828
+ line-height: 1.6;
829
+ resize: vertical;
830
+ transition: border-color var(--transition);
831
+ }
832
+
833
+ textarea:focus, input[type="text"]:focus {
834
+ outline: none;
835
+ border-color: var(--accent);
836
+ box-shadow: 0 0 0 3px var(--accent-glow);
837
+ }
838
+
839
+ textarea { min-height: unset; position: relative; }
840
+
841
+ /* ── Prompt Input + Mirror (color-only highlight, no text replacement) ── */
842
+ #promptInput {
843
+ color: transparent;
844
+ caret-color: var(--text);
845
+ padding-right: 44px;
846
+ }
847
+
848
+ #promptInput::selection {
849
+ background: rgba(108, 140, 255, 0.3);
850
+ color: transparent;
851
+ }
852
+
853
+ .prompt-mirror {
854
+ position: absolute;
855
+ top: 0;
856
+ left: 0;
857
+ right: 0;
858
+ bottom: 0;
859
+ padding: 10px 14px;
860
+ padding-right: 44px;
861
+ font-family: var(--font);
862
+ font-size: 0.85rem;
863
+ line-height: 1.6;
864
+ color: var(--text);
865
+ white-space: pre-wrap;
866
+ word-wrap: break-word;
867
+ overflow: hidden;
868
+ pointer-events: none;
869
+ }
870
+
871
+ .prompt-at-ref {
872
+ color: var(--green);
873
+ font-weight: 500;
874
+ }
875
+
876
+ /* ── Image Attachments ── */
877
+ .prompt-wrapper {
878
+ position: relative;
879
+ }
880
+
881
+ .prompt-wrapper.drag-over textarea {
882
+ border-color: var(--accent);
883
+ box-shadow: 0 0 0 3px var(--accent-glow);
884
+ }
885
+
886
+ .drop-overlay {
887
+ display: none;
888
+ position: absolute;
889
+ inset: 0;
890
+ background: rgba(108, 140, 255, 0.08);
891
+ border: 2px dashed var(--accent);
892
+ border-radius: var(--radius);
893
+ z-index: 10;
894
+ pointer-events: none;
895
+ align-items: center;
896
+ justify-content: center;
897
+ font-size: 0.85rem;
898
+ font-weight: 600;
899
+ color: var(--accent);
900
+ gap: 8px;
901
+ }
902
+
903
+ .prompt-wrapper.drag-over .drop-overlay {
904
+ display: flex;
905
+ }
906
+
907
+ .image-previews {
908
+ display: flex;
909
+ flex-wrap: wrap;
910
+ gap: 8px;
911
+ margin-top: 8px;
912
+ }
913
+
914
+ .image-previews:empty { display: none; }
915
+
916
+ .img-thumb {
917
+ position: relative;
918
+ width: 72px;
919
+ height: 72px;
920
+ border-radius: 6px;
921
+ border: 1px solid var(--border);
922
+ overflow: hidden;
923
+ background: var(--bg);
924
+ flex-shrink: 0;
925
+ animation: fadeIn 0.2s ease;
926
+ }
927
+
928
+ .img-thumb img {
929
+ width: 100%;
930
+ height: 100%;
931
+ object-fit: cover;
932
+ cursor: pointer;
933
+ }
934
+
935
+ .img-thumb .img-remove {
936
+ position: absolute;
937
+ top: 2px;
938
+ right: 2px;
939
+ width: 18px;
940
+ height: 18px;
941
+ border-radius: 50%;
942
+ background: rgba(0,0,0,0.7);
943
+ color: #fff;
944
+ font-size: 11px;
945
+ display: flex;
946
+ align-items: center;
947
+ justify-content: center;
948
+ cursor: pointer;
949
+ opacity: 0;
950
+ transition: opacity 0.15s;
951
+ border: none;
952
+ padding: 0;
953
+ line-height: 1;
954
+ }
955
+
956
+ .img-thumb:hover .img-remove {
957
+ opacity: 1;
958
+ }
959
+
960
+ .img-thumb.uploading {
961
+ opacity: 0.5;
962
+ }
963
+
964
+ .img-thumb.uploading::after {
965
+ content: '';
966
+ position: absolute;
967
+ inset: 0;
968
+ display: flex;
969
+ align-items: center;
970
+ justify-content: center;
971
+ background: rgba(0,0,0,0.3);
972
+ }
973
+
974
+ .img-count-badge {
975
+ display: inline-flex;
976
+ align-items: center;
977
+ gap: 4px;
978
+ padding: 2px 8px;
979
+ border-radius: 12px;
980
+ font-size: 0.7rem;
981
+ font-weight: 600;
982
+ background: var(--accent-glow);
983
+ color: var(--accent);
984
+ margin-left: 8px;
985
+ }
986
+
987
+ .img-count-badge:empty { display: none; }
988
+
989
+ /* ── File Attachments (non-image) ── */
990
+ .file-thumb {
991
+ position: relative;
992
+ display: inline-flex;
993
+ align-items: center;
994
+ gap: 6px;
995
+ padding: 6px 10px 6px 8px;
996
+ border-radius: 6px;
997
+ border: 1px solid var(--border);
998
+ background: var(--surface);
999
+ max-width: 200px;
1000
+ animation: fadeIn 0.2s ease;
1001
+ flex-shrink: 0;
1002
+ }
1003
+ .file-thumb .file-icon {
1004
+ width: 28px;
1005
+ height: 28px;
1006
+ display: flex;
1007
+ align-items: center;
1008
+ justify-content: center;
1009
+ border-radius: 4px;
1010
+ background: var(--surface-active);
1011
+ color: var(--text-muted);
1012
+ flex-shrink: 0;
1013
+ font-size: 0.6rem;
1014
+ font-weight: 700;
1015
+ font-family: var(--font-mono);
1016
+ text-transform: uppercase;
1017
+ letter-spacing: -0.02em;
1018
+ }
1019
+ .file-thumb .file-info {
1020
+ display: flex;
1021
+ flex-direction: column;
1022
+ gap: 1px;
1023
+ overflow: hidden;
1024
+ min-width: 0;
1025
+ }
1026
+ .file-thumb .file-name {
1027
+ font-size: 0.75rem;
1028
+ font-weight: 500;
1029
+ color: var(--text);
1030
+ white-space: nowrap;
1031
+ overflow: hidden;
1032
+ text-overflow: ellipsis;
1033
+ }
1034
+ .file-thumb .file-size {
1035
+ font-size: 0.65rem;
1036
+ color: var(--text-muted);
1037
+ }
1038
+ .file-thumb .file-remove {
1039
+ position: absolute;
1040
+ top: -4px;
1041
+ right: -4px;
1042
+ width: 16px;
1043
+ height: 16px;
1044
+ border-radius: 50%;
1045
+ background: rgba(0,0,0,0.7);
1046
+ color: #fff;
1047
+ font-size: 10px;
1048
+ display: flex;
1049
+ align-items: center;
1050
+ justify-content: center;
1051
+ cursor: pointer;
1052
+ opacity: 0;
1053
+ transition: opacity 0.15s;
1054
+ border: none;
1055
+ padding: 0;
1056
+ line-height: 1;
1057
+ }
1058
+ .file-thumb:hover .file-remove { opacity: 1; }
1059
+ .file-thumb.uploading { opacity: 0.5; }
1060
+
1061
+ /* ── Attach Button (inside prompt-wrapper) ── */
1062
+ .attach-float-btn {
1063
+ position: absolute;
1064
+ bottom: 12px;
1065
+ right: 10px;
1066
+ width: 28px;
1067
+ height: 28px;
1068
+ border-radius: 6px;
1069
+ background: var(--surface-hover);
1070
+ border: 1px solid var(--border);
1071
+ color: var(--text-muted);
1072
+ display: flex;
1073
+ align-items: center;
1074
+ justify-content: center;
1075
+ cursor: pointer;
1076
+ transition: all var(--transition);
1077
+ z-index: 5;
1078
+ }
1079
+ .attach-float-btn:hover {
1080
+ background: var(--surface-active);
1081
+ color: var(--accent);
1082
+ border-color: var(--accent);
1083
+ }
1084
+
1085
+ textarea::placeholder, input::placeholder {
1086
+ color: var(--text-muted);
1087
+ }
1088
+
1089
+ .form-actions {
1090
+ display: flex;
1091
+ justify-content: flex-end;
1092
+ gap: 8px;
1093
+ }
1094
+
1095
+ /* ── Job Table ── */
1096
+ .table-wrap { overflow-x: hidden; }
1097
+
1098
+ table {
1099
+ width: 100%;
1100
+ border-collapse: collapse;
1101
+ font-size: 0.82rem;
1102
+ table-layout: fixed;
1103
+ }
1104
+
1105
+ th {
1106
+ text-align: left;
1107
+ padding: 10px 14px;
1108
+ font-weight: 600;
1109
+ font-size: 0.72rem;
1110
+ text-transform: uppercase;
1111
+ letter-spacing: 0.06em;
1112
+ color: var(--text-muted);
1113
+ background: var(--bg);
1114
+ border-bottom: 1px solid var(--border);
1115
+ white-space: nowrap;
1116
+ }
1117
+
1118
+ td {
1119
+ padding: 10px 14px;
1120
+ border-bottom: 1px solid var(--border);
1121
+ color: var(--text-secondary);
1122
+ vertical-align: top;
1123
+ overflow: hidden;
1124
+ text-overflow: ellipsis;
1125
+ white-space: nowrap;
1126
+ }
1127
+
1128
+ tr:hover td { background: var(--surface-hover); }
1129
+ tr { cursor: pointer; transition: background var(--transition); }
1130
+ thead tr { cursor: default; }
1131
+
1132
+ .badge {
1133
+ display: inline-flex;
1134
+ align-items: center;
1135
+ gap: 5px;
1136
+ padding: 3px 9px;
1137
+ border-radius: 20px;
1138
+ font-size: 0.72rem;
1139
+ font-weight: 600;
1140
+ white-space: nowrap;
1141
+ }
1142
+
1143
+ .badge-running {
1144
+ background: var(--blue-dim);
1145
+ color: var(--blue);
1146
+ }
1147
+
1148
+ .badge-running::before {
1149
+ content: '';
1150
+ width: 6px; height: 6px;
1151
+ border-radius: 50%;
1152
+ background: var(--blue);
1153
+ animation: pulse 1.5s ease-in-out infinite;
1154
+ }
1155
+
1156
+ .badge-done {
1157
+ background: var(--green-dim);
1158
+ color: var(--green);
1159
+ }
1160
+
1161
+ .badge-failed {
1162
+ background: var(--red-dim);
1163
+ color: var(--red);
1164
+ }
1165
+
1166
+ .badge-pending {
1167
+ background: var(--yellow-dim);
1168
+ color: var(--yellow);
1169
+ }
1170
+
1171
+ .prompt-cell {
1172
+ overflow: hidden;
1173
+ text-overflow: ellipsis;
1174
+ white-space: nowrap;
1175
+ }
1176
+
1177
+ .job-id {
1178
+ font-family: var(--font-mono);
1179
+ font-size: 0.78rem;
1180
+ color: var(--accent);
1181
+ }
1182
+
1183
+ .job-cwd {
1184
+ font-family: var(--font-mono);
1185
+ font-size: 0.75rem;
1186
+ color: var(--text-muted);
1187
+ max-width: 100%;
1188
+ overflow: hidden;
1189
+ text-overflow: ellipsis;
1190
+ white-space: nowrap;
1191
+ }
1192
+
1193
+ .job-session {
1194
+ font-family: var(--font-mono);
1195
+ font-size: 0.78rem;
1196
+ color: var(--text-muted);
1197
+ }
1198
+ .job-session.clickable {
1199
+ color: var(--accent);
1200
+ cursor: pointer;
1201
+ border-radius: 3px;
1202
+ transition: background var(--transition);
1203
+ }
1204
+ .job-session.clickable:hover {
1205
+ text-decoration: underline;
1206
+ background: var(--accent-glow);
1207
+ }
1208
+
1209
+ .job-time {
1210
+ font-size: 0.75rem;
1211
+ color: var(--text-muted);
1212
+ white-space: nowrap;
1213
+ }
1214
+
1215
+ .expand-row td {
1216
+ padding: 0;
1217
+ border-bottom: 1px solid var(--border);
1218
+ }
1219
+
1220
+ .expand-content {
1221
+ padding: 14px 18px;
1222
+ background: var(--bg);
1223
+ font-family: var(--font-mono);
1224
+ font-size: 0.78rem;
1225
+ line-height: 1.7;
1226
+ color: var(--text-secondary);
1227
+ white-space: pre-wrap;
1228
+ word-break: break-word;
1229
+ max-height: 300px;
1230
+ overflow-y: auto;
1231
+ animation: slideDown 0.2s ease;
1232
+ }
1233
+
1234
+ @keyframes slideDown {
1235
+ from { opacity: 0; max-height: 0; }
1236
+ to { opacity: 1; max-height: 300px; }
1237
+ }
1238
+
1239
+ .empty-state {
1240
+ text-align: center;
1241
+ padding: 40px 20px;
1242
+ color: var(--text-muted);
1243
+ font-size: 0.85rem;
1244
+ }
1245
+
1246
+ .empty-state svg {
1247
+ width: 40px;
1248
+ height: 40px;
1249
+ margin-bottom: 12px;
1250
+ opacity: 0.3;
1251
+ }
1252
+
1253
+ /* ── Stream Panel ── */
1254
+ .stream-panel {
1255
+ background: var(--bg);
1256
+ border-top: 1px solid var(--border);
1257
+ animation: streamSlideDown 0.25s ease;
1258
+ }
1259
+
1260
+ @keyframes streamSlideDown {
1261
+ from { opacity: 0; max-height: 0; }
1262
+ to { opacity: 1; max-height: 600px; }
1263
+ }
1264
+
1265
+
1266
+ .stream-spinner {
1267
+ display: inline-block;
1268
+ width: 12px;
1269
+ height: 12px;
1270
+ border: 2px solid rgba(96, 165, 250, 0.25);
1271
+ border-top-color: var(--blue);
1272
+ border-radius: 50%;
1273
+ animation: spin 0.8s linear infinite;
1274
+ }
1275
+
1276
+ .stream-pulse {
1277
+ display: inline-flex;
1278
+ align-items: center;
1279
+ gap: 4px;
1280
+ font-size: 0.7rem;
1281
+ color: var(--blue);
1282
+ font-weight: 500;
1283
+ }
1284
+
1285
+ .stream-pulse-dot {
1286
+ width: 6px;
1287
+ height: 6px;
1288
+ border-radius: 50%;
1289
+ background: var(--blue);
1290
+ animation: streamPulse 1.5s ease-in-out infinite;
1291
+ }
1292
+
1293
+ @keyframes streamPulse {
1294
+ 0%, 100% { opacity: 1; transform: scale(1); }
1295
+ 50% { opacity: 0.3; transform: scale(0.7); }
1296
+ }
1297
+
1298
+ .stream-content {
1299
+ max-height: 400px;
1300
+ overflow-y: auto;
1301
+ padding: 14px 18px;
1302
+ background: #080a0e;
1303
+ font-family: var(--font-mono);
1304
+ font-size: 0.78rem;
1305
+ line-height: 1.7;
1306
+ scroll-behavior: smooth;
1307
+ }
1308
+
1309
+ .stream-content::-webkit-scrollbar-thumb { background: var(--border-light); }
1310
+
1311
+ .stream-event {
1312
+ padding: 3px 0;
1313
+ word-break: break-word;
1314
+ }
1315
+
1316
+ .stream-event + .stream-event {
1317
+ margin-top: 2px;
1318
+ }
1319
+
1320
+ .stream-event-text {
1321
+ color: #e4e6ed;
1322
+ white-space: pre-wrap;
1323
+ }
1324
+
1325
+ .stream-event-tool {
1326
+ color: var(--yellow);
1327
+ display: flex;
1328
+ align-items: flex-start;
1329
+ gap: 8px;
1330
+ padding: 4px 0;
1331
+ }
1332
+
1333
+ .stream-tool-badge {
1334
+ display: inline-flex;
1335
+ align-items: center;
1336
+ gap: 4px;
1337
+ padding: 2px 8px;
1338
+ border-radius: 4px;
1339
+ background: var(--yellow-dim);
1340
+ color: var(--yellow);
1341
+ font-size: 0.7rem;
1342
+ font-weight: 600;
1343
+ white-space: nowrap;
1344
+ flex-shrink: 0;
1345
+ }
1346
+
1347
+ .stream-tool-badge::before {
1348
+ content: '>';
1349
+ opacity: 0.5;
1350
+ }
1351
+
1352
+ .stream-tool-input {
1353
+ color: #d4d4d4;
1354
+ white-space: pre-wrap;
1355
+ flex: 1;
1356
+ min-width: 0;
1357
+ }
1358
+
1359
+ .stream-event-result {
1360
+ color: var(--green);
1361
+ padding: 6px 0;
1362
+ display: flex;
1363
+ align-items: flex-start;
1364
+ gap: 8px;
1365
+ }
1366
+
1367
+ .stream-result-icon {
1368
+ color: var(--green);
1369
+ flex-shrink: 0;
1370
+ font-weight: 700;
1371
+ }
1372
+
1373
+ .stream-result-text {
1374
+ white-space: pre-wrap;
1375
+ flex: 1;
1376
+ min-width: 0;
1377
+ }
1378
+
1379
+ .stream-event-error {
1380
+ color: var(--red);
1381
+ padding: 4px 0;
1382
+ display: flex;
1383
+ align-items: flex-start;
1384
+ gap: 8px;
1385
+ }
1386
+
1387
+ .stream-error-icon {
1388
+ color: var(--red);
1389
+ flex-shrink: 0;
1390
+ font-weight: 700;
1391
+ }
1392
+
1393
+ .stream-error-text {
1394
+ white-space: pre-wrap;
1395
+ flex: 1;
1396
+ min-width: 0;
1397
+ }
1398
+
1399
+ .stream-empty {
1400
+ color: var(--text-muted);
1401
+ text-align: center;
1402
+ padding: 24px;
1403
+ font-size: 0.8rem;
1404
+ }
1405
+
1406
+ .stream-done-banner {
1407
+ display: flex;
1408
+ align-items: center;
1409
+ justify-content: center;
1410
+ gap: 8px;
1411
+ padding: 8px 18px;
1412
+ background: var(--green-dim);
1413
+ color: var(--green);
1414
+ font-size: 0.75rem;
1415
+ font-weight: 600;
1416
+ border-top: 1px solid rgba(52, 211, 153, 0.2);
1417
+ }
1418
+
1419
+ .stream-done-banner.failed {
1420
+ background: var(--red-dim);
1421
+ color: var(--red);
1422
+ border-top-color: rgba(248, 113, 113, 0.2);
1423
+ }
1424
+
1425
+ /* ── Stream Action Buttons ── */
1426
+ .stream-actions {
1427
+ display: flex;
1428
+ align-items: center;
1429
+ gap: 6px;
1430
+ padding: 8px 18px;
1431
+ border-top: 1px solid var(--border);
1432
+ background: var(--surface);
1433
+ }
1434
+
1435
+ .stream-actions .btn svg { flex-shrink: 0; }
1436
+
1437
+ /* ── Delete Button in Job Row ── */
1438
+ .btn-delete-job {
1439
+ padding: 3px 8px;
1440
+ border-radius: 4px;
1441
+ background: transparent;
1442
+ color: var(--text-muted);
1443
+ border: 1px solid transparent;
1444
+ font-size: 0.72rem;
1445
+ cursor: pointer;
1446
+ display: inline-flex;
1447
+ align-items: center;
1448
+ gap: 4px;
1449
+ transition: all var(--transition);
1450
+ }
1451
+
1452
+ .btn-delete-job:hover {
1453
+ background: var(--red-dim);
1454
+ color: var(--red);
1455
+ border-color: var(--red);
1456
+ }
1457
+
1458
+ /* ── Retry Job Button in Job Row ── */
1459
+ .btn-retry-job {
1460
+ padding: 3px 8px;
1461
+ border-radius: 4px;
1462
+ background: transparent;
1463
+ color: var(--text-muted);
1464
+ border: 1px solid transparent;
1465
+ font-size: 0.72rem;
1466
+ cursor: pointer;
1467
+ display: inline-flex;
1468
+ align-items: center;
1469
+ gap: 4px;
1470
+ transition: all var(--transition);
1471
+ }
1472
+
1473
+ .btn-retry-job:hover {
1474
+ background: var(--yellow-dim);
1475
+ color: var(--yellow);
1476
+ border-color: var(--yellow);
1477
+ }
1478
+
1479
+ /* ── Continue Session Button in Job Row ── */
1480
+ .btn-continue-job {
1481
+ padding: 3px 8px;
1482
+ border-radius: 4px;
1483
+ background: transparent;
1484
+ color: var(--text-muted);
1485
+ border: 1px solid transparent;
1486
+ font-size: 0.72rem;
1487
+ cursor: pointer;
1488
+ display: inline-flex;
1489
+ align-items: center;
1490
+ gap: 4px;
1491
+ transition: all var(--transition);
1492
+ }
1493
+
1494
+ .btn-continue-job:hover {
1495
+ background: var(--accent-glow);
1496
+ color: var(--accent);
1497
+ border-color: var(--accent);
1498
+ }
1499
+
1500
+ /* ── Fork Session Button in Job Row ── */
1501
+ .btn-fork-job {
1502
+ padding: 3px 8px;
1503
+ border-radius: 4px;
1504
+ background: transparent;
1505
+ color: var(--text-muted);
1506
+ border: 1px solid transparent;
1507
+ font-size: 0.72rem;
1508
+ cursor: pointer;
1509
+ display: inline-flex;
1510
+ align-items: center;
1511
+ gap: 4px;
1512
+ transition: all var(--transition);
1513
+ }
1514
+
1515
+ .btn-fork-job:hover {
1516
+ background: var(--yellow-dim);
1517
+ color: var(--yellow);
1518
+ border-color: var(--yellow);
1519
+ }
1520
+
1521
+ /* ── Follow-up Input in Stream Panel ── */
1522
+ .stream-followup {
1523
+ display: flex;
1524
+ align-items: center;
1525
+ gap: 8px;
1526
+ padding: 10px 18px;
1527
+ border-top: 1px solid var(--border);
1528
+ background: var(--bg);
1529
+ }
1530
+
1531
+ .stream-followup-label {
1532
+ font-size: 0.7rem;
1533
+ color: var(--accent);
1534
+ font-weight: 600;
1535
+ white-space: nowrap;
1536
+ flex-shrink: 0;
1537
+ }
1538
+
1539
+ .followup-input-wrap {
1540
+ display: flex;
1541
+ align-items: center;
1542
+ gap: 6px;
1543
+ flex: 1;
1544
+ }
1545
+
1546
+ .followup-input {
1547
+ flex: 1;
1548
+ padding: 6px 10px;
1549
+ border-radius: var(--radius);
1550
+ border: 1px solid var(--border);
1551
+ background: var(--surface);
1552
+ color: var(--text);
1553
+ font-size: 0.78rem;
1554
+ font-family: var(--font-mono);
1555
+ outline: none;
1556
+ transition: border-color var(--transition);
1557
+ }
1558
+
1559
+ .followup-input:focus {
1560
+ border-color: var(--accent);
1561
+ }
1562
+
1563
+ .followup-input::placeholder {
1564
+ color: var(--text-muted);
1565
+ font-size: 0.72rem;
1566
+ }
1567
+
1568
+ .followup-previews {
1569
+ display: flex;
1570
+ flex-wrap: wrap;
1571
+ gap: 4px;
1572
+ padding: 0 18px;
1573
+ }
1574
+
1575
+ .followup-previews:empty { display: none; }
1576
+
1577
+ .followup-file-chip {
1578
+ display: inline-block;
1579
+ padding: 1px 6px;
1580
+ border-radius: 4px;
1581
+ font-size: 0.68rem;
1582
+ font-family: var(--font-mono);
1583
+ background: var(--green-dim);
1584
+ color: var(--green);
1585
+ white-space: nowrap;
1586
+ max-width: 200px;
1587
+ overflow: hidden;
1588
+ text-overflow: ellipsis;
1589
+ }
1590
+
1591
+ /* ── Copy Success Animation ── */
1592
+ .btn-copied {
1593
+ color: var(--green) !important;
1594
+ border-color: var(--green) !important;
1595
+ background: var(--green-dim) !important;
1596
+ }
1597
+
1598
+ /* ── Toast ── */
1599
+ .toast-container {
1600
+ position: fixed;
1601
+ top: 70px;
1602
+ right: 24px;
1603
+ z-index: 1000;
1604
+ display: flex;
1605
+ flex-direction: column;
1606
+ gap: 8px;
1607
+ }
1608
+
1609
+ .toast {
1610
+ padding: 10px 16px;
1611
+ border-radius: var(--radius);
1612
+ font-size: 0.82rem;
1613
+ font-weight: 500;
1614
+ background: var(--surface);
1615
+ border: 1px solid var(--border);
1616
+ color: var(--text);
1617
+ box-shadow: var(--shadow);
1618
+ animation: toastIn 0.3s ease, toastOut 0.3s ease 2.7s forwards;
1619
+ display: flex;
1620
+ align-items: center;
1621
+ gap: 8px;
1622
+ }
1623
+
1624
+ .toast.success { border-color: var(--green); color: var(--green); }
1625
+ .toast.error { border-color: var(--red); color: var(--red); }
1626
+
1627
+ @keyframes toastIn {
1628
+ from { opacity: 0; transform: translateX(20px); }
1629
+ to { opacity: 1; transform: translateX(0); }
1630
+ }
1631
+
1632
+ @keyframes toastOut {
1633
+ from { opacity: 1; transform: translateX(0); }
1634
+ to { opacity: 0; transform: translateX(20px); }
1635
+ }
1636
+
1637
+ /* ── Spinner ── */
1638
+ .spinner {
1639
+ display: inline-block;
1640
+ width: 14px;
1641
+ height: 14px;
1642
+ border: 2px solid var(--border);
1643
+ border-top-color: var(--accent);
1644
+ border-radius: 50%;
1645
+ animation: spin 0.6s linear infinite;
1646
+ }
1647
+
1648
+ @keyframes spin { to { transform: rotate(360deg); } }
1649
+
1650
+ /* ── Responsive ── */
1651
+ /* ── @image Chip in prompt cell ── */
1652
+ .prompt-img-chip {
1653
+ display: inline-flex;
1654
+ align-items: center;
1655
+ gap: 3px;
1656
+ padding: 1px 7px;
1657
+ border-radius: 4px;
1658
+ background: var(--blue-dim);
1659
+ color: var(--blue);
1660
+ font-size: 0.7rem;
1661
+ font-weight: 600;
1662
+ font-family: var(--font-mono);
1663
+ white-space: nowrap;
1664
+ vertical-align: baseline;
1665
+ }
1666
+
1667
+ .prompt-img-chip svg {
1668
+ width: 10px;
1669
+ height: 10px;
1670
+ flex-shrink: 0;
1671
+ }
1672
+
1673
+ @media (max-width: 900px) {
1674
+ .main { padding: 8px 0; }
1675
+ th, td { padding: 10px 10px; font-size: 0.78rem; }
1676
+ }
1677
+
1678
+ @media (max-width: 600px) {
1679
+ .main { padding: 4px 0; }
1680
+ .card-body { padding: 14px; }
1681
+ th, td { padding: 8px 6px; font-size: 0.74rem; }
1682
+ .job-cwd { max-width: 100%; }
1683
+ .stream-content { max-height: 300px; }
1684
+ }
1685
+
1686
+ /* ── Settings Panel ── */
1687
+ .settings-fab {
1688
+ position: fixed;
1689
+ bottom: 24px;
1690
+ right: 24px;
1691
+ z-index: 300;
1692
+ width: 44px;
1693
+ height: 44px;
1694
+ border-radius: 50%;
1695
+ background: var(--surface);
1696
+ border: 1px solid var(--border);
1697
+ color: var(--text-secondary);
1698
+ display: flex;
1699
+ align-items: center;
1700
+ justify-content: center;
1701
+ cursor: pointer;
1702
+ box-shadow: 0 4px 16px rgba(0,0,0,0.4);
1703
+ transition: all var(--transition);
1704
+ }
1705
+ .settings-fab:hover {
1706
+ background: var(--surface-hover);
1707
+ color: var(--accent);
1708
+ border-color: var(--accent);
1709
+ transform: rotate(30deg);
1710
+ }
1711
+
1712
+ .settings-overlay {
1713
+ display: none;
1714
+ position: fixed;
1715
+ inset: 0;
1716
+ z-index: 400;
1717
+ background: rgba(0,0,0,0.5);
1718
+ backdrop-filter: blur(4px);
1719
+ animation: fadeIn 0.2s ease;
1720
+ }
1721
+ .settings-overlay.open { display: flex; align-items: center; justify-content: center; }
1722
+
1723
+ .settings-panel {
1724
+ width: 520px;
1725
+ max-width: 90vw;
1726
+ max-height: 85vh;
1727
+ background: var(--surface);
1728
+ border: 1px solid var(--border);
1729
+ border-radius: var(--radius-lg);
1730
+ box-shadow: 0 16px 48px rgba(0,0,0,0.5);
1731
+ display: flex;
1732
+ flex-direction: column;
1733
+ overflow: hidden;
1734
+ animation: panel-slide 0.2s ease-out;
1735
+ }
1736
+
1737
+ .settings-header {
1738
+ display: flex;
1739
+ align-items: center;
1740
+ justify-content: space-between;
1741
+ padding: 16px 20px;
1742
+ border-bottom: 1px solid var(--border);
1743
+ }
1744
+ .settings-title {
1745
+ font-size: 1rem;
1746
+ font-weight: 700;
1747
+ color: var(--text);
1748
+ display: flex;
1749
+ align-items: center;
1750
+ gap: 8px;
1751
+ }
1752
+ .settings-title svg { width: 18px; height: 18px; color: var(--accent); }
1753
+ .settings-close {
1754
+ padding: 6px;
1755
+ border-radius: var(--radius);
1756
+ background: transparent;
1757
+ color: var(--text-muted);
1758
+ border: none;
1759
+ cursor: pointer;
1760
+ }
1761
+ .settings-close:hover { background: var(--surface-active); color: var(--text); }
1762
+
1763
+ .settings-body {
1764
+ flex: 1;
1765
+ overflow-y: auto;
1766
+ padding: 20px;
1767
+ }
1768
+
1769
+ .settings-section {
1770
+ margin-bottom: 20px;
1771
+ }
1772
+ .settings-section-title {
1773
+ font-size: 0.72rem;
1774
+ font-weight: 600;
1775
+ color: var(--text-muted);
1776
+ text-transform: uppercase;
1777
+ letter-spacing: 0.06em;
1778
+ margin-bottom: 12px;
1779
+ }
1780
+
1781
+ .setting-row {
1782
+ display: flex;
1783
+ align-items: flex-start;
1784
+ justify-content: space-between;
1785
+ padding: 10px 0;
1786
+ border-bottom: 1px solid var(--border);
1787
+ gap: 16px;
1788
+ }
1789
+ .setting-row:last-child { border-bottom: none; }
1790
+
1791
+ .setting-info { flex: 1; min-width: 0; }
1792
+ .setting-label {
1793
+ font-size: 0.85rem;
1794
+ font-weight: 500;
1795
+ color: var(--text);
1796
+ margin-bottom: 2px;
1797
+ }
1798
+ .setting-desc {
1799
+ font-size: 0.72rem;
1800
+ color: var(--text-muted);
1801
+ line-height: 1.4;
1802
+ }
1803
+
1804
+ .setting-control { flex-shrink: 0; }
1805
+
1806
+ /* Toggle Switch */
1807
+ .toggle {
1808
+ position: relative;
1809
+ width: 40px;
1810
+ height: 22px;
1811
+ cursor: pointer;
1812
+ }
1813
+ .toggle input { display: none; }
1814
+ .toggle-track {
1815
+ position: absolute;
1816
+ inset: 0;
1817
+ background: var(--border);
1818
+ border-radius: 11px;
1819
+ transition: background var(--transition);
1820
+ }
1821
+ .toggle input:checked + .toggle-track { background: var(--accent); }
1822
+ .toggle-thumb {
1823
+ position: absolute;
1824
+ top: 2px;
1825
+ left: 2px;
1826
+ width: 18px;
1827
+ height: 18px;
1828
+ border-radius: 50%;
1829
+ background: #fff;
1830
+ transition: transform var(--transition);
1831
+ box-shadow: 0 1px 3px rgba(0,0,0,0.3);
1832
+ }
1833
+ .toggle input:checked ~ .toggle-thumb { transform: translateX(18px); }
1834
+
1835
+ .setting-input {
1836
+ width: 100%;
1837
+ padding: 7px 10px;
1838
+ background: var(--bg);
1839
+ border: 1px solid var(--border);
1840
+ border-radius: var(--radius);
1841
+ color: var(--text);
1842
+ font-family: var(--font-mono);
1843
+ font-size: 0.8rem;
1844
+ transition: border-color var(--transition);
1845
+ }
1846
+ .setting-input:focus {
1847
+ outline: none;
1848
+ border-color: var(--accent);
1849
+ box-shadow: 0 0 0 3px var(--accent-glow);
1850
+ }
1851
+ .setting-input-sm { width: 80px; text-align: center; }
1852
+
1853
+ .settings-footer {
1854
+ display: flex;
1855
+ align-items: center;
1856
+ justify-content: flex-end;
1857
+ gap: 8px;
1858
+ padding: 14px 20px;
1859
+ border-top: 1px solid var(--border);
1860
+ }
1861
+
1862
+ .setting-restart-hint {
1863
+ font-size: 0.7rem;
1864
+ color: var(--yellow);
1865
+ margin-right: auto;
1866
+ display: flex;
1867
+ align-items: center;
1868
+ gap: 4px;
1869
+ }
1870
+
1871
+ /* ── Connection Modal ── */
1872
+ .conn-message {
1873
+ font-size: 0.8rem;
1874
+ color: var(--red);
1875
+ background: var(--red-dim);
1876
+ border: 1px solid rgba(248, 113, 113, 0.25);
1877
+ border-radius: var(--radius);
1878
+ padding: 8px 12px;
1879
+ }
1880
+
1881
+ /* ── Running Job Preview Row ── */
1882
+ .preview-row {
1883
+ cursor: default !important;
1884
+ }
1885
+ .preview-row,
1886
+ .preview-row:hover {
1887
+ background: transparent !important;
1888
+ }
1889
+ .preview-row td {
1890
+ padding: 0 !important;
1891
+ border-bottom: 1px solid var(--border) !important;
1892
+ }
1893
+
1894
+ .job-preview {
1895
+ padding: 6px 14px;
1896
+ background: var(--bg);
1897
+ font-family: var(--font-mono);
1898
+ font-size: 0.78rem;
1899
+ line-height: 1.7;
1900
+ color: var(--text-muted);
1901
+ max-height: calc(0.78rem * 1.7 * 2 + 6px + 6px);
1902
+ overflow: hidden;
1903
+ box-sizing: content-box;
1904
+ }
1905
+ .preview-lines {
1906
+ min-width: 0;
1907
+ overflow: hidden;
1908
+ }
1909
+ .preview-line {
1910
+ padding: 2px 0;
1911
+ word-break: break-word;
1912
+ }
1913
+ .preview-line + .preview-line {
1914
+ margin-top: 1px;
1915
+ }
1916
+ .preview-tool {
1917
+ display: inline-flex;
1918
+ align-items: center;
1919
+ gap: 4px;
1920
+ padding: 2px 8px;
1921
+ border-radius: 4px;
1922
+ background: var(--yellow-dim);
1923
+ color: var(--yellow);
1924
+ font-size: 0.7rem;
1925
+ font-weight: 600;
1926
+ white-space: nowrap;
1927
+ margin-right: 4px;
1928
+ }
1929
+ .preview-tool::before {
1930
+ content: '>';
1931
+ opacity: 0.5;
1932
+ }
1933
+ .preview-result {
1934
+ color: var(--green);
1935
+ }
1936
+ .preview-result::before {
1937
+ content: '✓ ';
1938
+ font-weight: 700;
1939
+ }
1940
+ .preview-text {
1941
+ color: var(--text-muted);
1942
+ }