openclacky 1.5.11 → 1.5.13

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -0
  3. data/lib/clacky/access_key.rb +59 -0
  4. data/lib/clacky/agent/cost_tracker.rb +2 -0
  5. data/lib/clacky/agent/message_compressor_helper.rb +53 -2
  6. data/lib/clacky/agent/session_serializer.rb +72 -19
  7. data/lib/clacky/agent/time_machine.rb +10 -1
  8. data/lib/clacky/agent.rb +107 -26
  9. data/lib/clacky/agent_config.rb +40 -0
  10. data/lib/clacky/agent_profile.rb +5 -5
  11. data/lib/clacky/billing/billing_record.rb +3 -0
  12. data/lib/clacky/billing/billing_store.rb +31 -5
  13. data/lib/clacky/billing/platform_billing.rb +231 -0
  14. data/lib/clacky/brand_config.rb +4 -3
  15. data/lib/clacky/cancel_flag.rb +23 -0
  16. data/lib/clacky/cli.rb +4 -2
  17. data/lib/clacky/client.rb +107 -0
  18. data/lib/clacky/default_extensions/advisor/advisors/general.md +23 -17
  19. data/lib/clacky/default_extensions/advisor/hooks/advisor.rb +104 -5
  20. data/lib/clacky/default_extensions/advisor/panels/advisor/view.js +92 -75
  21. data/lib/clacky/default_extensions/ext-studio/api/handler.rb +31 -0
  22. data/lib/clacky/default_extensions/ext-studio/panels/studio/view.js +74 -24
  23. data/lib/clacky/default_extensions/ext-studio/skills/ext-develop/SKILL.md +16 -37
  24. data/lib/clacky/default_extensions/git/ext.yml +1 -1
  25. data/lib/clacky/default_extensions/git/panels/git/view.js +483 -67
  26. data/lib/clacky/default_extensions/meeting/ext.yml +2 -1
  27. data/lib/clacky/default_extensions/time_machine/ext.yml +1 -1
  28. data/lib/clacky/default_extensions/time_machine/panels/time_machine/view.js +186 -208
  29. data/lib/clacky/extension/packager.rb +4 -2
  30. data/lib/clacky/extension/scaffold/templates/full/panels/dashboard/view.js.erb +2 -3
  31. data/lib/clacky/extension/verifier.rb +14 -1
  32. data/lib/clacky/fanout.rb +49 -2
  33. data/lib/clacky/json_ui_controller.rb +3 -2
  34. data/lib/clacky/message_format/open_ai.rb +5 -1
  35. data/lib/clacky/message_format/open_ai_responses.rb +409 -0
  36. data/lib/clacky/message_history.rb +43 -1
  37. data/lib/clacky/openai_responses_stream_aggregator.rb +294 -0
  38. data/lib/clacky/plain_ui_controller.rb +15 -5
  39. data/lib/clacky/providers.rb +24 -7
  40. data/lib/clacky/rich_ui/rich_ui_controller.rb +2 -2
  41. data/lib/clacky/server/channel/channel_manager.rb +93 -18
  42. data/lib/clacky/server/channel/channel_ui_controller.rb +16 -3
  43. data/lib/clacky/server/dir_picker.rb +154 -0
  44. data/lib/clacky/server/git_panel.rb +61 -9
  45. data/lib/clacky/server/http_server.rb +366 -42
  46. data/lib/clacky/server/web_ui_controller.rb +7 -5
  47. data/lib/clacky/session_manager.rb +74 -17
  48. data/lib/clacky/tools/ask_user.rb +3 -2
  49. data/lib/clacky/tools/terminal.rb +30 -3
  50. data/lib/clacky/ui2/markdown_renderer.rb +15 -12
  51. data/lib/clacky/ui2/strings_cjk_patch.rb +132 -0
  52. data/lib/clacky/ui2/themes/hacker_theme.rb +1 -1
  53. data/lib/clacky/ui2/themes/minimal_theme.rb +1 -1
  54. data/lib/clacky/ui2/ui_controller.rb +2 -2
  55. data/lib/clacky/ui_interface.rb +2 -2
  56. data/lib/clacky/utils/model_pricing.rb +92 -4
  57. data/lib/clacky/version.rb +1 -1
  58. data/lib/clacky/web/app.css +915 -142
  59. data/lib/clacky/web/components/code-editor.js +33 -1
  60. data/lib/clacky/web/components/composer.js +315 -0
  61. data/lib/clacky/web/components/custom-select.js +136 -0
  62. data/lib/clacky/web/components/mentions.js +655 -0
  63. data/lib/clacky/web/components/model-picker.js +527 -0
  64. data/lib/clacky/web/components/onboard.js +29 -55
  65. data/lib/clacky/web/core/aside.js +3 -3
  66. data/lib/clacky/web/core/ext.js +38 -0
  67. data/lib/clacky/web/features/billing/store.js +2 -6
  68. data/lib/clacky/web/features/billing/view.js +32 -16
  69. data/lib/clacky/web/features/extensions/view.js +22 -10
  70. data/lib/clacky/web/features/new-session/store.js +15 -1
  71. data/lib/clacky/web/features/new-session/view.js +80 -34
  72. data/lib/clacky/web/features/trash/view.js +31 -19
  73. data/lib/clacky/web/features/workspace/store.js +1 -0
  74. data/lib/clacky/web/features/workspace/view.js +766 -80
  75. data/lib/clacky/web/i18n.js +107 -17
  76. data/lib/clacky/web/index.html +125 -45
  77. data/lib/clacky/web/sessions.js +704 -635
  78. data/lib/clacky/web/settings.js +164 -190
  79. data/lib/clacky/web/skills.js +11 -17
  80. data/lib/clacky/web/ws-dispatcher.js +11 -33
  81. data/lib/clacky.rb +4 -0
  82. metadata +12 -1
@@ -802,7 +802,17 @@ body {
802
802
  #sidebar-list.is-scrolling::-webkit-scrollbar-thumb {
803
803
  background: var(--color-border-secondary);
804
804
  }
805
- #session-list { padding: 4px 0 0; min-height: 6.75rem; }
805
+
806
+ /* Windows/classic scrollbars occupy 4px of layout width. Keep them always
807
+ visible there instead of the show-on-scroll behaviour, so the occupied
808
+ gutter reads as an intentional scrollbar rather than empty space. */
809
+ .no-overlay-scrollbar #sidebar-list {
810
+ scrollbar-color: var(--color-border-secondary) transparent;
811
+ }
812
+ .no-overlay-scrollbar #sidebar-list::-webkit-scrollbar-thumb {
813
+ background: var(--color-border-secondary);
814
+ }
815
+ #session-list { padding: 4px 0 0; }
806
816
 
807
817
  /* ── Extension nav slots (top / mid / bottom) ───────────────────────────── */
808
818
  [id^="ext-slot-sidebar-nav"] { display: block; }
