openclacky 1.5.21 → 1.5.22

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +61 -0
  3. data/lib/clacky/billing/platform_billing.rb +3 -0
  4. data/lib/clacky/default_extensions/git/panels/git/view.js +1911 -398
  5. data/lib/clacky/default_extensions/preview/panels/preview/view.js +199 -34
  6. data/lib/clacky/providers.rb +43 -17
  7. data/lib/clacky/search_config.rb +33 -11
  8. data/lib/clacky/server/git_panel.rb +360 -34
  9. data/lib/clacky/server/http_server.rb +145 -47
  10. data/lib/clacky/server/preview.rb +118 -17
  11. data/lib/clacky/server/scheduler.rb +81 -2
  12. data/lib/clacky/server/web_ui_controller.rb +35 -27
  13. data/lib/clacky/session_manager.rb +52 -5
  14. data/lib/clacky/utils/mac_app_detector.rb +8 -7
  15. data/lib/clacky/utils/model_pricing.rb +60 -2
  16. data/lib/clacky/utils/windows_app_detector.rb +3 -1
  17. data/lib/clacky/version.rb +1 -1
  18. data/lib/clacky/web/app.css +650 -96
  19. data/lib/clacky/web/app.js +59 -6
  20. data/lib/clacky/web/auth.js +1 -1
  21. data/lib/clacky/web/components/composer.js +107 -8
  22. data/lib/clacky/web/components/image-zoom.js +165 -0
  23. data/lib/clacky/web/components/model-picker.js +6 -4
  24. data/lib/clacky/web/components/notify.js +2 -2
  25. data/lib/clacky/web/core/aside.js +60 -3
  26. data/lib/clacky/web/features/billing/view.js +2 -2
  27. data/lib/clacky/web/features/channels/view.js +5 -2
  28. data/lib/clacky/web/features/extensions/view.js +2 -2
  29. data/lib/clacky/web/features/new-session/store.js +79 -2
  30. data/lib/clacky/web/features/new-session/view.js +496 -58
  31. data/lib/clacky/web/features/skills/store.js +1 -1
  32. data/lib/clacky/web/features/tasks/view.js +162 -51
  33. data/lib/clacky/web/features/workspace/store.js +13 -6
  34. data/lib/clacky/web/features/workspace/view.js +153 -163
  35. data/lib/clacky/web/i18n.js +238 -56
  36. data/lib/clacky/web/index.html +173 -157
  37. data/lib/clacky/web/projects.js +37 -4
  38. data/lib/clacky/web/sessions.js +181 -105
  39. data/lib/clacky/web/settings.js +26 -8
  40. data/lib/clacky/web/skills.js +2 -2
  41. data/lib/clacky/web/theme.js +17 -2
  42. data/lib/clacky/web/utils.js +17 -2
  43. data/lib/clacky/web/weixin-qr.html +2 -1
  44. data/lib/clacky/web/ws-dispatcher.js +8 -29
  45. metadata +2 -1
@@ -466,6 +466,18 @@ input[type="checkbox"] { accent-color: var(--color-accent-primary); }
466
466
 
467
467
 
468
468
 
469
+ .theme-switching *,
470
+ .theme-switching *::before,
471
+ .theme-switching *::after {
472
+ transition: none !important;
473
+ }
474
+
475
+ ::view-transition-group(root),
476
+ ::view-transition-old(root),
477
+ ::view-transition-new(root) {
478
+ animation-duration: 600ms;
479
+ }
480
+
469
481
  body {
470
482
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
471
483
  background: var(--color-bg-primary);
@@ -1816,6 +1828,14 @@ body {
1816
1828
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 1rem), transparent);
1817
1829
  mask-image: linear-gradient(to right, #000 calc(100% - 1rem), transparent);
1818
1830
  }
