@bakapiano/ccsm 0.9.0 → 0.10.1

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 (69) hide show
  1. package/CLAUDE.md +222 -195
  2. package/README.md +77 -79
  3. package/lib/cliSessionWatcher.js +249 -0
  4. package/lib/config.js +101 -24
  5. package/lib/folders.js +96 -0
  6. package/lib/localCliSessions.js +177 -0
  7. package/lib/persistedSessions.js +134 -0
  8. package/lib/webTerminal.js +31 -18
  9. package/lib/workspace.js +26 -4
  10. package/package.json +1 -1
  11. package/public/assets/claude-color.svg +1 -0
  12. package/public/assets/codex-color.svg +1 -0
  13. package/public/assets/copilot-color.svg +1 -0
  14. package/public/css/base.css +22 -5
  15. package/public/css/cards.css +37 -3
  16. package/public/css/feedback.css +127 -43
  17. package/public/css/forms.css +97 -25
  18. package/public/css/layout.css +74 -26
  19. package/public/css/modal.css +40 -26
  20. package/public/css/responsive.css +2 -2
  21. package/public/css/sidebar.css +424 -25
  22. package/public/css/terminals.css +138 -0
  23. package/public/css/tokens.css +28 -12
  24. package/public/css/wco.css +38 -39
  25. package/public/css/widgets.css +1177 -6
  26. package/public/index.html +35 -2
  27. package/public/js/api.js +194 -37
  28. package/public/js/components/AdoptModal.js +171 -0
  29. package/public/js/components/App.js +1 -11
  30. package/public/js/components/DirectoryPicker.js +203 -0
  31. package/public/js/components/EntityFormModal.js +105 -0
  32. package/public/js/components/Modal.js +51 -0
  33. package/public/js/components/OfflineBanner.js +29 -23
  34. package/public/js/components/PageTitleBar.js +13 -0
  35. package/public/js/components/Picker.js +179 -0
  36. package/public/js/components/Popover.js +55 -0
  37. package/public/js/components/Sidebar.js +219 -32
  38. package/public/js/components/TerminalView.js +27 -3
  39. package/public/js/components/useDragSort.js +67 -0
  40. package/public/js/dialog.js +10 -2
  41. package/public/js/icons.js +66 -3
  42. package/public/js/main.js +54 -3
  43. package/public/js/pages/AboutPage.js +80 -0
  44. package/public/js/pages/ConfigurePage.js +429 -207
  45. package/public/js/pages/LaunchPage.js +326 -86
  46. package/public/js/pages/SessionsPage.js +91 -41
  47. package/public/js/state.js +102 -73
  48. package/public/manifest.webmanifest +2 -2
  49. package/scripts/install.js +7 -2
  50. package/server.js +755 -441
  51. package/lib/favorites.js +0 -51
  52. package/lib/focus.js +0 -369
  53. package/lib/labels.js +0 -29
  54. package/lib/launcher.js +0 -219
  55. package/lib/sessions.js +0 -272
  56. package/lib/snapshot.js +0 -141
  57. package/public/js/actions.js +0 -107
  58. package/public/js/components/Fab.js +0 -11
  59. package/public/js/components/FavoritesTable.js +0 -81
  60. package/public/js/components/Footer.js +0 -12
  61. package/public/js/components/NewSessionModal.js +0 -153
  62. package/public/js/components/PageHead.js +0 -33
  63. package/public/js/components/Pagination.js +0 -27
  64. package/public/js/components/RecentTable.js +0 -68
  65. package/public/js/components/SessionsTable.js +0 -71
  66. package/public/js/components/SnapshotPanel.js +0 -77
  67. package/public/js/components/TitleCell.js +0 -40
  68. package/public/js/components/WorkspacesGrid.js +0 -41
  69. package/public/js/pages/TerminalsPage.js +0 -74
@@ -7,31 +7,34 @@
7
7
  }
8
8
  .workspace-card {
9
9
  padding: var(--s-4);
10
- border: 1px solid var(--border);
10
+ border: 1px solid var(--border-soft);
11
11
  background: var(--bg-elev);
12
- border-radius: var(--r-md);
13
- transition: border-color .12s, box-shadow .12s;
12
+ border-radius: 6px;
13
+ transition: border-color .18s, box-shadow .18s, transform .18s;
14
14
  }
15
15
  .workspace-card:hover {
16
- border-color: var(--border-strong);
17
- box-shadow: var(--shadow);
16
+ border-color: var(--ink-faint);
17
+ box-shadow: var(--shadow-md);
18
+ transform: translateY(-1px);
18
19
  }
19
20
  .workspace-card.in-use {
20
21
  background: var(--bg);
21
22
  border-color: var(--ink-faint);
23
+ box-shadow: inset 3px 0 0 var(--accent);
22
24
  }
23
25
  .workspace-card .ws-head {
24
26
  display: flex;
25
27
  align-items: baseline;
26
28
  justify-content: space-between;
27
29
  gap: var(--s-2);
28
- margin-bottom: 4px;
30
+ margin-bottom: 6px;
29
31
  }
30
32
  .workspace-card .ws-name {
31
33
  font-size: 14.5px;
32
34
  font-weight: 600;
33
35
  letter-spacing: -0.01em;
34
36
  color: var(--ink);
37
+ line-height: 1.2;
35
38
  }
36
39
  .workspace-card .ws-tag {
37
40
  font-family: var(--mono);
@@ -202,3 +205,1171 @@
202
205
  white-space: pre;
203
206
  line-height: 1.55;
204
207
  }