@@ -1260,15 +1270,8 @@ body {
1260
1270
  .search-select {
1261
1271
  flex: 0 0 5rem;
1262
1272
  min-width: 0;
1263
- padding: 0 2px 0 0.25rem;
1264
1273
  height: 100%;
1265
- font-size: 0.6875rem;
1266
- border: none;
1267
1274
  border-right: 1px solid var(--color-border-primary);
1268
- background: transparent;
1269
- color: var(--color-text-secondary);
1270
- outline: none;
1271
- cursor: pointer;
1272
1275
  }
1273
1276
 
1274
1277
  /* date wrapper: half width, position:relative for the icon overlay */
@@ -1308,7 +1311,6 @@ body {
1308
1311
  }
1309
1312
 
1310
1313
  /* Active filter highlight */
1311
- .search-select[data-active="true"],
1312
1314
  .search-date[data-active="true"] {
1313
1315
  color: var(--color-accent-primary);
1314
1316
  font-weight: 500;
@@ -1494,10 +1496,9 @@ body {
1494
1496
  /* ── Session empty placeholder ───────────────────────────────────────────── */
1495
1497
  .session-empty {
1496
1498
  margin: 0;
1497
- padding: 2rem 0.75rem;
1499
+ padding: 0.375rem 0.65rem;
1498
1500
  font-size: 0.75rem;
1499
1501
  color: var(--color-text-muted);
1500
- text-align: center;
1501
1502
  }
1502
1503
 
1503
1504
  /* ── Session List ────────────────────────────────────────────────────────── */
@@ -1766,6 +1767,9 @@ body {
1766
1767
  .session-actions-submenu-item:hover .session-actions-submenu-icon {
1767
1768
  color: var(--color-text-primary);
1768
1769
  }
1770
+ .session-actions-submenu-item.selected {
1771
+ background: var(--color-bg-hover);
1772
+ }
1769
1773
  .session-actions-submenu-divider {
1770
1774
  height: 1px;
1771
1775
  background: var(--color-border-secondary);
@@ -2517,8 +2521,17 @@ body {
2517
2521
  max-height: 12.5rem;
2518
2522
  overflow-y: auto;
2519
2523
  scrollbar-width: none;
2524
+ white-space: pre-wrap;
2525
+ overflow-wrap: break-word;
2526
+ word-break: break-word;
2527
+ min-height: calc(1.55em + 8px);
2520
2528
  }
2521
2529
  .new-session-textarea::-webkit-scrollbar { display: none; }
2530
+ .new-session-textarea:empty::before {
2531
+ content: attr(data-placeholder);
2532
+ color: var(--color-text-tertiary);
2533
+ pointer-events: none;
2534
+ }
2522
2535
  .new-session-advanced-wrap {
2523
2536
  display: flex;
2524
2537
  flex-direction: column;
@@ -2948,56 +2961,129 @@ body {
2948
2961
  flex: none;
2949
2962
  display: flex;
2950
2963
  align-items: center;
2951
- justify-content: space-between;
2952
- gap: 8px;
2953
- padding: 8px 12px;
2964
+ gap: 6px;
2965
+ padding: 6px 8px;
2954
2966
  border-bottom: 1px solid var(--color-border-secondary);
2955
2967
  }
2956
- .wt-bar-hint { font-size: 11px; color: var(--color-text-tertiary); }
2957
- .wt-bar-btn {
2958
- flex: none;
2959
- padding: 3px 10px;
2968
+ .wt-search {
2969
+ flex: 1;
2970
+ min-width: 0;
2971
+ display: flex;
2972
+ align-items: center;
2973
+ gap: 6px;
2974
+ height: 26px;
2975
+ padding: 0 4px 0 8px;
2976
+ background: var(--color-bg-primary);
2960
2977
  border: 1px solid var(--color-border-primary);
2961
2978
  border-radius: var(--radius-sm);
2962
- background: var(--color-bg-secondary);
2979
+ transition: border-color var(--transition-base);
2980
+ }
2981
+ .wt-search:focus-within { border-color: var(--color-accent-primary); }
2982
+ .wt-search-icon { display: inline-flex; color: var(--color-text-muted); flex-shrink: 0; }
2983
+ .wt-search-input {
2984
+ flex: 1;
2985
+ min-width: 0;
2986
+ border: none;
2987
+ outline: none;
2988
+ background: transparent;
2989
+ font-size: 12px;
2990
+ color: var(--color-text-primary);
2991
+ padding: 0;
2992
+ }
2993
+ .wt-search-input::placeholder { color: var(--color-text-muted); }
2994
+ .wt-search-clear {
2995
+ flex: none;
2996
+ display: none;
2997
+ align-items: center;
2998
+ justify-content: center;
2999
+ width: 18px;
3000
+ height: 18px;
3001
+ padding: 0;
3002
+ border: none;
3003
+ border-radius: var(--radius-xs);
3004
+ background: transparent;
3005
+ color: var(--color-text-muted);
3006
+ cursor: pointer;
3007
+ }
3008
+ .wt-search-clear:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }
3009
+ .wt-search-list {
3010
+ flex: 1;
3011
+ overflow-y: auto;
3012
+ padding: 4px 6px 8px;
3013
+ font-size: 0.8125rem;
3014
+ }
3015
+ .wt-search-row { gap: 6px; }
3016
+ .wt-search-dir {
3017
+ margin-left: auto;
3018
+ padding-left: 0.5rem;
3019
+ font-size: 0.6875rem;
3020
+ color: var(--color-text-muted);
3021
+ overflow: hidden;
3022
+ text-overflow: ellipsis;
3023
+ white-space: nowrap;
3024
+ flex-shrink: 1;
3025
+ }
3026
+ .wt-mark {
3027
+ background: var(--color-accent-soft);
3028
+ color: inherit;
3029
+ border-radius: 2px;
3030
+ padding: 0 1px;
3031
+ }
3032
+ .wt-bar-btn {
3033
+ flex: none;
3034
+ display: inline-flex;
3035
+ align-items: center;
3036
+ justify-content: center;
3037
+ width: 24px;
3038
+ height: 24px;
3039
+ padding: 0;
3040
+ border: none;
3041
+ border-radius: var(--radius-xs);
3042
+ background: transparent;
2963
3043
  color: var(--color-text-secondary);
2964
- font-size: 11px;
2965
3044
  cursor: pointer;
2966
3045
  }
2967
- .wt-bar-btn:hover { background: var(--color-bg-hover); }
3046
+ .wt-bar-btn:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }
2968
3047
  .wt-tree {
2969
3048
  flex: 1;
2970
3049
  overflow-y: auto;
2971
- padding: 6px 8px;
3050
+ padding: 4px 6px 8px;
2972
3051
  font-size: 0.8125rem;
2973
- font-family: var(--font-mono);
2974
3052
  }
2975
3053
  .wt-node { user-select: none; }
2976
3054
  .wt-row {
2977
3055
  display: flex;
2978
3056
  align-items: center;
2979
- gap: 0.25rem;
2980
- padding: 0.1875rem 0.375rem;
2981
- border-radius: var(--radius-sm);
3057
+ gap: 5px;
3058
+ height: 24px;
3059
+ padding: 0 8px 0 5px;
3060
+ border-radius: var(--radius-xs);
2982
3061
  cursor: pointer;
2983
3062
  color: var(--color-text-primary);
2984
3063
  white-space: nowrap;
2985
3064
  overflow: hidden;
2986
3065
  }
2987
3066
  .wt-row:hover { background: var(--color-bg-hover); }
3067
+ .wt-row.active { background: var(--color-accent-soft); }
2988
3068
  .wt-caret {
2989
3069
  display: inline-flex;
2990
- width: 0.875rem;
3070
+ width: 0.75rem;
2991
3071
  flex-shrink: 0;
2992
- color: var(--color-text-secondary);
3072
+ color: var(--color-text-muted);
2993
3073
  transition: transform var(--transition-base);
2994
3074
  }
2995
3075
  .wt-caret.open { transform: rotate(90deg); }
2996
3076
  .wt-caret.leaf { visibility: hidden; }
2997
3077
  .wt-icon { display: inline-flex; flex-shrink: 0; color: var(--color-text-secondary); }
3078
+ .wt-icon svg { display: block; }
2998
3079
  .wt-name { overflow: hidden; text-overflow: ellipsis; }
2999
- .wt-size { margin-left: auto; padding-left: 0.5rem; font-size: 0.6875rem; color: var(--color-text-tertiary, var(--color-text-secondary)); flex-shrink: 0; }
3000
- .wt-children { margin-left: 0.75rem; }
3080
+ .wt-size { margin-left: auto; padding-left: 0.5rem; font-size: 0.6875rem; color: var(--color-text-muted); opacity: 0; transition: opacity var(--transition-base); flex-shrink: 0; }
3081
+ .wt-row:hover .wt-size, .wt-row.active .wt-size { opacity: 1; }
3082
+ .wt-children {
3083
+ margin-left: 11px;
3084
+ border-left: 1px solid transparent;
3085
+ }
3086
+ .wt-children.guide-on { border-left-color: color-mix(in srgb, var(--color-text-primary) 20%, transparent); }
3001
3087
  .wt-empty, .wt-loading, .wt-error {
3002
3088
  padding: 0.375rem 0.625rem;
3003
3089
  font-size: 0.75rem;
@@ -3005,6 +3091,147 @@ body {
3005
3091
  }
3006
3092
  .wt-error { color: var(--color-danger, #d23); }
3007
3093
 
3094
+ /* ── Workspace viewer (file tree + tabbed preview, inside the Files tab) ── */
3095
+ .wv-root { flex: 1; min-height: 0; display: flex; }
3096
+ .wv-tree-pane {
3097
+ flex: 0 0 auto;
3098
+ width: var(--wv-tree-width, 38%);
3099
+ min-width: 168px;
3100
+ max-width: 460px;
3101
+ display: flex;
3102
+ flex-direction: column;
3103
+ min-height: 0;
3104
+ }
3105
+ .wv-tree-resize {
3106
+ flex: none;
3107
+ width: 6px;
3108
+ cursor: col-resize;
3109
+ position: relative;
3110
+ z-index: 2;
3111
+ background: transparent;
3112
+ display: none;
3113
+ }
3114
+ .wv-root.has-open-files .wv-tree-resize { display: block; }
3115
+ .wv-tree-resize::after {
3116
+ content: "";
3117
+ position: absolute;
3118
+ top: 0;
3119
+ bottom: 0;
3120
+ left: 2px;
3121
+ width: 1px;
3122
+ background: var(--color-border-primary);
3123
+ }
3124
+ .wv-viewer { flex: 1; min-width: 0; display: none; flex-direction: column; min-height: 0; }
3125
+ .wv-root.has-open-files .wv-viewer { display: flex; }
3126
+ .wv-root:not(.has-open-files) .wv-tree-pane { flex: 1 1 auto; max-width: none; }
3127
+
3128
+ .wv-tabbar {
3129
+ flex: none;
3130
+ display: flex;
3131
+ align-items: center;
3132
+ gap: 6px;
3133
+ padding: 4px 6px 4px 8px;
3134
+ border-bottom: 1px solid var(--color-border-secondary);
3135
+ }
3136
+ .wv-tabs {
3137
+ flex: 1;
3138
+ min-width: 0;
3139
+ display: flex;
3140
+ align-items: center;
3141
+ gap: 2px;
3142
+ overflow-x: auto;
3143
+ scrollbar-width: none;
3144
+ }
3145
+ .wv-tabs::-webkit-scrollbar { display: none; }
3146
+ .wv-tab {
3147
+ flex: none;
3148
+ display: inline-flex;
3149
+ align-items: center;
3150
+ gap: 4px;
3151
+ max-width: 150px;
3152
+ padding: 3px 4px 3px 9px;
3153
+ border: 1px solid transparent;
3154
+ border-radius: var(--radius-sm);
3155
+ background: none;
3156
+ font-size: 12px;
3157
+ color: var(--color-text-tertiary);
3158
+ cursor: pointer;
3159
+ white-space: nowrap;
3160
+ }
3161
+ .wv-tab:hover { color: var(--color-text-secondary); background: var(--color-bg-hover); }
3162
+ .wv-tab.active {
3163
+ color: var(--color-text-primary);
3164
+ background: var(--color-bg-hover);
3165
+ border-color: var(--color-border-secondary);
3166
+ font-weight: 500;
3167
+ }
3168
+ .wv-tab-label { overflow: hidden; text-overflow: ellipsis; }
3169
+ .wv-tab-dot {
3170
+ flex: none;
3171
+ width: 6px;
3172
+ height: 6px;
3173
+ border-radius: 50%;
3174
+ background: var(--color-accent-primary);
3175
+ }
3176
+ .wv-tab-close {
3177
+ display: inline-flex;
3178
+ align-items: center;
3179
+ justify-content: center;
3180
+ width: 16px;
3181
+ height: 16px;
3182
+ border-radius: 4px;
3183
+ color: var(--color-text-tertiary);
3184
+ cursor: pointer;
3185
+ }
3186
+ .wv-tab-close:hover { background: var(--color-border-primary); color: var(--color-text-primary); }
3187
+
3188
+ .wv-actions { flex: none; display: flex; align-items: center; gap: 2px; }
3189
+ .wv-action {
3190
+ display: inline-flex;
3191
+ align-items: center;
3192
+ justify-content: center;
3193
+ width: 26px;
3194
+ height: 26px;
3195
+ border: none;
3196
+ border-radius: var(--radius-sm);
3197
+ background: none;
3198
+ color: var(--color-text-tertiary);
3199
+ cursor: pointer;
3200
+ }
3201
+ .wv-action:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }
3202
+ .wv-action.active { background: var(--color-bg-hover); color: var(--color-accent-primary); }
3203
+ .wv-action.dirty { color: var(--color-accent-primary); }
3204
+
3205
+ .wv-content { flex: 1; min-height: 0; position: relative; }
3206
+ .wv-pane { position: absolute; inset: 0; display: none; }
3207
+ .wv-pane.active { display: flex; }
3208
+ .wv-pane--text { flex-direction: column; }
3209
+ .wv-pane[data-mode="edit"] .wv-md-preview { display: none; }
3210
+ .wv-pane[data-mode="preview"] .wv-code { display: none; }
3211
+ .wv-code { flex: 1; min-height: 0; overflow: hidden; }
3212
+ .wv-code .cm-editor {
3213
+ height: 100%;
3214
+ font-size: 0.8125rem;
3215
+ line-height: 1.6;
3216
+ background: transparent;
3217
+ }
3218
+ .wv-code .cm-editor .cm-content { background: transparent; }
3219
+ .wv-code .cm-editor.cm-focused { outline: none; }
3220
+ .wv-code .cm-scroller { overflow: auto; font-family: var(--font-mono, 'SF Mono', 'Fira Code', monospace); }
3221
+ .wv-code .cm-gutters {
3222
+ background: transparent;
3223
+ border-right: 1px solid var(--color-border-primary);
3224
+ color: var(--color-text-tertiary);
3225
+ }
3226
+ .wv-code .cm-activeLineGutter { background: var(--color-bg-hover); }
3227
+ .wv-pane--image {
3228
+ align-items: center;
3229
+ justify-content: center;
3230
+ background: var(--color-bg-primary);
3231
+ }
3232
+ .wv-pane--image img { max-width: 100%; max-height: 100%; object-fit: contain; }
3233
+
3234
+
3008
3235
  /* Mobile-only floating back button — replaces the old in-header back button.
3009
3236
  Hidden on desktop; mobile media query enables it. Positioned absolutely so
3010
3237
  it doesn't take layout space or add visual chrome on desktop. */
@@ -4655,7 +4882,7 @@ body {
4655
4882
  position: fixed;
4656
4883
  /* Position will be calculated dynamically via JavaScript */
4657
4884
  min-width: 12.5rem;
4658
- max-width: min(17.5rem, calc(100vw - 1.5rem));
4885
+ max-width: min(20rem, calc(100vw - 1.5rem));
4659
4886
  background: var(--color-bg-secondary);
4660
4887
  border: 1px solid var(--color-border-primary);
4661
4888
  border-radius: 8px;
@@ -4714,25 +4941,33 @@ body {
4714
4941
 
4715
4942
  .sib-submodel-toggle {
4716
4943
  margin-left: 0.375rem;
4717
- width: 1.125rem;
4718
- height: 1.125rem;
4944
+ width: 1.25rem;
4945
+ height: 1.25rem;
4719
4946
  padding: 0;
4720
- border: none;
4721
- border-radius: 4px;
4722
- background: transparent;
4947
+ border: 1px solid var(--color-border-primary);
4948
+ border-radius: 5px;
4949
+ background: var(--color-bg-primary);
4723
4950
  color: var(--color-text-secondary);
4724
4951
  cursor: pointer;
4725
4952
  display: inline-flex;
4726
4953
  align-items: center;
4727
4954
  justify-content: center;
4728
- transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
4955
+ transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
4729
4956
  }
4730
4957
  .sib-submodel-toggle:hover {
4731
4958
  background: color-mix(in srgb, var(--color-accent-primary) 15%, transparent);
4959
+ border-color: color-mix(in srgb, var(--color-accent-primary) 45%, transparent);
4732
4960
  color: var(--color-accent-primary);
4733
4961
  }
4734
4962
  .sib-submodel-toggle[aria-expanded="true"] {
4735
4963
  background: color-mix(in srgb, var(--color-accent-primary) 18%, transparent);
4964
+ border-color: color-mix(in srgb, var(--color-accent-primary) 50%, transparent);
4965
+ color: var(--color-accent-primary);
4966
+ }
4967
+ /* Keep the chevron visible when its row is hovered or selected. */
4968
+ .sib-model-option:hover .sib-submodel-toggle,
4969
+ .sib-model-option.current .sib-submodel-toggle {
4970
+ border-color: color-mix(in srgb, var(--color-accent-primary) 45%, transparent);
4736
4971
  color: var(--color-accent-primary);
4737
4972
  }
4738
4973
  .sib-submodel-toggle[aria-expanded="true"] svg {
@@ -4748,8 +4983,8 @@ body {
4748
4983
 
4749
4984
  .sib-submodel-panel {
4750
4985
  position: fixed;
4751
- min-width: 11rem;
4752
- max-width: 16rem;
4986
+ min-width: 12rem;
4987
+ max-width: 18rem;
4753
4988
  background: var(--color-bg-secondary);
4754
4989
  border: 1px solid var(--color-border-primary);
4755
4990
  border-radius: 8px;
@@ -4760,6 +4995,9 @@ body {
4760
4995
  padding: 0.25rem 0;
4761
4996
  }
4762
4997
  .sib-submodel-panel-header {
4998
+ display: flex;
4999
+ align-items: baseline;
5000
+ gap: 0.375rem;
4763
5001
  padding: 0.375rem 0.875rem 0.4375rem;
4764
5002
  font-size: 0.625rem;
4765
5003
  text-transform: uppercase;
@@ -4768,6 +5006,17 @@ body {
4768
5006
  border-bottom: 1px solid var(--color-border-primary);
4769
5007
  margin-bottom: 0.25rem;
4770
5008
  }
5009
+ .sib-submodel-panel-model {
5010
+ font-family: var(--font-mono, monospace);
5011
+ font-size: 0.625rem;
5012
+ text-transform: none;
5013
+ letter-spacing: 0;
5014
+ color: var(--color-text-tertiary);
5015
+ overflow: hidden;
5016
+ text-overflow: ellipsis;
5017
+ white-space: nowrap;
5018
+ min-width: 0;
5019
+ }
4771
5020
  .sib-submodel-row {
4772
5021
  padding: 0.5rem 0.875rem;
4773
5022
  font-size: 0.7rem;
@@ -4790,6 +5039,13 @@ body {
4790
5039
  color: var(--color-accent-primary);
4791
5040
  }
4792
5041
  .sib-submodel-row-name {
5042
+ display: inline-flex;
5043
+ align-items: center;
5044
+ gap: 0.375rem;
5045
+ overflow: hidden;
5046
+ min-width: 0;
5047
+ }
5048
+ .sib-submodel-row-text {
4793
5049
  overflow: hidden;
4794
5050
  text-overflow: ellipsis;
4795
5051
  white-space: nowrap;
@@ -4857,7 +5113,6 @@ body {
4857
5113
  display: inline-flex;
4858
5114
  align-items: center;
4859
5115
  flex: 0 0 auto;
4860
- margin-left: 0.375rem;
4861
5116
  padding: 1px 0.375rem;
4862
5117
  font-size: 0.5625rem;
4863
5118
  line-height: 1.4;
@@ -4953,15 +5208,58 @@ body {
4953
5208
  .sib-model-option .sib-model-name.has-sub {
4954
5209
  flex-direction: column;
4955
5210
  align-items: flex-start;
4956
- gap: 0.125rem;
5211
+ gap: 0.325rem;
4957
5212
  }
4958
5213
  .sib-model-option .sib-model-name-main {
5214
+ display: inline-flex;
5215
+ align-items: center;
5216
+ gap: 0.375rem;
5217
+ overflow: hidden;
5218
+ flex: 0 1 auto;
5219
+ min-width: 0;
5220
+ }
5221
+ .sib-model-option .sib-model-name-text {
4959
5222
  overflow: hidden;
4960
5223
  text-overflow: ellipsis;
4961
5224
  white-space: nowrap;
4962
- flex: 0 1 auto;
4963
5225
  min-width: 0;
4964
5226
  }
5227
+ .sib-model-option.current .sib-model-name-text {
5228
+ color: var(--color-accent-primary);
5229
+ }
5230
+ .sib-model-check {
5231
+ display: inline-flex;
5232
+ align-items: center;
5233
+ flex: 0 0 auto;
5234
+ color: var(--color-success, #2da44e);
5235
+ }
5236
+
5237
+ /* Brand-colored tile (provider initial) shown before each model name.
5238
+ Solid brand color + white letter stays legible in both light and dark
5239
+ themes; the neutral hairline keeps dark tiles from melting into the bg. */
5240
+ .sib-vendor-badge {
5241
+ flex: 0 0 auto;
5242
+ width: 1.125rem;
5243
+ height: 1.125rem;
5244
+ border-radius: 5px;
5245
+ display: inline-flex;
5246
+ align-items: center;
5247
+ justify-content: center;
5248
+ font-size: 0.5625rem;
5249
+ font-weight: 700;
5250
+ letter-spacing: 0.02em;
5251
+ line-height: 1;
5252
+ color: #fff;
5253
+ background: var(--vendor-color, #7A8B99);
5254
+ border: 1px solid rgba(127, 127, 127, 0.25);
5255
+ user-select: none;
5256
+ }
5257
+ .sib-vendor-badge svg {
5258
+ width: 0.6875rem;
5259
+ height: 0.6875rem;
5260
+ fill: currentColor;
5261
+ display: block;
5262
+ }
4965
5263
  .sib-model-option .sib-model-name-sub {
4966
5264
  font-size: 0.6875rem;
4967
5265
  color: var(--color-text-secondary);
@@ -5485,6 +5783,193 @@ body {
5485
5783
  background: var(--color-accent-soft);
5486
5784
  }
5487
5785
 
5786
+ /* ── @ mention menu (Files & Folders / Past Chats) ────────────────────── */
5787
+ .mention-autocomplete {
5788
+ position: absolute;
5789
+ bottom: 100%;
5790
+ left: 24px;
5791
+ right: 24px;
5792
+ background: var(--color-bg-primary);
5793
+ border: 1px solid var(--color-border-primary);
5794
+ border-radius: 13px;
5795
+ box-shadow: var(--shadow-card);
5796
+ margin-bottom: 8px;
5797
+ max-height: 18.75rem;
5798
+ z-index: 1000;
5799
+ display: flex;
5800
+ flex-direction: column;
5801
+ gap: 0.125rem;
5802
+ padding: 0.375rem;
5803
+ }
5804
+ #ns-mention-autocomplete {
5805
+ bottom: calc(100% - 3rem);
5806
+ }
5807
+ .mention-list {
5808
+ display: flex;
5809
+ flex-direction: column;
5810
+ gap: 0.125rem;
5811
+ overflow-y: auto;
5812
+ flex: 1 1 auto;
5813
+ min-height: 0;
5814
+ position: relative;
5815
+ margin-right: -0.375rem;
5816
+ padding-right: 0.375rem;
5817
+ }
5818
+ .mention-header {
5819
+ flex-shrink: 0;
5820
+ display: flex;
5821
+ align-items: center;
5822
+ gap: 0.5rem;
5823
+ padding: 0.25rem 0.375rem 0.5rem;
5824
+ margin-bottom: 0.125rem;
5825
+ border-bottom: 1px solid var(--color-border-secondary);
5826
+ }
5827
+ .mention-back {
5828
+ display: inline-flex;
5829
+ align-items: center;
5830
+ gap: 0.25rem;
5831
+ border: none;
5832
+ background: transparent;
5833
+ color: var(--color-text-secondary);
5834
+ font-size: 0.75rem;
5835
+ cursor: pointer;
5836
+ padding: 0.175rem 0.375rem;
5837
+ border-radius: 0.375rem;
5838
+ }
5839
+ .mention-back:hover {
5840
+ color: var(--color-text-primary);
5841
+ background: var(--color-bg-hover);
5842
+ }
5843
+ .mention-title {
5844
+ font-size: 0.6875rem;
5845
+ color: var(--color-text-tertiary);
5846
+ font-weight: 500;
5847
+ overflow: hidden;
5848
+ text-overflow: ellipsis;
5849
+ white-space: nowrap;
5850
+ }
5851
+ .mention-item {
5852
+ display: flex;
5853
+ align-items: center;
5854
+ gap: 0.625rem;
5855
+ padding: 0.5rem 0.625rem;
5856
+ cursor: pointer;
5857
+ border-radius: 0.5rem;
5858
+ transition: background 0.1s;
5859
+ user-select: none;
5860
+ }
5861
+ .mention-item.active {
5862
+ background: color-mix(in srgb, var(--color-text-primary) 8%, transparent);
5863
+ }
5864
+ .mention-item-main {
5865
+ display: flex;
5866
+ align-items: center;
5867
+ gap: 0.625rem;
5868
+ flex: 1;
5869
+ min-width: 0;
5870
+ }
5871
+ .mention-ico {
5872
+ flex-shrink: 0;
5873
+ display: inline-flex;
5874
+ align-items: center;
5875
+ color: var(--color-text-secondary);
5876
+ }
5877
+ .mention-name {
5878
+ font-size: 0.8125rem;
5879
+ color: var(--color-text-primary);
5880
+ white-space: nowrap;
5881
+ overflow: hidden;
5882
+ text-overflow: ellipsis;
5883
+ min-width: 0;
5884
+ }
5885
+ .mention-size {
5886
+ font-size: 0.6875rem;
5887
+ color: var(--color-text-tertiary);
5888
+ flex-shrink: 0;
5889
+ }
5890
+ .mention-chevron {
5891
+ flex-shrink: 0;
5892
+ display: inline-flex;
5893
+ align-items: center;
5894
+ justify-content: center;
5895
+ color: var(--color-text-tertiary);
5896
+ margin-left: 0.375rem;
5897
+ padding: 0.25rem;
5898
+ border-radius: 0.375rem;
5899
+ transition: background 0.1s, color 0.1s;
5900
+ }
5901
+ .mention-chevron:hover {
5902
+ background: var(--color-bg-hover);
5903
+ color: var(--color-text-primary);
5904
+ }
5905
+ .mention-empty {
5906
+ padding: 0.875rem 0.625rem;
5907
+ font-size: 0.8125rem;
5908
+ color: var(--color-text-tertiary);
5909
+ }
5910
+ .mention-load-more {
5911
+ flex-shrink: 0;
5912
+ border: none;
5913
+ background: transparent;
5914
+ color: var(--color-text-tertiary);
5915
+ font-size: 0.8125rem;
5916
+ cursor: pointer;
5917
+ padding: 0.5rem 0.625rem;
5918
+ border-radius: 0.5rem;
5919
+ text-align: center;
5920
+ transition: background 0.1s, color 0.1s;
5921
+ }
5922
+ .mention-load-more:hover {
5923
+ color: var(--color-text-primary);
5924
+ background: var(--color-bg-hover);
5925
+ }
5926
+ .mention-load-more.active {
5927
+ color: var(--color-text-primary);
5928
+ background: color-mix(in srgb, var(--color-text-primary) 8%, transparent);
5929
+ }
5930
+ .mention-load-more:disabled {
5931
+ color: var(--color-text-tertiary);
5932
+ cursor: default;
5933
+ }
5934
+
5935
+ /* ── Mention chips inside the contenteditable composer ─────────────────── */
5936
+ .mention-chip {
5937
+ display: inline-flex;
5938
+ align-items: center;
5939
+ gap: 0.25rem;
5940
+ padding: 0 0.375rem;
5941
+ margin: 0 0.125rem;
5942
+ background: var(--color-bg-hover);
5943
+ color: var(--color-text-primary);
5944
+ border-radius: 0.375rem;
5945
+ font-size: 0.8125rem;
5946
+ vertical-align: baseline;
5947
+ user-select: none;
5948
+ cursor: default;
5949
+ }
5950
+ .mention-chip-icon {
5951
+ display: inline-flex;
5952
+ align-items: center;
5953
+ color: var(--color-text-secondary);
5954
+ }
5955
+
5956
+ /* ── Mention badge inside user message bubbles ─────────────────────────── */
5957
+ .msg-mention-badge {
5958
+ display: inline-flex;
5959
+ align-items: center;
5960
+ gap: 0.3125rem;
5961
+ padding: 0.1875rem 0.5rem;
5962
+ border-radius: 0.375rem;
5963
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, transparent);
5964
+ font-size: 0.75rem;
5965
+ margin: 0 0.25rem 0.25rem 0;
5966
+ }
5967
+ .msg-mention-badge-icon {
5968
+ display: inline-flex;
5969
+ align-items: center;
5970
+ flex-shrink: 0;
5971
+ }
5972
+
5488
5973
  #user-input {
5489
5974
  flex: 1;
5490
5975
  background: transparent !important;
@@ -5500,8 +5985,17 @@ body {
5500
5985
  overflow-y: auto;
5501
5986
  scrollbar-width: none;
5502
5987
  margin: 0;
5988
+ white-space: pre-wrap;
5989
+ overflow-wrap: break-word;
5990
+ word-break: break-word;
5991
+ min-height: calc(1.55em + 8px);
5503
5992
  }
5504
5993
  #user-input::-webkit-scrollbar { display: none; }
5994
+ #user-input:empty::before {
5995
+ content: attr(data-placeholder);
5996
+ color: var(--color-text-tertiary);
5997
+ pointer-events: none;
5998
+ }
5505
5999
 
5506
6000
  #btn-send, #btn-interrupt {
5507
6001
  border: none;
@@ -5664,11 +6158,13 @@ body {
5664
6158
  align-items: center;
5665
6159
  justify-content: space-between;
5666
6160
  font-size: 1.125rem;
5667
- font-weight: 700;
5668
6161
  color: var(--color-text-primary);
5669
6162
  letter-spacing: -0.3px;
5670
6163
  padding-bottom: 0.5rem;
5671
6164
  }
6165
+ .settings-section-title > span {
6166
+ font-weight: 700;
6167
+ }
5672
6168
  .btn-settings-add {
5673
6169
  display: flex;
5674
6170
  align-items: center;
@@ -6072,6 +6568,7 @@ body {
6072
6568
  cursor: pointer;
6073
6569
  display: flex;
6074
6570
  align-items: center;
6571
+ gap: 0.375rem;
6075
6572
  justify-content: space-between;
6076
6573
  transition: border-color 0.15s ease;
6077
6574
  }
@@ -6092,6 +6589,24 @@ body {
6092
6589
  .custom-select-trigger .placeholder {
6093
6590
  color: var(--color-text-secondary);
6094
6591
  }
6592
+ .custom-select-value {
6593
+ overflow: hidden;
6594
+ text-overflow: ellipsis;
6595
+ white-space: nowrap;
6596
+ }
6597
+ .custom-select-trigger--bare {
6598
+ border: none;
6599
+ background: transparent;
6600
+ border-radius: 0;
6601
+ padding: 0 0.25rem;
6602
+ font-size: 0.6875rem;
6603
+ height: 100%;
6604
+ color: var(--color-text-secondary);
6605
+ }
6606
+ .custom-select-trigger--bare .custom-select-value:not(.placeholder) {
6607
+ color: var(--color-accent-primary);
6608
+ font-weight: 500;
6609
+ }
6095
6610
  .custom-select-arrow {
6096
6611
  width: 0.75rem;
6097
6612
  height: 0.75rem;
@@ -6099,6 +6614,9 @@ body {
6099
6614
  transition: transform 0.2s ease;
6100
6615
  flex-shrink: 0;
6101
6616
  }
6617
+ .custom-select-arrow path {
6618
+ stroke-width: 2.5;
6619
+ }
6102
6620
  .custom-select-trigger.open .custom-select-arrow {
6103
6621
  transform: rotate(180deg);
6104
6622
  }
@@ -6106,7 +6624,9 @@ body {
6106
6624
  position: absolute;
6107
6625
  top: calc(100% + 0.25rem);
6108
6626
  left: 0;
6109
- right: 0;
6627
+ min-width: 100%;
6628
+ width: max-content;
6629
+ max-width: 24rem;
6110
6630
  background: var(--color-bg-secondary);
6111
6631
  border: 1px solid var(--color-border-primary);
6112
6632
  border-radius: 8px;
@@ -6115,16 +6635,22 @@ body {
6115
6635
  overflow-y: auto;
6116
6636
  z-index: 1000;
6117
6637
  display: none;
6638
+ padding: 0.375rem 0;
6118
6639
  }
6119
6640
  .custom-select-dropdown.open {
6120
6641
  display: block;
6121
6642
  }
6122
6643
  .custom-select-option {
6123
6644
  padding: 0.5rem 0.75rem;
6645
+ margin: 0 0.375rem;
6124
6646
  font-size: 0.8125rem;
6125
6647
  color: var(--color-text-primary);
6126
6648
  cursor: pointer;
6649
+ border-radius: 6px;
6127
6650
  transition: background-color 0.15s ease;
6651
+ white-space: nowrap;
6652
+ overflow: hidden;
6653
+ text-overflow: ellipsis;
6128
6654
  }
6129
6655
  .custom-select-option:hover {
6130
6656
  background: var(--color-bg-hover);
@@ -6133,6 +6659,55 @@ body {
6133
6659
  background: var(--color-bg-hover);
6134
6660
  color: var(--color-accent-primary);
6135
6661
  }
6662
+ /* "Custom" entry lives in a fixed footer area outside the panel's own
6663
+ scroll region, so it stays visible without ever scrolling with the list. */
6664
+ .custom-select-dropdown--footer {
6665
+ display: none;
6666
+ flex-direction: column;
6667
+ overflow: hidden;
6668
+ padding: 0.375rem 0 0;
6669
+ }
6670
+ .custom-select-dropdown--footer.open {
6671
+ display: flex;
6672
+ }
6673
+ .custom-select-list {
6674
+ flex: 1 1 auto;
6675
+ min-height: 0;
6676
+ overflow-y: auto;
6677
+ }
6678
+ .custom-select-option-custom {
6679
+ position: relative;
6680
+ flex-shrink: 0;
6681
+ display: flex;
6682
+ align-items: center;
6683
+ gap: 0.5rem;
6684
+ /* Override .custom-select-option's overflow:hidden (ellipsis) so the
6685
+ ::before divider can extend above this row. */
6686
+ overflow: visible;
6687
+ margin: 0.375rem;
6688
+ padding: 0.5rem 0.75rem;
6689
+ border-radius: 6px;
6690
+ background: var(--color-bg-secondary);
6691
+ color: var(--color-text-secondary);
6692
+ }
6693
+ .custom-select-option-custom::before {
6694
+ content: "";
6695
+ position: absolute;
6696
+ top: -0.1875rem;
6697
+ left: 0;
6698
+ right: 0;
6699
+ height: 1px;
6700
+ background: var(--color-border-primary);
6701
+ }
6702
+ .custom-select-option-custom:hover {
6703
+ color: var(--color-text-primary);
6704
+ }
6705
+ .custom-select-option-custom svg {
6706
+ flex-shrink: 0;
6707
+ }
6708
+ .custom-select-option-custom:hover {
6709
+ color: var(--color-text-primary);
6710
+ }
6136
6711
 
6137
6712
  /* Provider recommended badge (inside dropdown option) */
6138
6713
  .provider-badge-recommended {
@@ -6236,25 +6811,13 @@ body {
6236
6811
  color: var(--color-text-tertiary);
6237
6812
  }
6238
6813
  .model-provider-filter {
6239
- height: 2.25rem;
6240
- padding: 0 1.75rem 0 0.625rem;
6241
- border: 1px solid var(--color-border-primary);
6242
- border-radius: 6px;
6243
- background: var(--color-bg-primary);
6244
- color: var(--color-text-primary);
6245
- font-size: 0.8125rem;
6246
- outline: none;
6247
- cursor: pointer;
6248
- transition: border-color 0.15s;
6814
+ width: auto;
6249
6815
  max-width: 12rem;
6250
6816
  min-width: 0;
6251
- appearance: none;
6252
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238b949e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 9l-7 7-7-7'/%3E%3C/svg%3E");
6253
- background-repeat: no-repeat;
6254
- background-position: right 0.625rem center;
6817
+ height: 2.25rem;
6255
6818
  }
6256
- .model-provider-filter:focus {
6257
- border-color: var(--color-accent-primary);
6819
+ .model-provider-filter .custom-select-trigger {
6820
+ height: 100%;
6258
6821
  }
6259
6822
 
6260
6823
  /* ── Grid Model Card ────────────────────────────────────────────────────────── */
@@ -6392,20 +6955,23 @@ body {
6392
6955
  .model-card-grid-link {
6393
6956
  display: inline-flex;
6394
6957
  align-items: center;
6395
- gap: 0.25rem;
6396
- font-size: 0.6875rem;
6397
- color: var(--color-text-tertiary);
6958
+ gap: 0.375rem;
6959
+ font-size: 0.75rem;
6960
+ font-weight: 500;
6961
+ color: var(--color-text-secondary);
6398
6962
  text-decoration: none;
6399
- padding: 0.125rem 0.25rem;
6400
- border-radius: 4px;
6401
- transition: color 0.15s;
6963
+ padding: 0.375rem 0.625rem;
6964
+ border: 1px solid var(--color-border-primary);
6965
+ border-radius: 6px;
6966
+ background: var(--color-bg-tertiary);
6967
+ transition: all 0.15s;
6402
6968
  }
6403
6969
  .model-card-grid-link:hover {
6970
+ border-color: var(--color-accent-primary);
6404
6971
  color: var(--color-accent-primary);
6405
- text-decoration: underline;
6972
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, transparent);
6406
6973
  }
6407
6974
  .model-card-grid-link svg {
6408
- opacity: 0.7;
6409
6975
  flex-shrink: 0;
6410
6976
  }
6411
6977
 
@@ -6594,16 +7160,122 @@ body {
6594
7160
  }
6595
7161
  /* ── Dir Picker — Finder-style ────────────────────────────────────── */
6596
7162
  .dp-modal {
6597
- max-width: 680px;
6598
- width: 680px;
6599
- max-height: 85vh;
7163
+ max-width: 820px;
7164
+ width: 820px;
7165
+ height: min(640px, calc(100vh - 2rem));
7166
+ max-height: none;
6600
7167
  display: flex;
6601
- flex-direction: column;
7168
+ flex-direction: row;
6602
7169
  padding: 0;
6603
7170
  overflow: hidden;
6604
7171
  border-radius: 10px;
6605
7172
  }
6606
7173
 
7174
+ /* Sidebar — quick-access places (favorites + locations) */
7175
+ .dp-sidebar {
7176
+ width: 184px;
7177
+ flex-shrink: 0;
7178
+ overflow-y: auto;
7179
+ padding: 0.8rem 0.5rem 0.5rem 0.5rem;
7180
+ border-right: 1px solid var(--color-border-primary);
7181
+ background: var(--color-bg-secondary);
7182
+ }
7183
+ .dp-sidebar-label {
7184
+ padding: 0.25rem 0.5rem 0.25rem;
7185
+ font-size: 0.6875rem;
7186
+ font-weight: 600;
7187
+ text-transform: uppercase;
7188
+ letter-spacing: 0.04em;
7189
+ color: var(--color-text-tertiary);
7190
+ }
7191
+ .dp-sidebar-label:not(:first-child) {
7192
+ margin-top: 0.5rem;
7193
+ }
7194
+ .dp-sidebar-item {
7195
+ display: flex;
7196
+ align-items: center;
7197
+ gap: 0.5rem;
7198
+ width: 100%;
7199
+ padding: 0.35rem 0.5rem;
7200
+ border: none;
7201
+ border-radius: 6px;
7202
+ background: transparent;
7203
+ color: var(--color-text-primary);
7204
+ font-size: 0.8125rem;
7205
+ cursor: pointer;
7206
+ text-align: left;
7207
+ transition: background 0.08s;
7208
+ }
7209
+ .dp-sidebar-item:hover {
7210
+ background: var(--color-bg-hover);
7211
+ }
7212
+ .dp-sidebar-icon {
7213
+ display: inline-flex;
7214
+ align-items: center;
7215
+ flex-shrink: 0;
7216
+ color: var(--color-text-secondary);
7217
+ }
7218
+ .dp-sidebar-name {
7219
+ flex: 1;
7220
+ min-width: 0;
7221
+ white-space: nowrap;
7222
+ overflow: hidden;
7223
+ text-overflow: ellipsis;
7224
+ }
7225
+ .dp-sidebar-favorite {
7226
+ display: flex;
7227
+ align-items: center;
7228
+ border-radius: 6px;
7229
+ transition: background 0.08s;
7230
+ }
7231
+ .dp-sidebar-favorite:hover,
7232
+ .dp-sidebar-favorite:focus-within {
7233
+ background: var(--color-bg-hover);
7234
+ }
7235
+ .dp-sidebar-favorite-open {
7236
+ min-width: 0;
7237
+ padding-right: 0.25rem;
7238
+ }
7239
+ .dp-sidebar-favorite-open:hover {
7240
+ background: transparent;
7241
+ }
7242
+ .dp-sidebar-favorite-remove {
7243
+ display: inline-flex;
7244
+ align-items: center;
7245
+ justify-content: center;
7246
+ width: 24px;
7247
+ height: 24px;
7248
+ margin-right: 2px;
7249
+ padding: 0;
7250
+ flex-shrink: 0;
7251
+ border: 0;
7252
+ border-radius: 4px;
7253
+ background: transparent;
7254
+ color: var(--color-text-tertiary);
7255
+ cursor: pointer;
7256
+ opacity: 0;
7257
+ pointer-events: none;
7258
+ transition: opacity 0.1s, background 0.1s, color 0.1s;
7259
+ }
7260
+ .dp-sidebar-favorite:hover .dp-sidebar-favorite-remove,
7261
+ .dp-sidebar-favorite:focus-within .dp-sidebar-favorite-remove {
7262
+ opacity: 1;
7263
+ pointer-events: auto;
7264
+ }
7265
+ .dp-sidebar-favorite-remove:hover {
7266
+ background: var(--color-bg-active);
7267
+ color: var(--color-text-primary);
7268
+ }
7269
+
7270
+ /* Main column — toolbar + list + footer */
7271
+ .dp-main {
7272
+ display: flex;
7273
+ flex-direction: column;
7274
+ flex: 1;
7275
+ min-width: 0;
7276
+ min-height: 0;
7277
+ }
7278
+
6607
7279
  /* Toolbar */
6608
7280
  .dp-toolbar {
6609
7281
  display: flex;
@@ -6622,74 +7294,175 @@ body {
6622
7294
  display: inline-flex;
6623
7295
  align-items: center;
6624
7296
  justify-content: center;
6625
- width: 26px;
6626
- height: 26px;
7297
+ width: 32px;
7298
+ height: 32px;
6627
7299
  padding: 0;
6628
- border: 1px solid rgba(0,0,0,0.18);
7300
+ border: 0;
6629
7301
  border-radius: 5px;
6630
- background: var(--color-bg-primary);
6631
- color: var(--color-text-primary);
7302
+ background: transparent;
7303
+ color: var(--color-text-secondary);
6632
7304
  cursor: pointer;
6633
- transition: background 0.1s;
7305
+ transition: background 0.1s, color 0.1s;
6634
7306
  }
6635
7307
  .dp-nav-btn:hover:not(:disabled) {
6636
7308
  background: var(--color-bg-hover);
7309
+ color: var(--color-text-primary);
6637
7310
  }
6638
7311
  .dp-nav-btn:disabled {
6639
7312
  opacity: 0.3;
6640
7313
  cursor: not-allowed;
6641
7314
  }
7315
+ .dp-favorite-btn {
7316
+ flex-shrink: 0;
7317
+ }
7318
+ .dp-favorite-btn.active {
7319
+ color: var(--color-accent-primary);
7320
+ }
6642
7321
  /* Breadcrumb */
6643
7322
  .dp-breadcrumb {
6644
7323
  display: flex;
6645
7324
  align-items: center;
6646
7325
  gap: 0;
6647
7326
  flex: 1;
7327
+ height: 28px;
6648
7328
  min-width: 0;
7329
+ padding: 1px 4px;
6649
7330
  overflow-x: auto;
6650
7331
  overflow-y: hidden;
7332
+ border: 1px solid transparent;
7333
+ border-radius: 5px;
7334
+ background: var(--color-bg-primary);
7335
+ cursor: text;
7336
+ transition: border-color 0.12s, background 0.12s;
6651
7337
  scrollbar-width: none; /* Firefox */
6652
7338
  -ms-overflow-style: none; /* IE */
6653
- /* Left fade mask when content overflows */
6654
- -webkit-mask-image: linear-gradient(to right, transparent 0px, black 32px);
6655
- mask-image: linear-gradient(to right, transparent 0px, black 32px);
7339
+ }
7340
+ .dp-breadcrumb.editing {
7341
+ padding: 0;
7342
+ overflow: hidden;
7343
+ border-color: var(--color-accent-primary);
7344
+ background: var(--color-bg-secondary);
6656
7345
  }
6657
7346
  .dp-breadcrumb::-webkit-scrollbar {
6658
7347
  display: none;
6659
7348
  }
6660
7349
  .dp-bc-seg {
7350
+ display: inline-flex;
7351
+ align-items: center;
7352
+ height: 22px;
6661
7353
  font-size: 0.8125rem;
7354
+ font-family: inherit;
6662
7355
  color: var(--color-text-secondary);
6663
7356
  cursor: pointer;
6664
7357
  white-space: nowrap;
6665
7358
  padding: 3px 6px;
7359
+ border: 0;
6666
7360
  border-radius: 4px;
7361
+ background: transparent;
6667
7362
  transition: background 0.1s, color 0.1s;
6668
7363
  }
6669
7364
  .dp-bc-seg:hover {
6670
- background: rgba(0,0,0,0.07);
7365
+ background: var(--color-bg-hover);
6671
7366
  color: var(--color-text-primary);
6672
7367
  }
6673
7368
  .dp-bc-current {
6674
7369
  color: var(--color-text-primary);
6675
7370
  font-weight: 500;
6676
- cursor: default;
6677
- }
6678
- .dp-bc-current:hover {
6679
- background: transparent;
6680
7371
  }
6681
7372
  .dp-bc-sep {
6682
7373
  display: inline-flex;
6683
7374
  align-items: center;
7375
+ justify-content: center;
7376
+ width: 22px;
7377
+ height: 22px;
7378
+ padding: 0;
7379
+ border: 0;
7380
+ border-radius: 4px;
7381
+ background: transparent;
6684
7382
  color: var(--color-text-tertiary);
7383
+ cursor: pointer;
6685
7384
  flex-shrink: 0;
6686
7385
  }
6687
- .dp-bc-folder-icon {
6688
- display: inline-flex;
7386
+ .dp-bc-sep svg {
7387
+ width: 12px;
7388
+ height: 12px;
7389
+ transform-origin: center;
7390
+ transition: transform 0.16s ease;
7391
+ }
7392
+ .dp-bc-sep.open svg {
7393
+ transform: rotate(90deg);
7394
+ }
7395
+ .dp-bc-sep:hover,
7396
+ .dp-bc-sep.open {
7397
+ color: var(--color-text-primary);
7398
+ background: var(--color-bg-hover);
7399
+ }
7400
+ @media (prefers-reduced-motion: reduce) {
7401
+ .dp-bc-sep svg {
7402
+ transition: none;
7403
+ }
7404
+ }
7405
+ .dp-address-input {
7406
+ width: 100%;
7407
+ height: 100%;
7408
+ padding: 0 8px;
7409
+ border: 0;
7410
+ outline: 0;
7411
+ background: transparent;
7412
+ color: var(--color-text-primary);
7413
+ font-family: var(--font-mono);
7414
+ font-size: 0.8125rem;
7415
+ }
7416
+ .dp-address-input.invalid {
7417
+ box-shadow: inset 0 0 0 1px var(--color-text-danger, #ef4444);
7418
+ }
7419
+ .dp-bc-menu {
7420
+ position: fixed;
7421
+ z-index: 1100;
7422
+ min-width: 180px;
7423
+ max-width: min(320px, calc(100vw - 16px));
7424
+ max-height: 280px;
7425
+ padding: 4px;
7426
+ overflow-y: auto;
7427
+ border: 1px solid var(--color-border-primary);
7428
+ border-radius: 7px;
7429
+ background: var(--color-bg-primary);
7430
+ box-shadow: var(--shadow-lg);
7431
+ }
7432
+ .dp-bc-menu-item {
7433
+ display: flex;
6689
7434
  align-items: center;
6690
- color: var(--color-text-secondary);
6691
- margin-right: 3px;
7435
+ gap: 0.5rem;
7436
+ width: 100%;
7437
+ padding: 0.4rem 0.5rem;
7438
+ border: 0;
7439
+ border-radius: 5px;
7440
+ background: transparent;
7441
+ color: var(--color-text-primary);
7442
+ cursor: pointer;
7443
+ font: inherit;
7444
+ text-align: left;
7445
+ }
7446
+ .dp-bc-menu-item:hover {
7447
+ background: var(--color-bg-hover);
7448
+ }
7449
+ .dp-bc-menu-icon {
7450
+ display: inline-flex;
6692
7451
  flex-shrink: 0;
7452
+ color: var(--color-text-secondary);
7453
+ }
7454
+ .dp-bc-menu-name {
7455
+ overflow: hidden;
7456
+ text-overflow: ellipsis;
7457
+ white-space: nowrap;
7458
+ }
7459
+ .dp-bc-menu-state {
7460
+ padding: 0.6rem 0.75rem;
7461
+ color: var(--color-text-tertiary);
7462
+ font-size: 0.8125rem;
7463
+ }
7464
+ .dp-bc-menu-error {
7465
+ color: var(--color-text-danger, #ef4444);
6693
7466
  }
6694
7467
 
6695
7468
  /* Column header */
@@ -6729,7 +7502,7 @@ body {
6729
7502
  .dp-list {
6730
7503
  flex: 1;
6731
7504
  overflow-y: auto;
6732
- min-height: 320px;
7505
+ min-height: 0;
6733
7506
  padding-top: 0.35rem;
6734
7507
  background: var(--color-bg-primary);
6735
7508
  }
@@ -8248,29 +9021,14 @@ body {
8248
9021
  flex: 1;
8249
9022
  min-width: 15rem;
8250
9023
  font-size: 0.8125rem;
8251
- padding: 0.4375rem 0.75rem;
8252
- border-radius: 6px;
8253
- border: 1px solid var(--color-border-primary);
8254
- background: var(--color-bg-secondary);
8255
- color: var(--color-text-primary);
8256
- }
8257
- .extensions-sort {
8258
- flex-shrink: 0;
8259
- font-size: 0.8125rem;
8260
- padding: 0.4375rem 2rem 0.4375rem 0.75rem;
9024
+ padding: 0.5375rem 0.75rem;
8261
9025
  border-radius: 6px;
8262
9026
  border: 1px solid var(--color-border-primary);
8263
9027
  background: var(--color-bg-secondary);
8264
9028
  color: var(--color-text-primary);
8265
- cursor: pointer;
8266
- appearance: none;
8267
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
8268
- background-repeat: no-repeat;
8269
- background-position: right 0.625rem center;
8270
9029
  }
8271
- .extensions-sort:focus {
8272
- outline: none;
8273
- border-color: var(--color-accent, #6366f1);
9030
+ .extensions-select {
9031
+ width: auto;
8274
9032
  }
8275
9033
  #extensions-list {
8276
9034
  display: flex;
@@ -11823,6 +12581,7 @@ body.setup-mode[data-theme="dark"] {
11823
12581
  }
11824
12582
  /* Project filter dropdown */
11825
12583
  .trash-filter-project-wrap {
12584
+ position: relative;
11826
12585
  display: inline-flex;
11827
12586
  align-items: center;
11828
12587
  gap: 0.3rem;
@@ -11842,16 +12601,12 @@ body.setup-mode[data-theme="dark"] {
11842
12601
  flex-shrink: 0;
11843
12602
  pointer-events: none;
11844
12603
  }
11845
- .trash-filter-project-select {
11846
- font-size: 0.6875rem;
11847
- color: inherit;
11848
- background: transparent;
11849
- border: none;
11850
- outline: none;
11851
- cursor: pointer;
11852
- padding: 0;
12604
+ .trash-filter-project-wrap .custom-select-wrapper {
12605
+ /* dropdown anchors to the wrap (icon + trigger) instead, so the panel
12606
+ aligns with the whole control's left edge rather than the icon's right */
12607
+ position: static;
12608
+ min-width: 0;
11853
12609
  max-width: 130px;
11854
- appearance: auto;
11855
12610
  }
11856
12611
  .trash-actions {
11857
12612
  display: flex;
@@ -12105,25 +12860,29 @@ body.setup-mode[data-theme="dark"] {
12105
12860
  }
12106
12861
  .billing-top-bar {
12107
12862
  display: flex;
12108
- justify-content: space-between;
12109
- align-items: center;
12110
- flex-wrap: wrap;
12863
+ flex-direction: column;
12864
+ align-items: stretch;
12111
12865
  gap: 1rem;
12112
12866
  }
12113
12867
  .billing-title-row {
12114
12868
  display: flex;
12115
12869
  align-items: baseline;
12870
+ flex-wrap: wrap;
12116
12871
  gap: 0.75rem;
12872
+ min-width: 0;
12117
12873
  }
12118
12874
  .billing-title-row h2 {
12119
12875
  font-size: 1.5rem;
12120
12876
  font-weight: 500;
12121
12877
  color: var(--color-text-primary);
12122
12878
  margin: 0;
12879
+ flex-shrink: 0;
12123
12880
  }
12124
12881
  .billing-subtitle {
12125
12882
  font-size: 0.875rem;
12126
12883
  color: var(--color-text-secondary);
12884
+ min-width: 0;
12885
+ overflow-wrap: anywhere;
12127
12886
  }
12128
12887
  .billing-controls {
12129
12888
  display: flex;
@@ -12131,6 +12890,14 @@ body.setup-mode[data-theme="dark"] {
12131
12890
  gap: 0.625rem;
12132
12891
  flex-wrap: wrap;
12133
12892
  }
12893
+ .billing-controls .segmented-control {
12894
+ flex: 0 0 auto;
12895
+ }
12896
+ .billing-controls .segmented-control,
12897
+ .billing-model-filter,
12898
+ .billing-share-btn {
12899
+ height: 2rem;
12900
+ }
12134
12901
 
12135
12902
  /* ── Disclaimer notice ──────────────────────────────────────────────── */
12136
12903
  .billing-disclaimer {
@@ -12147,34 +12914,20 @@ body.setup-mode[data-theme="dark"] {
12147
12914
 
12148
12915
  /* ── Model Filter ────────────────────────────────────────────────────── */
12149
12916
  .billing-model-filter {
12150
- padding: 0.5375rem 1.75rem 0.5375rem 0.75rem;
12151
- border: 1px solid var(--color-border-primary);
12152
- border-radius: 8px;
12153
- background: var(--color-bg-secondary);
12154
- color: var(--color-text-primary);
12155
- font-size: 0.8125rem;
12156
- cursor: pointer;
12157
- min-width: 130px;
12158
- appearance: none;
12159
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
12160
- background-repeat: no-repeat;
12161
- background-position: right 0.625rem center;
12162
- transition: border-color 0.15s ease;
12163
- }
12164
- .billing-model-filter:focus {
12165
- outline: none;
12166
- border-color: var(--color-accent-primary);
12167
- box-shadow: 0 0 0 3px var(--color-accent-soft);
12917
+ width: 16rem;
12918
+ flex: 0 0 16rem;
12919
+ min-width: 0;
12168
12920
  }
12169
- .billing-model-filter option {
12170
- background: var(--color-bg-secondary);
12171
- color: var(--color-text-primary);
12921
+ .billing-model-filter .custom-select-trigger {
12922
+ height: 100%;
12172
12923
  }
12173
12924
 
12174
12925
  /* ── Action Buttons ──────────────────────────────────────────────────── */
12175
12926
  .billing-share-btn {
12176
12927
  display: inline-flex;
12177
12928
  align-items: center;
12929
+ justify-content: center;
12930
+ margin-left: auto;
12178
12931
  gap: 0.375rem;
12179
12932
  padding: 0.4375rem 0.75rem;
12180
12933
  border: 1px solid var(--color-border-primary);
@@ -14278,6 +15031,26 @@ body.setup-mode[data-theme="dark"] {
14278
15031
  #billing-body { padding: 1rem 1rem 1rem; }
14279
15032
  #trash-body { padding: 1rem 1rem 1rem; }
14280
15033
 
15034
+ .billing-controls .segmented-control {
15035
+ flex: 1 0 100%;
15036
+ }
15037
+ .billing-controls .segmented-control__btn {
15038
+ flex: 1 1 0;
15039
+ min-width: 0;
15040
+ }
15041
+ .billing-model-filter {
15042
+ width: auto;
15043
+ flex: 1 1 0;
15044
+ }
15045
+ @media (max-width: 500px) {
15046
+ .billing-controls .segmented-control {
15047
+ overflow-x: auto;
15048
+ }
15049
+ .billing-controls .segmented-control__btn {
15050
+ flex: 1 0 auto;
15051
+ padding-inline: 0.5rem;
15052
+ }
15053
+ }
14281
15054
  .billing-heatmap-row { grid-template-columns: 1fr; }
14282
15055
 
14283
15056
  /* ── MCP page ── */