1831
+ /* A sliding title needs a fade on its leading edge too, or the glyphs are
1832
+ guillotined at the viewport once they travel left. The class is added by JS
1833
+ only after the slide's 0.3s delay, so the first glyph is not dimmed while the
1834
+ text is still standing; a CSS-only swap would also linger on the way back. */
1835
+ .session-item.session-name-leading-fade:not(.group-item) .session-name .session-name__text {
1836
+ -webkit-mask-image: linear-gradient(to right, transparent, #000 1rem, #000 calc(100% - 1rem), transparent);
1837
+ mask-image: linear-gradient(to right, transparent, #000 1rem, #000 calc(100% - 1rem), transparent);
1838
+ }
1819
1839
  .session-name__content {
1820
1840
  display: inline-block;
1821
1841
  min-width: max-content;
@@ -2352,8 +2372,10 @@ body {
2352
2372
  display: flex;
2353
2373
  flex-direction: column;
2354
2374
  padding: 1.75rem 2.25rem;
2355
- gap: 1.25rem;
2356
2375
  }
2376
+ /* Spacing is per block rather than one flex gap: the tabs belong to their list
2377
+ more than to the header above them. */
2378
+ #task-detail-body > .task-page-header { margin-bottom: 1.25rem; }
2357
2379
 
2358
2380
  /* ── Task Page Header ───────────────────────────────────────────────────── */
2359
2381
  .task-page-header {
@@ -2466,8 +2488,8 @@ body {
2466
2488
  transition: color .15s, background .15s;
2467
2489
  }
2468
2490
  .page-tab:hover:not(.active) {
2469
- background: var(--color-bg-hover);
2470
- color: var(--color-text-primary);
2491
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, transparent);
2492
+ color: var(--color-accent-primary);
2471
2493
  }
2472
2494
  .page-tab.active { color: var(--color-accent-primary); }
2473
2495
  .page-tab.active::after {
@@ -2517,16 +2539,15 @@ body {
2517
2539
  .tasks-search:focus { border-color: var(--color-accent-primary); }
2518
2540
  .tasks-search::placeholder { color: var(--color-text-tertiary); }
2519
2541
 
2520
- /* ── Task rows ───────────────────────────────────────────────────────────── */
2542
+ /* ── Task rows (run history) ─────────────────────────────────────────────── */
2521
2543
  .task-section-label {
2522
2544
  display: flex;
2523
2545
  align-items: center;
2524
2546
  font-size: 0.75rem;
2525
2547
  font-weight: 500;
2526
2548
  color: var(--color-text-tertiary);
2527
- padding: 1.5rem 0.25rem 0.5rem;
2549
+ padding: 1rem 0.25rem 0.5rem;
2528
2550
  }
2529
- .task-section-label:first-child { padding-top: 0.375rem; }
2530
2551
  .cron-row {
2531
2552
  border-radius: 10px;
2532
2553
  background: var(--color-bg-secondary);
@@ -2557,32 +2578,7 @@ body {
2557
2578
  font-weight: 500;
2558
2579
  color: var(--color-text-primary);
2559
2580
  }
2560
- .cron-row-paused .cron-row-name,
2561
- .cron-row-paused .cron-row-cron { color: var(--color-text-tertiary); }
2562
- .cron-row-paused .cron-row-preview { color: var(--color-text-muted); }
2563
- .cron-row-preview {
2564
- flex: 0 1 auto;
2565
- max-width: 28rem;
2566
- min-width: 0;
2567
- overflow: hidden;
2568
- text-overflow: ellipsis;
2569
- white-space: nowrap;
2570
- color: var(--color-text-tertiary);
2571
- }
2572
- .cron-row-cron {
2573
- flex-shrink: 0;
2574
- white-space: nowrap;
2575
- color: var(--color-text-secondary);
2576
- }
2577
- .cron-row-cron-manual { color: var(--color-text-tertiary); }
2578
2581
  .cron-row-spacer { flex: 1; }
2579
- .task-section-empty {
2580
- padding: 0.75rem 0.875rem;
2581
- border: 1px dashed var(--color-border-primary);
2582
- border-radius: 8px;
2583
- font-size: 0.8125rem;
2584
- color: var(--color-text-tertiary);
2585
- }
2586
2582
  .cron-row-end {
2587
2583
  position: relative;
2588
2584
  display: flex;
@@ -2634,21 +2630,167 @@ body {
2634
2630
  background: color-mix(in srgb, var(--color-bg-hover) 92%, var(--color-text-primary));
2635
2631
  color: var(--color-text-secondary);
2636
2632
  }
2637
- .cron-row-detail { padding: 0 0.625rem 0.75rem; }
2638
- .task-card-detail-content {
2639
- padding: 0.75rem 1rem;
2640
- font-size: 0.8125rem;
2633
+
2634
+ /* ── Task filter bar ────────────────────────────────────────────────────── */
2635
+ /* Visuals come from the shared .segmented-control block; only the placement
2636
+ inside the scrolling list is task-specific. */
2637
+ #task-list-table > .segmented-control {
2638
+ align-self: flex-start;
2639
+ flex-shrink: 0;
2640
+ margin: 0.95rem 0 0.75rem;
2641
+ }
2642
+
2643
+ /* ── Task cards ──────────────────────────────────────────────────────────── */
2644
+ .task-card-grid {
2645
+ display: grid;
2646
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
2647
+ align-items: start;
2648
+ gap: 0.75rem;
2649
+ padding-bottom: 0.5rem;
2650
+ }
2651
+ .task-card {
2652
+ position: relative;
2653
+ display: flex;
2654
+ flex-direction: column;
2655
+ gap: 0.5rem;
2656
+ min-height: 8.75rem;
2657
+ padding: 1.125rem 1.25rem;
2658
+ border: 1px solid var(--color-border-primary);
2659
+ border-radius: var(--radius-lg);
2660
+ background: var(--color-bg-card);
2661
+ cursor: pointer;
2662
+ transition: border-color .15s, box-shadow .15s, background .15s;
2663
+ }
2664
+ /* Hover is a nudge, not a state change: full --color-bg-hover reads as pressed.
2665
+ Mix it down toward the card's resting fill. */
2666
+ .task-card:hover {
2667
+ background: color-mix(in srgb, var(--color-bg-hover) 55%, var(--color-bg-card));
2668
+ border-color: var(--color-border-secondary);
2669
+ }
2670
+ /* Paused cards recede: shell-toned fill, muted text. */
2671
+ .task-card.is-paused {
2672
+ background: var(--color-bg-primary);
2673
+ border-color: var(--color-border-secondary);
2674
+ }
2675
+ .task-card.is-paused:hover,
2676
+ .task-card.is-paused.is-menu-open {
2677
+ background: color-mix(in srgb, var(--color-bg-hover) 55%, var(--color-bg-primary));
2678
+ }
2679
+ .task-card-head {
2680
+ display: flex;
2681
+ align-items: center;
2682
+ gap: 0.75rem;
2683
+ min-height: 1.5rem;
2684
+ }
2685
+ .task-card-title {
2686
+ flex: 1;
2687
+ min-width: 0;
2688
+ margin: 0;
2689
+ font-size: 0.95rem;
2690
+ font-weight: 500;
2691
+ line-height: 1.35;
2692
+ color: var(--color-text-primary);
2693
+ overflow: hidden;
2694
+ text-overflow: ellipsis;
2695
+ white-space: nowrap;
2696
+ }
2697
+ .task-card.is-paused .task-card-title { color: var(--color-text-tertiary); }
2698
+ /* Actions sit in the header row, right of the title, and stay visible so the
2699
+ card is operable without a hover state (touch, keyboard, dark screens). */
2700
+ .task-card-actions {
2701
+ display: flex;
2702
+ align-items: center;
2703
+ gap: 0.5rem;
2704
+ flex-shrink: 0;
2705
+ }
2706
+ /* Hover-revealed: the row keeps its space (opacity, not display) so the title
2707
+ never reflows as the pointer enters. Touch devices show it outright. */
2708
+ .task-card-tools {
2709
+ display: flex;
2710
+ align-items: center;
2711
+ gap: 0.125rem;
2712
+ opacity: 0;
2713
+ pointer-events: none;
2714
+ transition: opacity .15s;
2715
+ }
2716
+ .task-card:hover .task-card-tools,
2717
+ .task-card:focus-within .task-card-tools,
2718
+ .task-card.is-menu-open .task-card-tools {
2719
+ opacity: 1;
2720
+ pointer-events: auto;
2721
+ }
2722
+ @media (hover: none) {
2723
+ .task-card-tools { opacity: 1; pointer-events: auto; }
2724
+ }
2725
+ .task-card-toggle { flex-shrink: 0; }
2726
+ .task-card-tool {
2727
+ display: flex;
2728
+ align-items: center;
2729
+ justify-content: center;
2730
+ width: 1.625rem;
2731
+ height: 1.625rem;
2732
+ padding: 0;
2733
+ border: none;
2734
+ border-radius: var(--radius-sm);
2735
+ background: transparent;
2641
2736
  color: var(--color-text-secondary);
2642
- line-height: 1.65;
2737
+ cursor: pointer;
2738
+ transition: background .15s, color .15s;
2739
+ }
2740
+ .task-card.is-paused .task-card-tool { color: var(--color-text-tertiary); }
2741
+ .task-card-tool:hover {
2742
+ background: var(--color-bg-hover);
2743
+ color: var(--color-text-primary);
2744
+ }
2745
+ .task-card-desc {
2746
+ margin: 0;
2747
+ font-size: 0.75rem;
2748
+ line-height: 1.7;
2749
+ color: var(--color-text-tertiary);
2750
+ display: -webkit-box;
2751
+ -webkit-line-clamp: 2;
2752
+ -webkit-box-orient: vertical;
2753
+ overflow: hidden;
2643
2754
  word-break: break-word;
2644
- max-height: 20rem;
2755
+ }
2756
+ .task-card.is-paused .task-card-desc { color: var(--color-text-muted); }
2757
+ .task-card-foot {
2758
+ display: flex;
2759
+ align-items: center;
2760
+ justify-content: space-between;
2761
+ gap: 0.5rem;
2762
+ margin-top: auto;
2763
+ padding-top: 0.75rem;
2764
+ border-top: 1px solid var(--color-border-secondary);
2765
+ font-size: 0.75rem;
2766
+ line-height: 1.4;
2767
+ color: var(--color-text-tertiary);
2768
+ }
2769
+ .task-card-sched {
2770
+ display: inline-flex;
2771
+ align-items: center;
2772
+ gap: 0.3125rem;
2773
+ min-width: 0;
2774
+ }
2775
+ .task-card-clock { flex-shrink: 0; opacity: 0.75; }
2776
+ .task-card-sched-text {
2777
+ overflow: hidden;
2778
+ text-overflow: ellipsis;
2779
+ white-space: nowrap;
2780
+ }
2781
+ .task-card-next { flex-shrink: 0; white-space: nowrap; }
2782
+ .task-card.is-paused .task-card-next { color: var(--color-text-muted); }
2783
+ /* ── Task detail modal (reuses shared .modal-box / .modal-body) ──────────── */
2784
+ .task-detail-modal {
2785
+ display: flex;
2786
+ flex-direction: column;
2787
+ max-height: min(80vh, 46rem);
2788
+ }
2789
+ .task-detail-modal .modal-body {
2790
+ flex: 1;
2791
+ min-height: 0;
2645
2792
  overflow-y: auto;
2646
- background: var(--color-bg-secondary);
2647
- border: 1px solid var(--color-border-primary);
2648
- border-radius: 6px;
2649
2793
  }
2650
- .task-card-detail-content > :first-child { margin-top: 0; }
2651
- .task-card-detail-content > :last-child { margin-bottom: 0; }
2652
2794
 
2653
2795
  /* ── Run history ─────────────────────────────────────────────────────────── */
2654
2796
  .task-run-row .cron-row-main { cursor: default; }
@@ -2969,10 +3111,9 @@ body {
2969
3111
  color: var(--color-accent-primary);
2970
3112
  background: var(--color-accent-soft);
2971
3113
  }
2972
- .new-session-composer-btn > span {
2973
- font-size: 0.875rem;
2974
- font-weight: 400;
2975
- line-height: 1;
3114
+ .new-session-composer-btn svg {
3115
+ width: 1.125rem;
3116
+ height: 1.125rem;
2976
3117
  }
2977
3118
  .new-session-textarea {
2978
3119
  flex: 1;
@@ -3140,6 +3281,10 @@ body {
3140
3281
  overflow: hidden;
3141
3282
  text-overflow: ellipsis;
3142
3283
  }
3284
+ /* `hidden` alone loses to the inline-flex above, and hiding must not leave a gap. */
3285
+ .ns-ctx-chip[hidden] {
3286
+ display: none;
3287
+ }
3143
3288
  .ns-ctx-chip:hover {
3144
3289
  color: var(--color-text-primary);
3145
3290
  background: var(--color-bg-hover);
@@ -3158,6 +3303,10 @@ body {
3158
3303
  flex-shrink: 0;
3159
3304
  opacity: 0.7;
3160
3305
  }
3306
+ /* Vendor badges bring their own colors, so they skip the 0.7 icon opacity. */
3307
+ .ns-ctx-chip-icon--badge {
3308
+ opacity: 1;
3309
+ }
3161
3310
  .ns-ctx-chip-label {
3162
3311
  overflow: hidden;
3163
3312
  text-overflow: ellipsis;
@@ -3225,6 +3374,193 @@ body {
3225
3374
  color: var(--color-text-tertiary);
3226
3375
  }
3227
3376
 
3377
+ /* Branch picker — search pinned on top, list scrolls, footer pinned below.
3378
+ Drops the popover's own padding/scroll so the three zones stay put while
3379
+ the branch list is long. */
3380
+ .ns-ctx-popover.ns-branch-pop {
3381
+ padding: 0;
3382
+ min-width: 15rem;
3383
+ max-width: 19rem;
3384
+ max-height: 20rem;
3385
+ overflow: hidden;
3386
+ }
3387
+ .ns-branch-search {
3388
+ display: flex;
3389
+ align-items: center;
3390
+ gap: 0.375rem;
3391
+ flex-shrink: 0;
3392
+ position: relative;
3393
+ padding: 0.75rem 0.625rem 0.5rem;
3394
+ color: var(--color-text-tertiary);
3395
+ }
3396
+ /* The divider is inset instead of full-bleed so it reads as part of the list
3397
+ rather than as an extra border hugging the popover frame. The search row has
3398
+ none: it sits right under the popover's own top edge. */
3399
+ .ns-branch-foot::before {
3400
+ content: "";
3401
+ position: absolute;
3402
+ left: 0.5rem;
3403
+ right: 0.5rem;
3404
+ height: 1px;
3405
+ background: var(--color-border-primary);
3406
+ }
3407
+ .ns-branch-search-input {
3408
+ flex: 1;
3409
+ min-width: 0;
3410
+ border: none;
3411
+ outline: none;
3412
+ background: transparent;
3413
+ color: var(--color-text-primary);
3414
+ font-size: 0.8125rem;
3415
+ font-family: inherit;
3416
+ }
3417
+ .ns-branch-search-input::placeholder {
3418
+ color: var(--color-text-tertiary);
3419
+ }
3420
+ .ns-branch-list {
3421
+ display: flex;
3422
+ flex-direction: column;
3423
+ gap: 1px;
3424
+ flex: 1;
3425
+ min-height: 0;
3426
+ padding: 0.25rem;
3427
+ overflow-y: auto;
3428
+ }
3429
+ /* Long branch lists must scroll, not squeeze: flex children shrink by default,
3430
+ which flattened every row to a few pixels once the list overflowed. */
3431
+ .ns-branch-list > * {
3432
+ flex-shrink: 0;
3433
+ }
3434
+ .ns-branch-list.is-busy {
3435
+ opacity: 0.55;
3436
+ pointer-events: none;
3437
+ }
3438
+ .ns-branch-group {
3439
+ padding: 0.375rem 0.625rem 0.1875rem;
3440
+ font-size: 0.6875rem;
3441
+ letter-spacing: 0.04em;
3442
+ text-transform: uppercase;
3443
+ color: var(--color-text-tertiary);
3444
+ }
3445
+ .ns-branch-item {
3446
+ display: flex;
3447
+ align-items: center;
3448
+ gap: 0.5rem;
3449
+ padding: 0.4375rem 0.625rem;
3450
+ }
3451
+ .ns-branch-item-icon,
3452
+ .ns-branch-item-check {
3453
+ display: flex;
3454
+ flex-shrink: 0;
3455
+ }
3456
+ .ns-branch-item-icon {
3457
+ opacity: 0.75;
3458
+ }
3459
+ .ns-branch-item-label {
3460
+ flex: 1;
3461
+ overflow: hidden;
3462
+ text-overflow: ellipsis;
3463
+ text-align: left;
3464
+ }
3465
+ .ns-branch-item.is-remote .ns-branch-item-label {
3466
+ opacity: 0.75;
3467
+ }
3468
+ .ns-branch-foot {
3469
+ position: relative;
3470
+ flex-shrink: 0;
3471
+ padding: 0.25rem;
3472
+ }
3473
+ .ns-branch-foot::before {
3474
+ top: 0;
3475
+ }
3476
+ .ns-branch-create {
3477
+ display: flex;
3478
+ align-items: center;
3479
+ gap: 0.5rem;
3480
+ width: 100%;
3481
+ }
3482
+ /* Create-branch modal */
3483
+ .ns-branch-field-head {
3484
+ display: flex;
3485
+ align-items: center;
3486
+ justify-content: space-between;
3487
+ gap: 0.5rem;
3488
+ }
3489
+ .ns-branch-prefix-btn {
3490
+ padding: 0;
3491
+ border: none;
3492
+ background: transparent;
3493
+ color: var(--color-accent-primary);
3494
+ font-size: 0.75rem;
3495
+ font-family: inherit;
3496
+ cursor: pointer;
3497
+ }
3498
+ .ns-branch-prefix-btn:hover {
3499
+ text-decoration: underline;
3500
+ }
3501
+ .ns-branch-prefix-btn:disabled {
3502
+ color: var(--color-text-muted);
3503
+ cursor: default;
3504
+ text-decoration: none;
3505
+ }
3506
+ .ns-branch-name-row {
3507
+ display: flex;
3508
+ align-items: center;
3509
+ gap: 0.125rem;
3510
+ padding: 0 0.75rem;
3511
+ border: 1px solid var(--color-border-primary);
3512
+ border-radius: var(--radius-sm);
3513
+ background: var(--color-bg-input);
3514
+ transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
3515
+ }
3516
+ .ns-branch-name-row:hover {
3517
+ border-color: var(--color-border-strong);
3518
+ }
3519
+ .ns-branch-name-row:focus-within {
3520
+ border-color: var(--color-accent-primary);
3521
+ box-shadow: 0 0 0 3px var(--color-accent-soft);
3522
+ }
3523
+ .ns-branch-name-row.is-invalid {
3524
+ border-color: var(--color-error);
3525
+ }
3526
+ .ns-branch-name-row .ns-branch-name-input {
3527
+ flex: 1;
3528
+ min-width: 0;
3529
+ padding: 0.5625rem 0;
3530
+ border: none;
3531
+ background: transparent;
3532
+ color: var(--color-text-primary);
3533
+ font-size: 0.8125rem;
3534
+ font-family: inherit;
3535
+ outline: none;
3536
+ box-shadow: none;
3537
+ }
3538
+ .ns-branch-name-row .ns-branch-name-input::placeholder {
3539
+ color: var(--color-text-muted);
3540
+ }
3541
+ .ns-branch-prefix-chip {
3542
+ flex-shrink: 0;
3543
+ padding: 0.125rem 0.375rem;
3544
+ border-radius: 0.25rem;
3545
+ background: var(--color-bg-hover);
3546
+ color: var(--color-text-tertiary);
3547
+ font-size: 0.75rem;
3548
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
3549
+ white-space: nowrap;
3550
+ }
3551
+ .ns-branch-prefix-chip[hidden] {
3552
+ display: none;
3553
+ }
3554
+ .ns-branch-modal-error {
3555
+ font-size: 0.75rem;
3556
+ line-height: 1.5;
3557
+ color: var(--color-error);
3558
+ word-break: break-word;
3559
+ }
3560
+ .ns-branch-modal-error[hidden] {
3561
+ display: none;
3562
+ }
3563
+
3228
3564
  /* Dir popover layout */
3229
3565
 
3230
3566
  .new-session-advanced {
@@ -3411,6 +3747,16 @@ body {
3411
3747
  }
3412
3748
  #chat-panel.aside-fullscreen .session-aside-resize { display: none; }
3413
3749
 
3750
+ /* Too narrow to split: the aside crossed the chat column's floor, so it takes
3751
+ the workspace and the resize handle moves inside the window edge to drag
3752
+ the split back. */
3753
+ #chat-panel.chat-collapsed #chat-main { display: none; }
3754
+ #chat-panel.chat-collapsed #session-aside {
3755
+ width: 100%;
3756
+ border-left: none;
3757
+ }
3758
+ #chat-panel.chat-collapsed .session-aside-resize { left: 0; }
3759
+
3414
3760
  .session-aside-slot { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
3415
3761
 
3416
3762
  /* Tab bar (rendered by Clacky.ext). Neutral edge fades reveal when more tabs
@@ -3661,6 +4007,41 @@ body {
3661
4007
  }
3662
4008
  .wt-error { color: var(--color-error); }
3663
4009
 
4010
+ /* A working dir can vanish under a session (deleted clone, renamed folder).
4011
+ Spell out the cause and offer the picker instead of a bare "load failed". */
4012
+ .wt-error-card {
4013
+ display: flex;
4014
+ flex-direction: column;
4015
+ gap: 0.375rem;
4016
+ margin: 0.5rem 0.375rem;
4017
+ padding: 0.75rem;
4018
+ border: 1px solid var(--color-border-primary);
4019
+ border-radius: var(--radius-sm);
4020
+ background: var(--color-bg-tertiary);
4021
+ }
4022
+ .wt-error-card-title {
4023
+ font-size: 0.75rem;
4024
+ font-weight: 600;
4025
+ color: var(--color-text-primary);
4026
+ }
4027
+ .wt-error-card-desc {
4028
+ font-size: 0.6875rem;
4029
+ line-height: 1.5;
4030
+ color: var(--color-text-secondary);
4031
+ }
4032
+ .wt-error-card-path {
4033
+ padding: 0.25rem 0.375rem;
4034
+ border-radius: var(--radius-xs);
4035
+ background: var(--color-bg-secondary);
4036
+ font-family: var(--font-mono);
4037
+ font-size: 0.6875rem;
4038
+ color: var(--color-text-muted);
4039
+ overflow: hidden;
4040
+ text-overflow: ellipsis;
4041
+ white-space: nowrap;
4042
+ }
4043
+ .wt-error-card-action { align-self: flex-start; }
4044
+
3664
4045
  /* ── Workspace viewer (file tree + tabbed preview, inside the Files tab) ── */
3665
4046
  .wv-root { flex: 1; min-height: 0; display: flex; }
3666
4047
  .wv-tree-pane {
@@ -5275,6 +5656,12 @@ body {
5275
5656
  transition-delay: 0.3s;
5276
5657
  transition-timing-function: linear;
5277
5658
  }
5659
+ /* Same leading fade as the session rows: without it the sliding text is cut
5660
+ flat at the left edge. Added by JS after the slide's 0.3s delay. */
5661
+ .todo-item.todo-text-leading-fade .todo-text {
5662
+ -webkit-mask-image: linear-gradient(to right, transparent, #000 1rem, #000 calc(100% - 1rem), transparent);
5663
+ mask-image: linear-gradient(to right, transparent, #000 1rem, #000 calc(100% - 1rem), transparent);
5664
+ }
5278
5665
 
5279
5666
  @media (prefers-reduced-motion: reduce) {
5280
5667
  .todo-trigger,
@@ -5646,6 +6033,8 @@ body {
5646
6033
  display: flex;
5647
6034
  align-items: center;
5648
6035
  justify-content: center;
6036
+ overflow: hidden;
6037
+ touch-action: none;
5649
6038
  cursor: zoom-out;
5650
6039
  animation: lb-fade-in 0.15s ease;
5651
6040
  }
@@ -5654,13 +6043,19 @@ body {
5654
6043
  to { opacity: 1; }
5655
6044
  }
5656
6045
  .img-lightbox img {
5657
- max-width: 90vw;
5658
- max-height: 90vh;
6046
+ flex: none;
6047
+ max-width: none;
6048
+ max-height: none;
5659
6049
  border-radius: 8px;
5660
6050
  object-fit: contain;
6051
+ transform-origin: center center;
6052
+ will-change: transform;
5661
6053
  box-shadow: 0 8px 40px rgba(0,0,0,0.6);
5662
- cursor: default;
6054
+ cursor: grab;
6055
+ user-select: none;
6056
+ -webkit-user-drag: none;
5663
6057
  }
6058
+ .img-lightbox.is-panning img { cursor: grabbing; }
5664
6059
  .img-lightbox-close {
5665
6060
  position: absolute;
5666
6061
  top: 1rem;
@@ -5671,8 +6066,53 @@ body {
5671
6066
  cursor: pointer;
5672
6067
  opacity: 0.8;
5673
6068
  user-select: none;
6069
+ z-index: 1;
5674
6070
  }
5675
6071
  .img-lightbox-close:hover { opacity: 1; }
6072
+ .img-lightbox-toolbar {
6073
+ position: absolute;
6074
+ left: 50%;
6075
+ bottom: 1rem;
6076
+ z-index: 1;
6077
+ display: flex;
6078
+ align-items: center;
6079
+ gap: 0.125rem;
6080
+ padding: 0.25rem;
6081
+ border: 1px solid rgba(255,255,255,0.18);
6082
+ border-radius: 9px;
6083
+ background: rgba(24,24,27,0.78);
6084
+ color: #fff;
6085
+ transform: translateX(-50%);
6086
+ backdrop-filter: blur(8px);
6087
+ }
6088
+ .img-lightbox-zoom-btn {
6089
+ width: 1.75rem;
6090
+ height: 1.75rem;
6091
+ padding: 0;
6092
+ border: none;
6093
+ border-radius: 6px;
6094
+ background: transparent;
6095
+ color: inherit;
6096
+ font-size: 1rem;
6097
+ line-height: 1;
6098
+ display: inline-flex;
6099
+ align-items: center;
6100
+ justify-content: center;
6101
+ cursor: pointer;
6102
+ }
6103
+ .img-lightbox-zoom-btn:hover { background: rgba(255,255,255,0.14); }
6104
+ .img-lightbox-zoom-btn:disabled {
6105
+ opacity: 0.35;
6106
+ cursor: default;
6107
+ background: transparent;
6108
+ }
6109
+ .img-lightbox-zoom-level {
6110
+ min-width: 2.75rem;
6111
+ text-align: center;
6112
+ color: rgba(255,255,255,0.82);
6113
+ font-size: 0.75rem;
6114
+ font-variant-numeric: tabular-nums;
6115
+ }
5676
6116
 
5677
6117
  .msg-pdf-badge {
5678
6118
  display: inline-flex;
@@ -5687,12 +6127,27 @@ body {
5687
6127
  min-width: 6.25rem;
5688
6128
  vertical-align: middle;
5689
6129
  }
6130
+ .msg-file-open {
6131
+ color: inherit;
6132
+ font: inherit;
6133
+ text-align: left;
6134
+ cursor: pointer;
6135
+ }
6136
+ .msg-file-open:hover {
6137
+ background: var(--color-bg-hover);
6138
+ border-color: var(--color-border-secondary);
6139
+ }
6140
+ .msg-file-open:focus-visible {
6141
+ outline: 2px solid var(--color-accent-primary);
6142
+ outline-offset: 2px;
6143
+ }
5690
6144
  .msg-pdf-badge-icon {
5691
6145
  display: flex;
5692
6146
  align-items: center;
5693
6147
  color: var(--color-text-secondary);
5694
6148
  flex-shrink: 0;
5695
6149
  }
6150
+ .msg-pdf-badge-icon svg { width: 20px; height: 20px; }
5696
6151
  .msg-pdf-badge-info {
5697
6152
  display: flex;
5698
6153
  flex-direction: column;
@@ -6620,7 +7075,7 @@ body {
6620
7075
  font-weight: 700;
6621
7076
  letter-spacing: 0.02em;
6622
7077
  line-height: 1;
6623
- color: #fff;
7078
+ color: var(--vendor-ink, #fff);
6624
7079
  background: var(--vendor-color, #7A8B99);
6625
7080
  border: 1px solid rgba(127, 127, 127, 0.25);
6626
7081
  user-select: none;
@@ -6794,8 +7249,9 @@ body {
6794
7249
  display: none;
6795
7250
  }
6796
7251
 
6797
- /* Page-level drop target for session references and file attachments. */
6798
- #chat-panel.drag-over,
7252
+ /* Drop target for session references and file attachments. Scoped to the
7253
+ chat column so the session aside never flashes a drop outline. */
7254
+ #chat-main.drag-over,
6799
7255
  #welcome.drag-over {
6800
7256
  outline: 2px dashed var(--color-accent-primary);
6801
7257
  outline-offset: -5px;
@@ -6861,12 +7317,42 @@ body {
6861
7317
  min-width: 7.5rem;
6862
7318
  box-sizing: border-box;
6863
7319
  }
7320
+ .pdf-preview-item--clickable {
7321
+ padding-left: 0;
7322
+ }
7323
+ .pdf-preview-item--clickable:hover {
7324
+ background: var(--color-bg-hover);
7325
+ }
7326
+ .pdf-preview-open {
7327
+ display: flex;
7328
+ align-items: center;
7329
+ gap: 0.5rem;
7330
+ width: 100%;
7331
+ height: 100%;
7332
+ min-width: 0;
7333
+ padding: 0 0 0 0.625rem;
7334
+ border: 0;
7335
+ border-radius: inherit;
7336
+ background: transparent;
7337
+ color: inherit;
7338
+ font: inherit;
7339
+ text-align: left;
7340
+ cursor: pointer;
7341
+ }
7342
+ .pdf-preview-open:hover {
7343
+ background: transparent;
7344
+ }
7345
+ .pdf-preview-open:focus-visible {
7346
+ outline: 2px solid var(--color-accent-primary);
7347
+ outline-offset: -2px;
7348
+ }
6864
7349
  .pdf-preview-icon {
6865
7350
  display: flex;
6866
7351
  align-items: center;
6867
7352
  color: var(--color-text-secondary);
6868
7353
  flex-shrink: 0;
6869
7354
  }
7355
+ .pdf-preview-icon svg { width: 24px; height: 24px; }
6870
7356
  .pdf-preview-info {
6871
7357
  display: flex;
6872
7358
  flex-direction: column;
@@ -6902,6 +7388,7 @@ body {
6902
7388
  text-align: center;
6903
7389
  cursor: pointer;
6904
7390
  padding: 0;
7391
+ z-index: 1;
6905
7392
  }
6906
7393
  .pdf-preview-remove:hover { background: var(--color-error); }
6907
7394
 
@@ -7197,12 +7684,11 @@ body {
7197
7684
  display: grid;
7198
7685
  place-items: center;
7199
7686
  border-radius: 8px;
7200
- font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
7201
7687
  transition: background .12s, color .12s;
7202
7688
  }
7203
- #btn-slash span {
7204
- font-size: 0.875rem;
7205
- font-weight: 400;
7689
+ #btn-slash svg {
7690
+ width: 1.125rem;
7691
+ height: 1.125rem;
7206
7692
  }
7207
7693
  #btn-slash:hover {
7208
7694
  color: var(--color-text-primary);
@@ -7761,9 +8247,9 @@ body {
7761
8247
  transition: background 0.15s, border-color 0.15s, color 0.15s;
7762
8248
  }
7763
8249
  .btn-backup-action:hover:not(:disabled) {
7764
- background: var(--color-bg-hover);
7765
- border-color: var(--color-text-muted);
7766
- color: var(--color-text-primary);
8250
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, transparent);
8251
+ border-color: var(--color-accent-primary);
8252
+ color: var(--color-accent-primary);
7767
8253
  }
7768
8254
  .btn-backup-action:disabled {
7769
8255
  opacity: 0.5;
@@ -8145,7 +8631,7 @@ body {
8145
8631
  transition: border-color 0.15s ease;
8146
8632
  }
8147
8633
  .custom-select-trigger:hover {
8148
- border-color: var(--color-text-muted);
8634
+ border-color: var(--color-accent-primary);
8149
8635
  }
8150
8636
  /* Focus: same accent border as `.open` so users see "this is where to start"
8151
8637
  without the dropdown auto-expanding. Used by onboard step 2 and the
@@ -8225,10 +8711,10 @@ body {
8225
8711
  text-overflow: ellipsis;
8226
8712
  }
8227
8713
  .custom-select-option:hover {
8228
- background: var(--color-bg-hover);
8714
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, transparent);
8229
8715
  }
8230
8716
  .custom-select-option.selected {
8231
- background: var(--color-bg-hover);
8717
+ background: color-mix(in srgb, var(--color-accent-primary) 12%, transparent);
8232
8718
  color: var(--color-accent-primary);
8233
8719
  }
8234
8720
  /* "Custom" entry lives in a fixed footer area outside the panel's own
@@ -8423,6 +8909,46 @@ body {
8423
8909
  gap: 0.375rem;
8424
8910
  min-height: 80px;
8425
8911
  }
8912
+ .model-card-grid-head {
8913
+ display: flex;
8914
+ align-items: center;
8915
+ gap: 0.75rem;
8916
+ min-width: 0;
8917
+ }
8918
+ .model-card-grid-head-text {
8919
+ flex: 1;
8920
+ min-width: 0;
8921
+ display: flex;
8922
+ flex-direction: column;
8923
+ gap: 0.125rem;
8924
+ }
8925
+ .model-card-grid-head > .btn-card-grid-action {
8926
+ align-self: flex-start;
8927
+ flex-shrink: 0;
8928
+ }
8929
+ /* Neutral tile so brand color lives in the mark, not in a loud swatch. */
8930
+ .model-card-grid-head .sib-vendor-badge {
8931
+ width: 2.5rem;
8932
+ height: 2.5rem;
8933
+ border-radius: 10px;
8934
+ font-size: 0.9375rem;
8935
+ font-weight: 600;
8936
+ background: var(--color-bg-primary);
8937
+ border: 1px solid var(--color-border-primary);
8938
+ color: var(--vendor-tint, var(--color-text-primary));
8939
+ }
8940
+ .model-card-grid-head .sib-vendor-badge:not(.is-brand):not(:has(svg)) {
8941
+ color: var(--color-text-tertiary);
8942
+ }
8943
+ .model-card-grid-head .sib-vendor-badge svg {
8944
+ width: 1.375rem;
8945
+ height: 1.375rem;
8946
+ }
8947
+ /* Some brand artwork (e.g. Kimi) has white shapes drawn for a dark tile. */
8948
+ .model-card-grid-head .sib-vendor-badge.is-brand:not(.is-light) {
8949
+ background: var(--vendor-color);
8950
+ border-color: transparent;
8951
+ }
8426
8952
  .model-card-grid-name-row {
8427
8953
  display: flex;
8428
8954
  align-items: center;
@@ -10802,7 +11328,7 @@ button:focus-visible { outline: 2px solid var(--color-accent-primary); outline-o
10802
11328
  .extension-row-name { display: flex; align-items: center; gap: 0.375rem; min-width: 0; }
10803
11329
  .extension-row-desc {
10804
11330
  font-size: 0.75rem;
10805
- color: var(--color-text-secondary);
11331
+ color: var(--color-text-tertiary);
10806
11332
  white-space: nowrap;
10807
11333
  overflow: hidden;
10808
11334
  text-overflow: ellipsis;
@@ -13987,17 +14513,10 @@ body.setup-mode {
13987
14513
  }
13988
14514
 
13989
14515
  .trash-tab-content {
13990
- flex: 1;
13991
- overflow-y: auto;
13992
- /* The list scrolls on its own so the toolbar above it stays put. Pulling the
13993
- box out into #trash-body's right padding leaves the cards where they are and
13994
- parks the scrollbar in that gutter instead of against the cards — the same
13995
- trick the tasks and skills lists use. */
13996
- margin-right: -2.25rem;
13997
- padding-right: 2.25rem;
13998
- /* #trash-body's section gap is meant for the stacked heading blocks above; the
13999
- toolbar and the list are one block, so halve it and let the strip sit exactly
14000
- one card-gap above the list instead of floating over a band of empty space. */
14516
+ /* #trash-scroll's gap is meant for the stacked heading blocks above; the
14517
+ toolbar and the list are one block, so halve it and let the strip sit
14518
+ exactly one card-gap above the list instead of floating over a band of
14519
+ empty space. */
14001
14520
  margin-top: -0.625rem;
14002
14521
  }
14003
14522
 
@@ -14102,9 +14621,9 @@ body.setup-mode {
14102
14621
  }
14103
14622
  .btn-trash-restore:hover:not(:disabled),
14104
14623
  .btn-trash-session-restore:hover:not(:disabled) {
14105
- background: var(--color-bg-hover, rgba(127,127,127,.08));
14106
- border-color: var(--color-text-muted);
14107
- color: var(--color-text-primary);
14624
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, transparent);
14625
+ border-color: var(--color-accent-primary);
14626
+ color: var(--color-accent-primary);
14108
14627
  }
14109
14628
  .btn-trash-delete:hover:not(:disabled),
14110
14629
  .btn-trash-session-delete:hover:not(:disabled) {
@@ -14148,7 +14667,10 @@ body.setup-mode {
14148
14667
  border-radius: 6px;
14149
14668
  }
14150
14669
  .trash-session-hint {
14151
- margin: -0.25rem 0;
14670
+ /* Only the bottom gap is tightened — the room under the pills comes from
14671
+ #trash-scroll's padding, which the files tab needs just as much. A negative
14672
+ top margin here would simply be clipped by the scroller. */
14673
+ margin: 0 0 -0.25rem;
14152
14674
  font-size: 0.75rem;
14153
14675
  color: var(--color-text-secondary);
14154
14676
  }
@@ -14181,9 +14703,9 @@ body.setup-mode {
14181
14703
  }
14182
14704
  .trash-filter-project-wrap:hover,
14183
14705
  .btn-trash-action:hover:not(:disabled) {
14184
- background: var(--color-bg-hover);
14185
- border-color: var(--color-text-muted);
14186
- color: var(--color-text-primary);
14706
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, transparent);
14707
+ border-color: var(--color-accent-primary);
14708
+ color: var(--color-accent-primary);
14187
14709
  }
14188
14710
  /* Project filter dropdown */
14189
14711
  .trash-filter-project-wrap {
@@ -14317,7 +14839,7 @@ body.setup-mode {
14317
14839
  #archive-body {
14318
14840
  flex: 1;
14319
14841
  overflow-y: auto;
14320
- padding: 1.75rem 2.25rem;
14842
+ padding: 1.25rem 2.25rem;
14321
14843
  display: flex;
14322
14844
  flex-direction: column;
14323
14845
  gap: 1.25rem;
@@ -14411,9 +14933,9 @@ body.setup-mode {
14411
14933
  transition: background 0.15s, border-color 0.15s, color 0.15s;
14412
14934
  }
14413
14935
  .btn-archive-unarchive:hover:not(:disabled) {
14414
- background: var(--color-bg-hover);
14415
- border-color: var(--color-text-muted);
14416
- color: var(--color-text-primary);
14936
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, transparent);
14937
+ border-color: var(--color-accent-primary);
14938
+ color: var(--color-accent-primary);
14417
14939
  }
14418
14940
  .btn-archive-delete {
14419
14941
  width: 1.75rem;
@@ -14483,7 +15005,7 @@ body.setup-mode {
14483
15005
  #backup-body {
14484
15006
  flex: 1;
14485
15007
  overflow-y: auto;
14486
- padding: 1.75rem 2.25rem;
15008
+ padding: 1.25rem 2.25rem;
14487
15009
  }
14488
15010
  #backup-content {
14489
15011
  max-width: 920px;
@@ -14501,8 +15023,24 @@ body.setup-mode {
14501
15023
  }
14502
15024
  #trash-body {
14503
15025
  flex: 1;
15026
+ min-height: 0;
15027
+ overflow: hidden;
15028
+ padding: 1.25rem 2.25rem;
15029
+ display: flex;
15030
+ flex-direction: column;
15031
+ }
15032
+ /* The hint, the toolbar and the list share one viewport, so the tab strip above
15033
+ stays put while the rest of the page moves. Pulling the box out into
15034
+ #trash-body's right padding parks the scrollbar in that gutter instead of
15035
+ against the cards — the same trick the tasks and skills lists use. */
15036
+ #trash-scroll {
15037
+ flex: 1;
15038
+ min-height: 0;
14504
15039
  overflow-y: auto;
14505
- padding: 1.75rem 2.25rem;
15040
+ margin-right: -2.25rem;
15041
+ /* The top padding is the breathing room under the pills; it lives here so
15042
+ both tabs get it, including the files tab whose first row is the toolbar. */
15043
+ padding: 0.5rem 2.25rem 0 0;
14506
15044
  display: flex;
14507
15045
  flex-direction: column;
14508
15046
  gap: 1.25rem;
@@ -14570,6 +15108,15 @@ body.setup-mode {
14570
15108
  background: color-mix(in srgb, var(--color-text-primary) 2%, var(--color-bg-hover));
14571
15109
  }
14572
15110
 
15111
+ /* Count badge for filter buttons — sits inside the button so label and count
15112
+ stay one hit area. */
15113
+ .segmented-control__count {
15114
+ margin-left: 0.25rem;
15115
+ font-size: 0.75rem;
15116
+ font-weight: 400;
15117
+ color: var(--color-text-tertiary);
15118
+ }
15119
+
14573
15120
  /* ═════════════════════════════════════════════════════════════════════════
14574
15121
  * BILLING PANEL
14575
15122
  * ═════════════════════════════════════════════════════════════════════════ */
@@ -14643,10 +15190,11 @@ body.setup-mode {
14643
15190
  }
14644
15191
  .billing-controls .segmented-control {
14645
15192
  flex: 0 0 auto;
15193
+ padding: 4px;
14646
15194
  }
14647
15195
  .billing-controls .segmented-control,
14648
15196
  .billing-model-filter {
14649
- height: 2rem;
15197
+ height: 2.25rem;
14650
15198
  }
14651
15199
 
14652
15200
  /* ── Disclaimer notice ──────────────────────────────────────────────── */
@@ -16588,6 +17136,10 @@ body.setup-mode {
16588
17136
  padding: 0px 12px 12px;
16589
17137
  }
16590
17138
 
17139
+ #input-queue {
17140
+ padding-inline: 12px;
17141
+ }
17142
+
16591
17143
  #skill-autocomplete {
16592
17144
  left: 12px;
16593
17145
  right: 12px;
@@ -16605,7 +17157,6 @@ body.setup-mode {
16605
17157
  }
16606
17158
  #btn-slash {
16607
17159
  padding: 0.25rem 0.375rem;
16608
- font-size: 0.875rem;
16609
17160
  }
16610
17161
 
16611
17162
  /* Textarea: prevent iOS auto-zoom (must be ≥1rem) */
@@ -16637,13 +17188,13 @@ body.setup-mode {
16637
17188
  }
16638
17189
  #task-detail-body {
16639
17190
  padding: 1rem 1rem 5rem;
16640
- gap: 0.75rem;
16641
17191
  overflow-y: auto;
16642
17192
  -webkit-overflow-scrolling: touch;
16643
17193
  overscroll-behavior: contain;
16644
17194
  flex: 1;
16645
17195
  min-height: 0;
16646
17196
  }
17197
+ #task-detail-body > .task-page-header { margin-bottom: 0.75rem; }
16647
17198
  /* btn-create-task: move below title instead of absolute top-right */
16648
17199
  .task-page-header {
16649
17200
  flex-direction: column;
@@ -16654,8 +17205,9 @@ body.setup-mode {
16654
17205
  align-self: flex-start;
16655
17206
  margin-top: 0.25rem;
16656
17207
  }
16657
- /* Task rows: drop the prompt preview and keep actions visible (no hover on touch) */
16658
- .cron-row-preview { display: none; }
17208
+ /* Task cards: the toolbar already lives in the header row, so only the
17209
+ touch target needs enlarging on narrow screens. */
17210
+ .task-card-tool { width: 2rem; height: 2rem; }
16659
17211
  .cron-row-end { gap: 0.5rem; }
16660
17212
  .cron-row-actions { position: static; transform: none; opacity: 1; pointer-events: auto; }
16661
17213
  .cron-row:hover .cron-row-meta { opacity: 1; }
@@ -16821,7 +17373,7 @@ body.setup-mode {
16821
17373
  /* ── Billing / Trash / Archive / Backup pages ── */
16822
17374
  #billing-body { padding: 1rem 1rem 1rem; }
16823
17375
  #trash-body { padding: 1rem 1rem 1rem; }
16824
- .trash-tab-content { margin-right: -1rem; padding-right: 1rem; }
17376
+ #trash-scroll { margin-right: -1rem; padding-right: 1rem; }
16825
17377
  #archive-body { padding: 1rem 1rem 1rem; }
16826
17378
  #backup-body { padding: 1rem 1rem 1rem; }
16827
17379
  #data-management-header { padding: 1rem 1rem 0; }
@@ -17261,8 +17813,9 @@ body.setup-mode {
17261
17813
  padding-left: 2.2rem;
17262
17814
  }
17263
17815
 
17816
+ /* Translucent so the drop-target frame and tint show through, like the session list. */
17264
17817
  .project-session-group .session-item.active {
17265
- background: var(--color-bg-hover);
17818
+ background: color-mix(in srgb, var(--color-text-primary) 5%, transparent);
17266
17819
  }
17267
17820
 
17268
17821
  .project-session-group .session-item.active::before {
@@ -17748,9 +18301,10 @@ body.setup-mode {
17748
18301
  #input-behavior-menu [aria-checked="true"] .input-behavior-check { visibility: visible; }
17749
18302
  @media (max-width: 768px) { #input-behavior-menu button { min-height: 56px; } }
17750
18303
 
17751
- /* Pending guidance: single-line previews and always-visible actions. */
18304
+ /* Pending guidance: single-line previews and always-visible actions.
18305
+ Sits between the message stream and the session info bar. */
17752
18306
  #input-queue[hidden] { display: none; }
17753
- #input-queue { max-height: 220px; overflow-y: auto; padding: 0 0 8px; }
18307
+ #input-queue { flex-shrink: 0; max-height: 220px; overflow-y: auto; padding: 6px 1.5rem 0; }
17754
18308
  .input-queue-row { display: flex; align-items: center; gap: 8px; margin-top: 4px; padding: 6px 10px; border: 1px solid var(--color-border-primary); border-radius: 10px; background: var(--color-bg-primary); }
17755
18309
  .input-queue-body { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
17756
18310
  .input-queue-status { flex-shrink: 0; white-space: nowrap; font-size: 11px; line-height: 1.5; color: var(--color-text-tertiary); }