208
+
209
+ /* === Launch page hero · ChatGPT-style centered composer ============= */
210
+
211
+ .launch-hero {
212
+ max-width: 640px;
213
+ width: 100%;
214
+ margin: 0 auto;
215
+ padding: var(--s-4);
216
+ display: flex;
217
+ flex-direction: column;
218
+ align-items: center;
219
+ justify-content: center;
220
+ gap: var(--s-5);
221
+ flex: 1;
222
+ min-height: 0;
223
+ }
224
+
225
+ .launch-brand {
226
+ display: inline-flex;
227
+ align-items: center;
228
+ justify-content: center;
229
+ color: var(--accent);
230
+ }
231
+ .launch-brand-mark svg {
232
+ width: 88px;
233
+ height: 88px;
234
+ display: block;
235
+ }
236
+
237
+ .launch-tagline {
238
+ font-size: 26px;
239
+ font-weight: 500;
240
+ letter-spacing: -0.02em;
241
+ color: var(--ink);
242
+ text-align: center;
243
+ margin: 0;
244
+ line-height: 1.25;
245
+ max-width: 32ch;
246
+ }
247
+ .launch-tagline em {
248
+ font-style: normal;
249
+ color: var(--accent);
250
+ font-weight: 500;
251
+ }
252
+
253
+
254
+
255
+ .launch-status {
256
+ font-family: var(--mono);
257
+ font-size: 11.5px;
258
+ color: var(--ink-muted);
259
+ align-self: stretch;
260
+ text-align: center;
261
+ }
262
+
263
+ .launch-import-link {
264
+ display: inline-flex;
265
+ align-items: center;
266
+ background: transparent;
267
+ border: none;
268
+ font: inherit;
269
+ font-size: 12px;
270
+ color: var(--ink-faint);
271
+ cursor: pointer;
272
+ padding: 4px 8px;
273
+ border-radius: 6px;
274
+ transition: color 120ms ease;
275
+ }
276
+ .launch-import-link:hover { color: var(--ink-mid); }
277
+ .launch-import-arrow {
278
+ display: inline-flex;
279
+ align-items: center;
280
+ margin-left: 6px;
281
+ transition: transform 180ms cubic-bezier(.4, 0, .2, 1);
282
+ }
283
+ .launch-import-link:hover .launch-import-arrow { transform: translateX(3px); }
284
+
285
+ /* === Launch toolbar · A · Pill toolbar =========================== */
286
+
287
+ .launch-toolbar {
288
+ width: 100%;
289
+ display: flex;
290
+ align-items: center;
291
+ justify-content: center;
292
+ flex-wrap: wrap;
293
+ gap: var(--s-2);
294
+ }
295
+
296
+ .pill {
297
+ appearance: none;
298
+ background: var(--bg);
299
+ border: 1px solid var(--border-soft);
300
+ border-radius: 999px;
301
+ padding: 8px 14px 8px 12px;
302
+ display: inline-flex;
303
+ align-items: center;
304
+ justify-content: center;
305
+ gap: 8px;
306
+ cursor: pointer;
307
+ color: var(--ink);
308
+ font: inherit;
309
+ font-size: 13px;
310
+ font-weight: 500;
311
+ line-height: 1;
312
+ white-space: nowrap;
313
+ transition: background .12s ease, border-color .12s ease, color .12s ease;
314
+ flex: 0 0 160px;
315
+ width: 160px;
316
+ min-width: 0;
317
+ }
318
+ .pill:hover {
319
+ background: var(--sidebar-hover);
320
+ border-color: var(--border);
321
+ }
322
+ .pill.is-open {
323
+ background: var(--sidebar-active);
324
+ border-color: var(--ink-faint);
325
+ }
326
+ .pill.is-set {
327
+ border-color: var(--ink-faint);
328
+ background: var(--sidebar-active);
329
+ }
330
+ .pill.is-disabled,
331
+ .pill:disabled {
332
+ opacity: 0.45;
333
+ cursor: not-allowed;
334
+ }
335
+ .pill.is-disabled:hover,
336
+ .pill:disabled:hover { background: var(--bg-elev); border-color: var(--border); }
337
+
338
+ /* --- Workdir picker (Launch page) ----------------------------------- */
339
+ .workdir-modal {
340
+ display: flex;
341
+ flex-direction: column;
342
+ gap: 14px;
343
+ padding: 18px 20px;
344
+ }
345
+ .workdir-mode-grid {
346
+ display: grid;
347
+ grid-template-columns: 1fr 1fr;
348
+ gap: 10px;
349
+ }
350
+ .workdir-mode-opt {
351
+ appearance: none;
352
+ background: var(--bg-elev);
353
+ border: 1px solid var(--border);
354
+ border-radius: 10px;
355
+ padding: 14px 14px 12px;
356
+ cursor: pointer;
357
+ display: grid;
358
+ grid-template-columns: 32px 1fr;
359
+ grid-template-rows: auto auto;
360
+ column-gap: 10px;
361
+ row-gap: 2px;
362
+ text-align: left;
363
+ align-items: center;
364
+ font: inherit;
365
+ color: var(--ink);
366
+ transition: border-color .12s ease, background .12s ease, box-shadow .12s ease;
367
+ }
368
+ .workdir-mode-opt:hover {
369
+ border-color: var(--ink-faint);
370
+ }
371
+ .workdir-mode-opt.is-active {
372
+ border-color: var(--ink);
373
+ background: var(--bg-elev);
374
+ box-shadow: 0 0 0 1px var(--ink) inset;
375
+ }
376
+ .workdir-mode-icon {
377
+ grid-row: 1 / span 2;
378
+ width: 32px;
379
+ height: 32px;
380
+ display: inline-flex;
381
+ align-items: center;
382
+ justify-content: center;
383
+ border-radius: 8px;
384
+ background: var(--bg);
385
+ color: var(--ink-mid);
386
+ }
387
+ .workdir-mode-opt.is-active .workdir-mode-icon {
388
+ background: var(--ink);
389
+ color: var(--bg-elev);
390
+ }
391
+ .workdir-mode-icon svg,
392
+ .workdir-mode-icon img { width: 18px; height: 18px; display: block; }
393
+ .workdir-mode-name {
394
+ font-size: 13px;
395
+ font-weight: 600;
396
+ letter-spacing: -0.005em;
397
+ }
398
+ .workdir-mode-sub {
399
+ font-size: 11.5px;
400
+ color: var(--ink-muted);
401
+ line-height: 1.35;
402
+ }
403
+ .workdir-mode-opt.is-active .workdir-mode-sub { color: var(--ink-mid); }
404
+
405
+ .workdir-detail {
406
+ border: 1px solid var(--border);
407
+ border-radius: 10px;
408
+ background: var(--bg);
409
+ overflow: hidden;
410
+ }
411
+ .workdir-detail .picker { max-height: min(56vh, 420px); }
412
+ .workdir-detail .filex {
413
+ padding: 10px;
414
+ gap: 10px;
415
+ }
416
+ .workdir-detail .filex-body { height: 320px; }
417
+
418
+ .workdir-foot {
419
+ display: flex;
420
+ justify-content: flex-end;
421
+ gap: 8px;
422
+ margin: 4px -20px -18px;
423
+ padding: 12px 20px;
424
+ border-top: 1px solid var(--border-soft);
425
+ background: var(--bg);
426
+ }
427
+
428
+ .icon-radio-sub {
429
+ font-size: 11px;
430
+ font-weight: 400;
431
+ color: var(--ink-muted);
432
+ margin-top: 1px;
433
+ }
434
+ .icon-radio-opt.is-active .icon-radio-sub { color: var(--accent-deep); opacity: 0.85; }
435
+
436
+ /* --- File-Explorer-style directory picker --------------------------- */
437
+ .filex {
438
+ display: flex;
439
+ flex-direction: column;
440
+ gap: 8px;
441
+ font-size: 12.5px;
442
+ }
443
+ .filex-loading, .filex-empty {
444
+ padding: 24px;
445
+ text-align: center;
446
+ font-size: 12px;
447
+ color: var(--ink-muted);
448
+ font-style: italic;
449
+ }
450
+
451
+ /* toolbar: back/fwd/up + breadcrumb */
452
+ .filex-toolbar {
453
+ display: flex;
454
+ align-items: center;
455
+ gap: 6px;
456
+ padding: 4px;
457
+ border: 1px solid var(--border);
458
+ border-radius: 8px;
459
+ background: var(--bg-elev);
460
+ }
461
+ .filex-navbtns {
462
+ display: flex;
463
+ gap: 2px;
464
+ flex-shrink: 0;
465
+ }
466
+ .filex-navbtn {
467
+ appearance: none;
468
+ background: transparent;
469
+ border: 0;
470
+ width: 28px;
471
+ height: 28px;
472
+ border-radius: 6px;
473
+ display: inline-flex;
474
+ align-items: center;
475
+ justify-content: center;
476
+ color: var(--ink-mid);
477
+ cursor: pointer;
478
+ transition: background .12s ease, color .12s ease;
479
+ }
480
+ .filex-navbtn:hover:not(:disabled) {
481
+ background: var(--sidebar-hover);
482
+ color: var(--ink);
483
+ }
484
+ .filex-navbtn:disabled {
485
+ opacity: 0.35;
486
+ cursor: not-allowed;
487
+ }
488
+ .filex-navbtn svg { width: 14px; height: 14px; }
489
+
490
+ .filex-breadcrumb {
491
+ flex: 1;
492
+ min-width: 0;
493
+ display: flex;
494
+ align-items: center;
495
+ gap: 1px;
496
+ flex-wrap: nowrap;
497
+ overflow: hidden;
498
+ padding: 0 6px;
499
+ cursor: text;
500
+ min-height: 28px;
501
+ }
502
+ .filex-crumb {
503
+ appearance: none;
504
+ background: transparent;
505
+ border: 0;
506
+ font: inherit;
507
+ font-size: 12.5px;
508
+ color: var(--ink);
509
+ padding: 4px 8px;
510
+ border-radius: 4px;
511
+ cursor: pointer;
512
+ white-space: nowrap;
513
+ transition: background .1s ease;
514
+ }
515
+ .filex-crumb:hover { background: var(--bg); }
516
+ .filex-crumb-sep {
517
+ color: var(--ink-faint);
518
+ font-size: 13px;
519
+ user-select: none;
520
+ flex-shrink: 0;
521
+ }
522
+ .filex-address-edit-btn {
523
+ appearance: none;
524
+ background: transparent;
525
+ border: 0;
526
+ width: 26px;
527
+ height: 26px;
528
+ border-radius: 4px;
529
+ display: inline-flex;
530
+ align-items: center;
531
+ justify-content: center;
532
+ color: var(--ink-faint);
533
+ cursor: pointer;
534
+ margin-left: auto;
535
+ flex-shrink: 0;
536
+ opacity: 0;
537
+ transition: opacity .12s ease, background .12s ease, color .12s ease;
538
+ }
539
+ .filex-toolbar:hover .filex-address-edit-btn { opacity: 0.7; }
540
+ .filex-address-edit-btn:hover {
541
+ background: var(--sidebar-hover);
542
+ color: var(--ink);
543
+ opacity: 1;
544
+ }
545
+ .filex-address-edit-btn svg { width: 12px; height: 12px; }
546
+ .filex-address-edit {
547
+ flex: 1;
548
+ display: flex;
549
+ padding: 0 4px;
550
+ }
551
+ .filex-address-input {
552
+ width: 100%;
553
+ appearance: none;
554
+ background: var(--bg);
555
+ border: 1px solid var(--accent);
556
+ border-radius: 5px;
557
+ padding: 5px 8px;
558
+ font-size: 12.5px;
559
+ color: var(--ink);
560
+ outline: none;
561
+ }
562
+
563
+ /* body: sidebar (quick access) + main file list */
564
+ .filex-body {
565
+ display: grid;
566
+ grid-template-columns: 150px 1fr;
567
+ gap: 8px;
568
+ height: 360px;
569
+ border: 1px solid var(--border);
570
+ border-radius: 8px;
571
+ background: var(--bg-elev);
572
+ overflow: hidden;
573
+ }
574
+ .filex-side {
575
+ border-right: 1px solid var(--border);
576
+ background: var(--bg);
577
+ overflow-y: auto;
578
+ padding: 6px 4px;
579
+ display: flex;
580
+ flex-direction: column;
581
+ gap: 1px;
582
+ }
583
+ .filex-side-label {
584
+ font-size: 10px;
585
+ font-weight: 600;
586
+ text-transform: uppercase;
587
+ letter-spacing: 0.08em;
588
+ color: var(--ink-faint);
589
+ padding: 4px 8px;
590
+ }
591
+ .filex-side-item {
592
+ appearance: none;
593
+ background: transparent;
594
+ border: 0;
595
+ text-align: left;
596
+ font: inherit;
597
+ font-size: 12px;
598
+ color: var(--ink-mid);
599
+ cursor: pointer;
600
+ padding: 5px 8px;
601
+ border-radius: 4px;
602
+ display: flex;
603
+ align-items: center;
604
+ gap: 6px;
605
+ width: 100%;
606
+ overflow: hidden;
607
+ text-overflow: ellipsis;
608
+ white-space: nowrap;
609
+ }
610
+ .filex-side-item:hover { background: var(--sidebar-hover); color: var(--ink); }
611
+ .filex-side-item.is-active {
612
+ background: var(--sidebar-active);
613
+ color: var(--ink);
614
+ font-weight: 500;
615
+ }
616
+ .filex-side-icon {
617
+ display: inline-flex;
618
+ width: 14px;
619
+ height: 14px;
620
+ align-items: center;
621
+ justify-content: center;
622
+ color: var(--ink-faint);
623
+ }
624
+ .filex-side-icon svg { width: 13px; height: 13px; }
625
+ .filex-side-name {
626
+ flex: 1;
627
+ min-width: 0;
628
+ overflow: hidden;
629
+ text-overflow: ellipsis;
630
+ }
631
+
632
+ .filex-main { overflow-y: auto; }
633
+ .filex-list { padding: 4px; }
634
+ .filex-row {
635
+ appearance: none;
636
+ display: flex;
637
+ align-items: center;
638
+ gap: 10px;
639
+ width: 100%;
640
+ padding: 8px 10px;
641
+ background: transparent;
642
+ border: 0;
643
+ border-radius: 5px;
644
+ text-align: left;
645
+ font: inherit;
646
+ font-size: 12.5px;
647
+ color: var(--ink);
648
+ cursor: pointer;
649
+ transition: background .08s ease;
650
+ }
651
+ .filex-row:hover { background: var(--bg); }
652
+ .filex-row[data-active="true"] {
653
+ background: var(--accent-soft);
654
+ color: var(--accent-deep);
655
+ }
656
+ .filex-row[data-active="true"] .filex-row-icon { color: var(--accent); }
657
+ .filex-row-icon {
658
+ display: inline-flex;
659
+ width: 18px;
660
+ height: 18px;
661
+ align-items: center;
662
+ justify-content: center;
663
+ color: var(--ink-muted);
664
+ flex-shrink: 0;
665
+ }
666
+ .filex-row-icon svg { width: 16px; height: 16px; }
667
+ .filex-row-name {
668
+ flex: 1;
669
+ min-width: 0;
670
+ overflow: hidden;
671
+ text-overflow: ellipsis;
672
+ white-space: nowrap;
673
+ }
674
+
675
+ .filex-foot {
676
+ display: flex;
677
+ align-items: center;
678
+ gap: 8px;
679
+ padding-top: 6px;
680
+ border-top: 1px solid var(--border);
681
+ }
682
+ .filex-foot-current {
683
+ flex: 1;
684
+ min-width: 0;
685
+ font-size: 11px;
686
+ color: var(--ink-muted);
687
+ overflow: hidden;
688
+ text-overflow: ellipsis;
689
+ white-space: nowrap;
690
+ }
691
+ .filex-foot-actions {
692
+ display: flex;
693
+ gap: 6px;
694
+ flex-shrink: 0;
695
+ }
696
+ .pill-icon {
697
+ display: inline-flex;
698
+ align-items: center;
699
+ color: var(--ink-muted);
700
+ flex: 0 0 auto;
701
+ }
702
+ .pill-icon svg { width: 14px; height: 14px; }
703
+ .pill-label {
704
+ flex: 0 1 auto;
705
+ min-width: 0;
706
+ overflow: hidden;
707
+ text-overflow: ellipsis;
708
+ }
709
+ .pill-chev {
710
+ display: inline-flex;
711
+ color: var(--ink-faint);
712
+ margin-left: 2px;
713
+ flex: 0 0 auto;
714
+ transition: transform .15s ease;
715
+ }
716
+ .pill-chev svg { width: 12px; height: 12px; }
717
+ .pill.is-open .pill-chev { transform: rotate(180deg); }
718
+
719
+ .action.launch-cta {
720
+ align-self: center;
721
+ border-radius: 6px;
722
+ padding: 7px 22px;
723
+ font-size: 13px;
724
+ font-weight: 500;
725
+ letter-spacing: -0.005em;
726
+ display: inline-flex;
727
+ align-items: center;
728
+ justify-content: center;
729
+ gap: 6px;
730
+ min-width: 0;
731
+ margin-top: var(--s-1);
732
+ background: var(--accent);
733
+ border-color: var(--accent);
734
+ color: #fff;
735
+ }
736
+ .action.launch-cta:hover:not(:disabled) {
737
+ background: var(--accent-deep);
738
+ border-color: var(--accent-deep);
739
+ box-shadow: 0 4px 12px -4px var(--accent-soft);
740
+ }
741
+
742
+ /* === Settings page scroll container ================================
743
+ .tab-panel is flex:1 inside .content which clips overflow. Without a
744
+ scroll layer Settings cards beyond the viewport bottom get cut off. */
745
+ .settings-scroll {
746
+ flex: 1;
747
+ min-height: 0;
748
+ overflow-y: auto;
749
+ display: flex;
750
+ flex-direction: column;
751
+ gap: var(--s-4);
752
+ padding: 4px var(--s-2) var(--s-4) 4px;
753
+ margin: -4px calc(-1 * var(--s-2)) 0 -4px;
754
+ }
755
+ /* In a flex column container, items default to flex-shrink:1 which
756
+ causes the cards to compress instead of pushing the scroll container
757
+ to actually scroll. flex:0 0 auto pins them to their natural height. */
758
+ .settings-scroll > .card { flex: 0 0 auto; }
759
+ .settings-scroll > .settings-section { flex: 0 0 auto; }
760
+
761
+ /* === Settings section · A · flat, no card ========================== */
762
+ .settings-section {
763
+ display: flex;
764
+ flex-direction: column;
765
+ gap: var(--s-3);
766
+ padding-bottom: var(--s-5);
767
+ border-bottom: 1px solid var(--border-soft);
768
+ }
769
+ .settings-section:last-child { border-bottom: 0; }
770
+ .settings-section-head {
771
+ display: flex;
772
+ flex-direction: column;
773
+ gap: 2px;
774
+ }
775
+ .settings-section-title {
776
+ font-size: 15px;
777
+ font-weight: 600;
778
+ letter-spacing: -0.012em;
779
+ color: var(--ink);
780
+ line-height: 1.2;
781
+ margin: 0;
782
+ }
783
+ .settings-section-meta {
784
+ font-size: 12.5px;
785
+ color: var(--ink-muted);
786
+ margin: 0;
787
+ }
788
+ .settings-section-body { display: flex; flex-direction: column; gap: var(--s-2); }
789
+
790
+ /* === Settings entity list (CLIs / Repos / Folders) ================== */
791
+ .entity-list {
792
+ display: flex;
793
+ flex-direction: column;
794
+ gap: 2px;
795
+ }
796
+ .entity-row {
797
+ display: flex;
798
+ align-items: center;
799
+ gap: var(--s-3);
800
+ padding: 8px 8px 8px 4px;
801
+ border-radius: 6px;
802
+ transition: background .1s ease;
803
+ }
804
+ .entity-row.is-draggable { cursor: grab; }
805
+ .entity-row.is-draggable:active { cursor: grabbing; }
806
+ .entity-row[data-dnd-over="true"] {
807
+ box-shadow: 0 -2px 0 var(--accent) inset;
808
+ }
809
+ .entity-row-grip {
810
+ display: inline-flex;
811
+ align-items: center;
812
+ justify-content: center;
813
+ width: 14px;
814
+ color: var(--ink-faint);
815
+ font-size: 12px;
816
+ letter-spacing: -1px;
817
+ user-select: none;
818
+ pointer-events: none;
819
+ flex: 0 0 14px;
820
+ }
821
+ .entity-row:hover { background: var(--bg); }
822
+ .entity-row-icon {
823
+ display: inline-flex;
824
+ align-items: center;
825
+ justify-content: center;
826
+ width: 20px;
827
+ height: 20px;
828
+ color: var(--ink-muted);
829
+ flex: 0 0 20px;
830
+ }
831
+ .entity-row-icon svg { width: 16px; height: 16px; }
832
+ .entity-row-main {
833
+ flex: 0 1 auto;
834
+ min-width: 0;
835
+ display: flex;
836
+ flex-direction: column;
837
+ gap: 1px;
838
+ }
839
+ .entity-row-primary {
840
+ font-size: 13px;
841
+ font-weight: 500;
842
+ color: var(--ink);
843
+ display: inline-flex;
844
+ align-items: center;
845
+ gap: 6px;
846
+ }
847
+ .entity-row-badge {
848
+ font-family: var(--mono);
849
+ font-size: 10px;
850
+ letter-spacing: 0.06em;
851
+ text-transform: uppercase;
852
+ padding: 1px 6px;
853
+ border-radius: 4px;
854
+ font-weight: 500;
855
+ }
856
+ .entity-row-badge.tone-accent {
857
+ background: var(--accent-soft);
858
+ color: var(--accent-deep);
859
+ }
860
+ .entity-row-badge.tone-ok {
861
+ background: rgba(74, 138, 74, 0.12);
862
+ color: var(--green);
863
+ }
864
+ .entity-row-badge.tone-warn {
865
+ background: rgba(196, 137, 43, 0.14);
866
+ color: var(--yellow);
867
+ }
868
+ .entity-row-secondary {
869
+ font-size: 11.5px;
870
+ color: var(--ink-muted);
871
+ overflow: hidden;
872
+ text-overflow: ellipsis;
873
+ white-space: nowrap;
874
+ }
875
+ .entity-row-actions {
876
+ display: flex;
877
+ align-items: center;
878
+ gap: 2px;
879
+ flex-shrink: 0;
880
+ opacity: 0;
881
+ transition: opacity .12s ease;
882
+ margin-right: auto; /* pin actions next to the name, let trailing space stay empty */
883
+ }
884
+ .entity-row:hover .entity-row-actions,
885
+ .entity-row:focus-within .entity-row-actions {
886
+ opacity: 1;
887
+ }
888
+ .entity-row-action {
889
+ appearance: none;
890
+ background: transparent;
891
+ border: 0;
892
+ display: inline-flex;
893
+ align-items: center;
894
+ justify-content: center;
895
+ width: 30px;
896
+ height: 30px;
897
+ border-radius: 6px;
898
+ cursor: pointer;
899
+ color: var(--ink-mid);
900
+ font: inherit;
901
+ font-size: 16px;
902
+ transition: background .12s ease, color .12s ease;
903
+ }
904
+ .entity-row-action:hover { background: var(--sidebar-hover); color: var(--ink); }
905
+ .entity-row-action.danger:hover { color: var(--red); }
906
+ .entity-row-action svg { width: 16px; height: 16px; }
907
+
908
+ .entity-empty {
909
+ padding: 14px 10px;
910
+ font-size: 12.5px;
911
+ color: var(--ink-muted);
912
+ font-style: italic;
913
+ }
914
+
915
+ .entity-add {
916
+ appearance: none;
917
+ background: var(--accent);
918
+ border: 0;
919
+ display: inline-flex;
920
+ align-self: flex-start;
921
+ align-items: center;
922
+ gap: 6px;
923
+ padding: 6px 12px;
924
+ margin-top: 4px;
925
+ border-radius: 6px;
926
+ cursor: pointer;
927
+ color: #fff;
928
+ font: inherit;
929
+ font-size: 12.5px;
930
+ font-weight: 500;
931
+ transition: background .12s ease, box-shadow .12s ease;
932
+ }
933
+ .entity-add:hover {
934
+ background: var(--accent-deep);
935
+ box-shadow: 0 2px 6px -2px var(--accent-soft);
936
+ }
937
+ .entity-add svg { width: 13px; height: 13px; }
938
+
939
+ /* === EntityFormModal · shared form layout ========================== */
940
+ .entity-form {
941
+ padding: var(--s-4);
942
+ display: flex;
943
+ flex-direction: column;
944
+ gap: var(--s-3);
945
+ }
946
+ .entity-field {
947
+ display: flex;
948
+ flex-direction: column;
949
+ gap: 4px;
950
+ }
951
+ .entity-field-label {
952
+ font-size: 11.5px;
953
+ color: var(--ink-muted);
954
+ font-weight: 500;
955
+ }
956
+ .entity-field .input {
957
+ padding: 8px 10px;
958
+ font-size: 13px;
959
+ max-width: none;
960
+ }
961
+ .entity-field .input[readonly],
962
+ .entity-field .input:disabled {
963
+ background: var(--bg);
964
+ color: var(--ink-muted);
965
+ cursor: not-allowed;
966
+ }
967
+ .entity-field-hint {
968
+ font-size: 11px;
969
+ color: var(--ink-muted);
970
+ }
971
+ .entity-checkbox-row {
972
+ display: inline-flex;
973
+ align-items: center;
974
+ gap: 8px;
975
+ padding: 4px 0;
976
+ }
977
+ .entity-form-actions {
978
+ display: flex;
979
+ justify-content: flex-end;
980
+ gap: 6px;
981
+ margin-top: 4px;
982
+ }
983
+
984
+ .icon-radio {
985
+ display: grid;
986
+ grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
987
+ gap: 6px;
988
+ }
989
+ .icon-radio.is-disabled { opacity: 0.6; pointer-events: none; }
990
+ .icon-radio-opt {
991
+ appearance: none;
992
+ background: var(--bg-elev);
993
+ border: 1px solid var(--border);
994
+ border-radius: 6px;
995
+ padding: 10px 8px 8px;
996
+ cursor: pointer;
997
+ display: flex;
998
+ flex-direction: column;
999
+ align-items: center;
1000
+ gap: 6px;
1001
+ color: var(--ink-mid);
1002
+ font: inherit;
1003
+ font-size: 12px;
1004
+ font-weight: 500;
1005
+ transition: border-color .12s ease, background .12s ease, color .12s ease;
1006
+ }
1007
+ .icon-radio-opt:hover { border-color: var(--ink-faint); color: var(--ink); }
1008
+ .icon-radio-opt.is-active {
1009
+ background: var(--accent-soft);
1010
+ border-color: var(--accent);
1011
+ color: var(--accent-deep);
1012
+ }
1013
+ .icon-radio-opt:disabled { cursor: not-allowed; }
1014
+ .icon-radio-icon {
1015
+ display: inline-flex;
1016
+ align-items: center;
1017
+ justify-content: center;
1018
+ width: 24px;
1019
+ height: 24px;
1020
+ }
1021
+ .icon-radio-icon svg,
1022
+ .icon-radio-icon img { width: 24px; height: 24px; display: block; }
1023
+ .launch-cta-plane {
1024
+ display: inline-flex;
1025
+ align-items: center;
1026
+ justify-content: center;
1027
+ width: 16px;
1028
+ height: 16px;
1029
+ /* Resting state: tilted slightly clockwise, like a paper plane caught
1030
+ mid-glide. */
1031
+ transform: translate(0, 0) rotate(8deg);
1032
+ transform-origin: 60% 50%;
1033
+ transition: transform .35s cubic-bezier(.4, 0, .2, 1),
1034
+ opacity .25s ease;
1035
+ will-change: transform, opacity;
1036
+ }
1037
+ .launch-cta-plane svg { width: 100%; height: 100%; }
1038
+ .launch-cta:hover:not(:disabled) .launch-cta-plane {
1039
+ /* Small lift + glide forward — no big arc, no fade-out. */
1040
+ transform: translate(4px, -3px) rotate(14deg);
1041
+ }
1042
+
1043
+ /* Narrow viewport — toolbar wraps. Push the Launch button onto its own
1044
+ row so the pills stay readable. */
1045
+ @media (max-width: 720px) {
1046
+ .launch-toolbar {
1047
+ flex-direction: column;
1048
+ align-items: center;
1049
+ }
1050
+ .pill { justify-content: center; flex: 0 0 auto; }
1051
+ }
1052
+
1053
+ /* === Popover + Picker ============================================== */
1054
+ .popover-panel {
1055
+ position: fixed;
1056
+ z-index: 80;
1057
+ background: var(--bg-elev);
1058
+ border: 1px solid var(--border);
1059
+ border-radius: 10px;
1060
+ box-shadow: var(--shadow-lg);
1061
+ overflow: hidden;
1062
+ animation: popover-in .14s ease-out;
1063
+ }
1064
+ @keyframes popover-in {
1065
+ from { opacity: 0; transform: translateY(-4px); }
1066
+ to { opacity: 1; transform: translateY(0); }
1067
+ }
1068
+
1069
+ .picker {
1070
+ display: flex;
1071
+ flex-direction: column;
1072
+ max-height: min(60vh, 460px);
1073
+ }
1074
+ .picker-title {
1075
+ padding: 10px 14px 6px;
1076
+ font-size: 11px;
1077
+ color: var(--ink-muted);
1078
+ font-weight: 500;
1079
+ letter-spacing: 0;
1080
+ border-bottom: 1px solid var(--border-soft);
1081
+ }
1082
+ .picker-search {
1083
+ display: flex;
1084
+ align-items: center;
1085
+ gap: 8px;
1086
+ padding: 8px 12px;
1087
+ border-bottom: 1px solid var(--border-soft);
1088
+ }
1089
+ .picker-search-icon {
1090
+ display: inline-flex;
1091
+ align-items: center;
1092
+ color: var(--ink-faint);
1093
+ }
1094
+ .picker-search-icon svg { width: 14px; height: 14px; }
1095
+ .picker-search-input {
1096
+ flex: 1;
1097
+ appearance: none;
1098
+ background: transparent;
1099
+ border: 0;
1100
+ outline: none;
1101
+ padding: 4px 0;
1102
+ font: inherit;
1103
+ font-size: 13px;
1104
+ color: var(--ink);
1105
+ }
1106
+ .picker-search-input::placeholder { color: var(--ink-faint); }
1107
+ .picker-search-clear {
1108
+ appearance: none;
1109
+ background: transparent;
1110
+ border: 0;
1111
+ padding: 2px;
1112
+ cursor: pointer;
1113
+ color: var(--ink-muted);
1114
+ display: inline-flex;
1115
+ align-items: center;
1116
+ border-radius: 4px;
1117
+ }
1118
+ .picker-search-clear:hover { background: var(--sidebar-hover); color: var(--ink); }
1119
+ .picker-search-clear svg { width: 12px; height: 12px; }
1120
+
1121
+ .picker-list {
1122
+ overflow-y: auto;
1123
+ padding: 4px;
1124
+ flex: 1 1 auto;
1125
+ min-height: 0;
1126
+ }
1127
+ .picker-empty {
1128
+ padding: 18px 14px;
1129
+ font-size: 12.5px;
1130
+ color: var(--ink-muted);
1131
+ text-align: center;
1132
+ line-height: 1.5;
1133
+ }
1134
+ .picker-item {
1135
+ appearance: none;
1136
+ background: transparent;
1137
+ border: 0;
1138
+ width: 100%;
1139
+ text-align: left;
1140
+ display: flex;
1141
+ align-items: center;
1142
+ gap: 10px;
1143
+ padding: 7px 10px;
1144
+ border-radius: 6px;
1145
+ cursor: pointer;
1146
+ color: var(--ink);
1147
+ font: inherit;
1148
+ font-size: 13px;
1149
+ transition: background .1s ease;
1150
+ }
1151
+ .picker-item-wrap {
1152
+ position: relative;
1153
+ display: flex;
1154
+ align-items: center;
1155
+ }
1156
+ .picker-item-wrap.is-draggable { cursor: grab; }
1157
+ .picker-item-wrap.is-draggable:active { cursor: grabbing; }
1158
+ .picker-item-wrap[data-dnd-over="true"] {
1159
+ box-shadow: 0 -2px 0 var(--accent) inset;
1160
+ }
1161
+ .picker-item-grip {
1162
+ display: inline-flex;
1163
+ align-items: center;
1164
+ justify-content: center;
1165
+ width: 14px;
1166
+ margin-left: 2px;
1167
+ color: var(--ink-faint);
1168
+ font-size: 11px;
1169
+ letter-spacing: -1px;
1170
+ user-select: none;
1171
+ pointer-events: none;
1172
+ flex: 0 0 14px;
1173
+ }
1174
+ .picker-item:hover { background: var(--sidebar-hover); }
1175
+ .picker-item.is-selected {
1176
+ background: var(--sidebar-active);
1177
+ font-weight: 500;
1178
+ }
1179
+ .picker-item:disabled {
1180
+ opacity: 0.45;
1181
+ cursor: not-allowed;
1182
+ }
1183
+ .picker-item-icon {
1184
+ display: inline-flex;
1185
+ align-items: center;
1186
+ justify-content: center;
1187
+ width: 18px;
1188
+ height: 18px;
1189
+ flex: 0 0 18px;
1190
+ color: var(--ink-muted);
1191
+ }
1192
+ .picker-item-icon svg,
1193
+ .picker-item-icon img { width: 18px; height: 18px; display: block; }
1194
+ .picker-item-label {
1195
+ flex: 0 0 auto;
1196
+ white-space: nowrap;
1197
+ }
1198
+ .picker-item-meta {
1199
+ flex: 1 1 auto;
1200
+ min-width: 0;
1201
+ font-family: var(--mono);
1202
+ font-size: 11px;
1203
+ color: var(--ink-muted);
1204
+ overflow: hidden;
1205
+ text-overflow: ellipsis;
1206
+ white-space: nowrap;
1207
+ }
1208
+ .picker-item-check {
1209
+ margin-left: auto;
1210
+ font-size: 12px;
1211
+ color: var(--accent);
1212
+ flex: 0 0 auto;
1213
+ }
1214
+
1215
+ .picker-create {
1216
+ border-top: 1px solid var(--border-soft);
1217
+ padding: 6px;
1218
+ }
1219
+ .picker-create-toggle {
1220
+ appearance: none;
1221
+ background: transparent;
1222
+ border: 0;
1223
+ width: 100%;
1224
+ display: flex;
1225
+ align-items: center;
1226
+ gap: 8px;
1227
+ padding: 8px 10px;
1228
+ border-radius: 6px;
1229
+ cursor: pointer;
1230
+ color: var(--ink-mid);
1231
+ font: inherit;
1232
+ font-size: 12.5px;
1233
+ font-weight: 500;
1234
+ transition: background .1s ease, color .1s ease;
1235
+ }
1236
+ .picker-create-toggle:hover {
1237
+ background: var(--sidebar-hover);
1238
+ color: var(--ink);
1239
+ }
1240
+ .picker-create-toggle svg { width: 14px; height: 14px; }
1241
+
1242
+ .picker-create-form {
1243
+ padding: 10px;
1244
+ display: flex;
1245
+ flex-direction: column;
1246
+ gap: 8px;
1247
+ }
1248
+ .picker-field {
1249
+ display: flex;
1250
+ flex-direction: column;
1251
+ gap: 4px;
1252
+ }
1253
+ .picker-field-label {
1254
+ font-size: 11px;
1255
+ color: var(--ink-muted);
1256
+ font-weight: 500;
1257
+ }
1258
+ .picker-field .input {
1259
+ padding: 6px 10px;
1260
+ font-size: 12.5px;
1261
+ max-width: none;
1262
+ }
1263
+ .picker-create-actions {
1264
+ display: flex;
1265
+ justify-content: flex-end;
1266
+ gap: 6px;
1267
+ margin-top: 4px;
1268
+ }
1269
+
1270
+ /* --- Adopt (import existing CLI session) modal --------------------- */
1271
+ .adopt-tabs {
1272
+ display: flex;
1273
+ align-items: center;
1274
+ gap: 4px;
1275
+ border-bottom: 1px solid var(--border);
1276
+ padding-bottom: 8px;
1277
+ margin-bottom: 10px;
1278
+ }
1279
+ .adopt-tab {
1280
+ display: inline-flex;
1281
+ align-items: center;
1282
+ gap: 6px;
1283
+ padding: 6px 10px;
1284
+ border-radius: 8px;
1285
+ border: 1px solid transparent;
1286
+ background: transparent;
1287
+ font: inherit;
1288
+ color: var(--ink-mid);
1289
+ cursor: pointer;
1290
+ font-size: 12.5px;
1291
+ }
1292
+ .adopt-tab:hover { background: var(--bg); color: var(--ink); }
1293
+ .adopt-tab.is-active {
1294
+ background: var(--bg);
1295
+ border-color: var(--border);
1296
+ color: var(--ink);
1297
+ font-weight: 500;
1298
+ }
1299
+ .adopt-tab-icon { display: inline-flex; width: 16px; height: 16px; }
1300
+ .adopt-tab-icon svg { width: 100%; height: 100%; }
1301
+ .adopt-refresh { margin-left: auto; font-size: 11.5px; padding: 4px 10px; }
1302
+
1303
+ .adopt-body {
1304
+ min-height: 220px;
1305
+ max-height: 60vh;
1306
+ overflow: auto;
1307
+ }
1308
+ .adopt-empty {
1309
+ padding: 36px 12px;
1310
+ text-align: center;
1311
+ color: var(--ink-muted);
1312
+ font-size: 12.5px;
1313
+ }
1314
+ .adopt-error { color: var(--danger); }
1315
+
1316
+ .adopt-list {
1317
+ list-style: none;
1318
+ margin: 0;
1319
+ padding: 0;
1320
+ display: flex;
1321
+ flex-direction: column;
1322
+ gap: 4px;
1323
+ }
1324
+ .adopt-item {
1325
+ display: flex;
1326
+ align-items: center;
1327
+ gap: 12px;
1328
+ padding: 10px 12px;
1329
+ border: 1px solid var(--border);
1330
+ background: var(--bg-elev);
1331
+ border-radius: 10px;
1332
+ }
1333
+ .adopt-item.is-adopted { opacity: 0.55; }
1334
+ .adopt-main { flex: 1 1 auto; min-width: 0; }
1335
+ .adopt-title {
1336
+ font-size: 13px;
1337
+ color: var(--ink);
1338
+ font-weight: 500;
1339
+ overflow: hidden;
1340
+ text-overflow: ellipsis;
1341
+ white-space: nowrap;
1342
+ }
1343
+ .adopt-meta {
1344
+ font-size: 11px;
1345
+ color: var(--ink-muted);
1346
+ margin-top: 2px;
1347
+ overflow: hidden;
1348
+ text-overflow: ellipsis;
1349
+ white-space: nowrap;
1350
+ }
1351
+ .adopt-sep { margin: 0 6px; opacity: 0.5; }
1352
+ .adopt-actions {
1353
+ display: flex;
1354
+ align-items: center;
1355
+ gap: 6px;
1356
+ flex: 0 0 auto;
1357
+ }
1358
+ .adopt-cli-select {
1359
+ font: inherit;
1360
+ font-size: 11.5px;
1361
+ padding: 4px 6px;
1362
+ border-radius: 6px;
1363
+ border: 1px solid var(--border);
1364
+ background: var(--bg);
1365
+ color: var(--ink);
1366
+ }
1367
+ .adopt-btn { padding: 5px 12px; font-size: 11.5px; }
1368
+ .adopt-badge {
1369
+ font-size: 11px;
1370
+ color: var(--ink-muted);
1371
+ padding: 4px 10px;
1372
+ border-radius: 999px;
1373
+ background: var(--bg);
1374
+ border: 1px solid var(--border);
1375
+ }