openclacky 1.5.2 → 1.5.4

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +13 -0
  3. data/CHANGELOG.md +50 -0
  4. data/Dockerfile +21 -1
  5. data/README.md +26 -7
  6. data/README_CN.md +26 -7
  7. data/README_JA.md +26 -7
  8. data/lib/clacky/agent/message_compressor.rb +4 -29
  9. data/lib/clacky/agent/message_compressor_helper.rb +13 -15
  10. data/lib/clacky/agent/session_serializer.rb +6 -0
  11. data/lib/clacky/agent.rb +13 -1
  12. data/lib/clacky/agent_config.rb +42 -11
  13. data/lib/clacky/brand_config.rb +32 -12
  14. data/lib/clacky/client.rb +7 -0
  15. data/lib/clacky/default_extensions/ext-studio/agents/ext-developer/system_prompt.md +15 -0
  16. data/lib/clacky/default_extensions/ext-studio/api/handler.rb +2 -6
  17. data/lib/clacky/default_extensions/ext-studio/panels/studio/view.js +11 -4
  18. data/lib/clacky/default_extensions/ext-studio/skills/ext-develop/SKILL.md +5 -1
  19. data/lib/clacky/default_parsers/xlsx_parser.py +66 -0
  20. data/lib/clacky/extension/api_extension.rb +3 -2
  21. data/lib/clacky/message_format/anthropic.rb +27 -1
  22. data/lib/clacky/message_format/open_ai.rb +92 -4
  23. data/lib/clacky/providers.rb +67 -14
  24. data/lib/clacky/server/http_server.rb +361 -36
  25. data/lib/clacky/server/project_manager.rb +150 -0
  26. data/lib/clacky/server/server_master.rb +7 -0
  27. data/lib/clacky/server/session_registry.rb +14 -1
  28. data/lib/clacky/session_manager.rb +5 -4
  29. data/lib/clacky/tools/file_reader.rb +2 -1
  30. data/lib/clacky/utils/model_pricing.rb +77 -18
  31. data/lib/clacky/utils/parser_manager.rb +115 -7
  32. data/lib/clacky/version.rb +1 -1
  33. data/lib/clacky/web/app.css +1053 -143
  34. data/lib/clacky/web/app.js +19 -5
  35. data/lib/clacky/web/components/code-editor.js +50 -12
  36. data/lib/clacky/web/components/notify.js +139 -22
  37. data/lib/clacky/web/core/aside.js +21 -0
  38. data/lib/clacky/web/features/billing/view.js +2 -1
  39. data/lib/clacky/web/features/brand/store.js +3 -1
  40. data/lib/clacky/web/features/brand/view.js +29 -5
  41. data/lib/clacky/web/features/extensions/store.js +15 -6
  42. data/lib/clacky/web/features/extensions/view.js +8 -4
  43. data/lib/clacky/web/features/new-session/view.js +2 -2
  44. data/lib/clacky/web/features/trash/store.js +23 -9
  45. data/lib/clacky/web/features/trash/view.js +51 -0
  46. data/lib/clacky/web/features/workspace/store.js +9 -0
  47. data/lib/clacky/web/features/workspace/view.js +8 -1
  48. data/lib/clacky/web/i18n.js +99 -4
  49. data/lib/clacky/web/index.html +70 -17
  50. data/lib/clacky/web/projects.js +1143 -0
  51. data/lib/clacky/web/sessions.js +318 -537
  52. data/lib/clacky/web/settings.js +146 -7
  53. data/lib/clacky/web/ws-dispatcher.js +59 -1
  54. data/scripts/build/src/install_system_deps.sh.cc +11 -3
  55. data/scripts/install_system_deps.sh +11 -3
  56. metadata +5 -2
  57. data/lib/clacky/default_parsers/xlsx_parser.rb +0 -121
@@ -803,7 +803,7 @@ body {
803
803
  margin-bottom: 6px;
804
804
  border-bottom: 1px solid var(--color-border-secondary);
805
805
  }
806
- #ext-slot-sidebar-nav { padding: 6px 0 4px; }
806
+ #ext-slot-sidebar-nav { padding: 10px 0 0px; }
807
807
  #ext-slot-sidebar-nav-bottom {
808
808
  padding: 8px 0 10px;
809
809
  margin-top: 6px;
@@ -842,12 +842,46 @@ body {
842
842
  .sidebar-divider:has(.sidebar-divider-actions) {
843
843
  justify-content: space-between;
844
844
  }
845
+ /* Sessions divider: suppress the rule line (buttons fill the right side) */
846
+ .sidebar-divider--no-rule::after {
847
+ display: none;
848
+ }
845
849
  .sidebar-divider-actions {
846
850
  display: flex;
847
851
  align-items: center;
848
852
  gap: 4px;
849
853
  }
850
854
 
855
+ /* ── Chat section collapse ───────────────────────────────────────────────── */
856
+ #chat-section-header {
857
+ cursor: pointer;
858
+ z-index: 20;
859
+ }
860
+ .chat-section-title {
861
+ display: flex;
862
+ align-items: center;
863
+ gap: 3px;
864
+ white-space: nowrap;
865
+ flex: 0 0 auto;
866
+ }
867
+ .chat-section-chevron {
868
+ flex-shrink: 0;
869
+ color: var(--color-text-muted);
870
+ opacity: 0;
871
+ transition: transform 0.2s ease, opacity 0.15s ease;
872
+ margin-left: 1px;
873
+ }
874
+ #chat-section-header:hover .chat-section-chevron {
875
+ opacity: 1;
876
+ }
877
+ .chat-header-collapsed .chat-section-chevron {
878
+ opacity: 1;
879
+ transform: rotate(-90deg);
880
+ }
881
+ .chat-section-collapsed {
882
+ display: none;
883
+ }
884
+
851
885
  /* ── New Session button ──────────────────────────────────────────────────── */
852
886
  .btn-split-wrap {
853
887
  display: flex;
@@ -1503,21 +1537,29 @@ body {
1503
1537
  /* Actions button (⋯) on session list items — visible only on hover */
1504
1538
  .session-actions-btn {
1505
1539
  flex-shrink: 0;
1506
- display: none;
1540
+ display: flex;
1507
1541
  align-items: center;
1508
1542
  justify-content: center;
1509
- width: 1.5rem;
1543
+ width: 0;
1510
1544
  height: 1.5rem;
1545
+ overflow: hidden;
1511
1546
  background: transparent;
1512
1547
  border: none;
1513
1548
  border-radius: 4px;
1514
1549
  color: var(--color-text-muted);
1515
1550
  cursor: pointer;
1516
1551
  padding: 0;
1517
- transition: background .15s, color .15s;
1552
+ opacity: 0;
1553
+ pointer-events: none;
1554
+ transition: background .15s, color .15s, width .15s, opacity .15s;
1518
1555
  align-self: center;
1519
1556
  }
1520
- .session-item:hover .session-actions-btn { display: flex; }
1557
+ .session-item:hover .session-actions-btn,
1558
+ .session-item.active .session-actions-btn {
1559
+ width: 1.5rem;
1560
+ opacity: 1;
1561
+ pointer-events: auto;
1562
+ }
1521
1563
  .session-actions-btn:hover {
1522
1564
  background: var(--color-border-primary);
1523
1565
  color: var(--color-text-primary);
@@ -2175,9 +2217,6 @@ body {
2175
2217
  }
2176
2218
 
2177
2219
  /* ── Starter Prompts ── */
2178
- .new-session-starter-prompts {
2179
- margin-top: 0.25rem;
2180
- }
2181
2220
  .ns-starter-label {
2182
2221
  font-size: 0.75rem;
2183
2222
  color: var(--color-text-tertiary);
@@ -2580,19 +2619,20 @@ body {
2580
2619
 
2581
2620
  .session-aside-collapse {
2582
2621
  position: absolute;
2583
- top: 7px;
2584
- right: 8px;
2622
+ top: 4px;
2623
+ right: 0.5rem;
2585
2624
  z-index: 11;
2586
2625
  display: inline-flex;
2587
2626
  align-items: center;
2588
2627
  justify-content: center;
2589
- width: 1.625rem;
2590
- height: 1.625rem;
2591
- border: none;
2592
- background: transparent;
2593
- color: var(--color-text-tertiary);
2628
+ width: 2rem;
2629
+ height: 2rem;
2630
+ border: 1px solid var(--color-border-primary);
2631
+ background: var(--color-bg-secondary);
2632
+ color: var(--color-text-secondary);
2594
2633
  border-radius: var(--radius-sm);
2595
2634
  cursor: pointer;
2635
+ box-shadow: var(--shadow-sm, 0 2px 8px rgba(0,0,0,0.06));
2596
2636
  transition: background-color var(--transition-base), color var(--transition-base);
2597
2637
  }
2598
2638
  .session-aside-collapse:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }
@@ -3405,6 +3445,32 @@ body {
3405
3445
  color: var(--color-text-secondary);
3406
3446
  }
3407
3447
  .msg-success { color: var(--color-success); align-self: flex-start; font-size: 0.8125rem; }
3448
+
3449
+ /* ── Ext-developer reload hint ─────────────────────────────────────────────── */
3450
+ .msg-ext-refresh-hint {
3451
+ align-self: flex-start;
3452
+ margin: 0 -1rem;
3453
+ }
3454
+ .btn-ext-refresh {
3455
+ display: inline-flex;
3456
+ align-items: center;
3457
+ gap: 0.4rem;
3458
+ padding: 0.375rem 0.75rem;
3459
+ font-size: 0.8125rem;
3460
+ font-weight: 500;
3461
+ color: var(--color-accent-primary);
3462
+ background: transparent;
3463
+ border: 1px solid var(--color-accent-primary);
3464
+ border-radius: 0.375rem;
3465
+ cursor: pointer;
3466
+ transition: background 0.15s, opacity 0.15s;
3467
+ }
3468
+ .btn-ext-refresh:hover:not(:disabled) {
3469
+ background: color-mix(in srgb, var(--color-accent-primary) 10%, transparent);
3470
+ }
3471
+ .btn-ext-refresh:disabled {
3472
+ cursor: default;
3473
+ }
3408
3474
  .tool-name { color: var(--color-warning); font-weight: 600; }
3409
3475
  .progress-msg { color: var(--color-accent-primary); font-size: 0.75rem; align-self: center; }
3410
3476
 
@@ -5376,7 +5442,7 @@ body {
5376
5442
  }
5377
5443
  .field-input-row .field-input { flex: 1; }
5378
5444
  .btn-toggle-key {
5379
- background: var(--color-border-secondary);
5445
+ background: var(--color-bg-primary);
5380
5446
  border: 1px solid var(--color-border-primary);
5381
5447
  border-radius: 6px;
5382
5448
  color: var(--color-text-secondary);
@@ -5384,8 +5450,19 @@ body {
5384
5450
  padding: 0.25rem 0.5rem;
5385
5451
  cursor: pointer;
5386
5452
  flex-shrink: 0;
5453
+ display: flex;
5454
+ align-items: center;
5455
+ justify-content: center;
5456
+ }
5457
+ .btn-toggle-key:hover {
5458
+ color: var(--color-text-primary);
5459
+ background: var(--color-bg-hover);
5460
+ }
5461
+ .btn-toggle-key:active {
5462
+ background: var(--color-bg-hover);
5463
+ filter: brightness(0.94);
5464
+ transform: scale(0.95);
5387
5465
  }
5388
- .btn-toggle-key:hover { color: var(--color-text-primary); }
5389
5466
  .field-checkbox {
5390
5467
  width: 1rem;
5391
5468
  height: 1rem;
@@ -5778,14 +5855,15 @@ body {
5778
5855
  max-height: 90vh;
5779
5856
  display: flex;
5780
5857
  flex-direction: column;
5781
- overflow: hidden;
5858
+ /* Do NOT use overflow:hidden here — it clips absolutely-positioned dropdowns
5859
+ inside the modal (e.g. the provider custom-select). Border-radius still
5860
+ applies because there is no overflow to clip. */
5861
+ overflow: visible;
5782
5862
  }
5783
5863
  .model-edit-modal-content {
5784
5864
  max-width: 500px;
5785
5865
  }
5786
- .model-edit-modal-content .modal-body {
5787
- overflow-y: auto;
5788
- }
5866
+ /* overflow override for model-edit modal is applied after .modal-content .modal-body below */
5789
5867
  .modal-content .modal-header {
5790
5868
  display: flex;
5791
5869
  align-items: center;
@@ -5823,6 +5901,12 @@ body {
5823
5901
  gap: 0.875rem;
5824
5902
  padding: 1.25rem;
5825
5903
  }
5904
+ /* model-edit modal: allow absolutely-positioned dropdowns to escape the body.
5905
+ Must come after .modal-content .modal-body to win the cascade. */
5906
+ .modal-content.model-edit-modal-content .modal-body {
5907
+ overflow: visible;
5908
+ padding-bottom: 0;
5909
+ }
5826
5910
  .modal-content .modal-footer {
5827
5911
  display: flex;
5828
5912
  align-items: center;
@@ -5866,187 +5950,232 @@ body {
5866
5950
  padding: 1rem 1.25rem;
5867
5951
  border-top: 1px solid var(--color-border-primary);
5868
5952
  }
5869
- .dir-picker-input {
5870
- width: 100%;
5871
- padding: 0.5rem 0.75rem;
5872
- border: 1px solid var(--color-border-primary);
5873
- border-radius: 6px;
5953
+ /* ── Dir Picker — Finder-style ────────────────────────────────────── */
5954
+ .dp-modal {
5955
+ max-width: 680px;
5956
+ width: 680px;
5957
+ max-height: 85vh;
5958
+ display: flex;
5959
+ flex-direction: column;
5960
+ padding: 0;
5961
+ overflow: hidden;
5962
+ border-radius: 10px;
5963
+ }
5964
+
5965
+ /* Toolbar */
5966
+ .dp-toolbar {
5967
+ display: flex;
5968
+ align-items: center;
5969
+ gap: 0.5rem;
5970
+ padding: 0.625rem 1rem;
5971
+ border-bottom: 1px solid var(--color-border-primary);
5972
+ background: var(--color-bg-secondary);
5973
+ flex-shrink: 0;
5974
+ }
5975
+ .dp-nav-btns {
5976
+ display: flex;
5977
+ gap: 2px;
5978
+ }
5979
+ .dp-nav-btn {
5980
+ display: inline-flex;
5981
+ align-items: center;
5982
+ justify-content: center;
5983
+ width: 26px;
5984
+ height: 26px;
5985
+ padding: 0;
5986
+ border: 1px solid rgba(0,0,0,0.18);
5987
+ border-radius: 5px;
5874
5988
  background: var(--color-bg-primary);
5875
5989
  color: var(--color-text-primary);
5876
- font-size: 0.875rem;
5877
- font-family: var(--font-mono, monospace);
5878
- transition: border-color 0.15s;
5879
- box-sizing: border-box;
5880
- }.dir-picker-input:focus {
5881
- outline: none;
5882
- border-color: var(--color-accent);
5990
+ cursor: pointer;
5991
+ transition: background 0.1s;
5883
5992
  }
5884
- .dir-picker-input::placeholder {
5885
- color: var(--color-text-tertiary);
5993
+ .dp-nav-btn:hover:not(:disabled) {
5994
+ background: var(--color-bg-hover);
5886
5995
  }
5887
- .dp-hidden-toggle {
5996
+ .dp-nav-btn:disabled {
5997
+ opacity: 0.3;
5998
+ cursor: not-allowed;
5999
+ }
6000
+ /* Breadcrumb */
6001
+ .dp-breadcrumb {
5888
6002
  display: flex;
5889
6003
  align-items: center;
5890
- gap: 0.375rem;
6004
+ gap: 0;
6005
+ flex: 1;
6006
+ min-width: 0;
6007
+ overflow-x: auto;
6008
+ overflow-y: hidden;
6009
+ scrollbar-width: none; /* Firefox */
6010
+ -ms-overflow-style: none; /* IE */
6011
+ /* Left fade mask when content overflows */
6012
+ -webkit-mask-image: linear-gradient(to right, transparent 0px, black 32px);
6013
+ mask-image: linear-gradient(to right, transparent 0px, black 32px);
6014
+ }
6015
+ .dp-breadcrumb::-webkit-scrollbar {
6016
+ display: none;
6017
+ }
6018
+ .dp-bc-seg {
5891
6019
  font-size: 0.8125rem;
5892
6020
  color: var(--color-text-secondary);
5893
6021
  cursor: pointer;
5894
- user-select: none;
6022
+ white-space: nowrap;
6023
+ padding: 3px 6px;
6024
+ border-radius: 4px;
6025
+ transition: background 0.1s, color 0.1s;
5895
6026
  }
5896
- .dp-hidden-toggle input {
5897
- cursor: pointer;
5898
- margin: 0;
6027
+ .dp-bc-seg:hover {
6028
+ background: rgba(0,0,0,0.07);
6029
+ color: var(--color-text-primary);
5899
6030
  }
5900
- /* Preset buttons row */
5901
- .dp-presets {
5902
- display: flex;
5903
- gap: 0.5rem;
5904
- flex-wrap: wrap;
6031
+ .dp-bc-current {
6032
+ color: var(--color-text-primary);
6033
+ font-weight: 500;
6034
+ cursor: default;
5905
6035
  }
5906
- .dp-presets .btn-sm {
5907
- padding: 0.25rem 0.625rem;
5908
- font-size: 0.75rem;
6036
+ .dp-bc-current:hover {
6037
+ background: transparent;
5909
6038
  }
5910
- .dp-up-btn {
6039
+ .dp-bc-sep {
5911
6040
  display: inline-flex;
5912
6041
  align-items: center;
5913
- gap: 0.25rem;
5914
- }
5915
- .dp-up-btn svg { flex-shrink: 0; }
5916
- .dp-up-btn:disabled {
5917
- opacity: 0.45;
5918
- cursor: not-allowed;
6042
+ color: var(--color-text-tertiary);
6043
+ flex-shrink: 0;
5919
6044
  }
5920
- /* Path input container */
5921
- .dp-path-container {
6045
+ .dp-bc-folder-icon {
6046
+ display: inline-flex;
6047
+ align-items: center;
6048
+ color: var(--color-text-secondary);
6049
+ margin-right: 3px;
5922
6050
  flex-shrink: 0;
5923
- position: relative;
5924
- }/* Autocomplete dropdown */
5925
- .dp-autocomplete {
5926
- position: absolute;
5927
- top: 100%;
5928
- left: 0;
5929
- right: 0;
5930
- z-index: 10;
5931
- max-height: 200px;
5932
- overflow-y: auto;
5933
- background: var(--color-bg-primary);
5934
- border: 1px solid var(--color-border-primary);
5935
- border-top: none;
5936
- border-radius: 0 0 6px 6px;
5937
- box-shadow: 0 4px 12px rgba(0,0,0,0.15);
5938
6051
  }
5939
- .dp-ac-item {
6052
+
6053
+ /* Column header */
6054
+ .dp-col-header {
5940
6055
  display: flex;
5941
6056
  align-items: center;
5942
- gap: 0.5rem;
5943
- padding: 0.4rem 0.75rem;
5944
- cursor: pointer;
5945
- font-size: 0.8125rem;
5946
- color: var(--color-text-primary);
5947
- transition: background 0.1s;
6057
+ padding: 0.3rem 1rem;
6058
+ border-bottom: 1px solid var(--color-border-primary);
6059
+ background: var(--color-bg-secondary);
6060
+ flex-shrink: 0;
5948
6061
  }
5949
- .dp-ac-item:hover,
5950
- .dp-ac-item.active {
5951
- background: var(--color-bg-hover);
6062
+ .dp-col-name {
6063
+ flex: 1;
6064
+ font-size: 0.75rem;
6065
+ font-weight: 600;
6066
+ color: var(--color-text-tertiary);
6067
+ text-transform: uppercase;
6068
+ letter-spacing: 0.04em;
5952
6069
  }
5953
- .dp-ac-icon {
5954
- display: inline-flex;
6070
+
6071
+ /* Hidden-files toggle (in header) */
6072
+ .dp-hidden-toggle {
6073
+ display: flex;
5955
6074
  align-items: center;
5956
- flex-shrink: 0;
5957
- color: var(--color-text-secondary);
6075
+ gap: 0.375rem;
6076
+ font-size: 0.75rem;
6077
+ color: var(--color-text-tertiary);
6078
+ cursor: pointer;
6079
+ user-select: none;
5958
6080
  }
5959
- .dp-ac-name {
5960
- overflow: hidden;
5961
- text-overflow: ellipsis;
5962
- white-space: nowrap;
6081
+ .dp-hidden-toggle input {
6082
+ cursor: pointer;
6083
+ margin: 0;
5963
6084
  }
5964
- /* Tree container */
5965
- .dp-tree {
5966
- border: 1px solid var(--color-border-primary);
5967
- border-radius: 6px;
5968
- background: var(--color-bg-secondary);
5969
- min-height: 200px;
5970
- max-height: 340px;
5971
- overflow: auto;
5972
- font-size: 0.8125rem;
6085
+
6086
+ /* List area */
6087
+ .dp-list {
6088
+ flex: 1;
6089
+ overflow-y: auto;
6090
+ min-height: 320px;
6091
+ padding-top: 0.35rem;
6092
+ background: var(--color-bg-primary);
5973
6093
  }
5974
- /* Tree node */
5975
6094
  .dp-node {
5976
6095
  user-select: none;
5977
6096
  }
5978
6097
  .dp-row {
5979
6098
  display: flex;
5980
6099
  align-items: center;
5981
- gap: 0.375rem;
5982
- padding: 0.375rem 0.5rem;
6100
+ gap: 0.5rem;
6101
+ padding: 0.4rem 0.75rem;
6102
+ margin: 0 0.5rem;
6103
+ border-radius: 6px;
5983
6104
  cursor: pointer;
5984
- border-radius: 4px;
5985
- transition: background 0.1s;
6105
+ transition: background 0.08s;
5986
6106
  }
5987
6107
  .dp-row:hover {
5988
6108
  background: var(--color-bg-hover);
5989
6109
  }
5990
6110
  .dp-row.selected {
5991
- background: var(--color-accent-subtle, rgba(59, 130, 246, 0.12));
6111
+ background: var(--color-accent, #3b82f6);
5992
6112
  }
5993
6113
  .dp-row.selected .dp-name {
5994
- color: var(--color-accent);
6114
+ color: #fff;
5995
6115
  font-weight: 500;
5996
6116
  }
5997
- /* Caret */
5998
- .dp-caret {
5999
- display: inline-flex;
6000
- align-items: center;
6001
- justify-content: center;
6002
- width: 16px;
6003
- height: 16px;
6004
- flex-shrink: 0;
6005
- color: var(--color-text-tertiary);
6006
- transition: transform 0.15s;
6007
- }
6008
- .dp-caret.open {
6009
- transform: rotate(90deg);
6117
+ .dp-row.selected .dp-icon {
6118
+ color: rgba(255,255,255,0.85);
6010
6119
  }
6011
- /* Folder icon */
6012
6120
  .dp-icon {
6013
6121
  display: inline-flex;
6014
6122
  align-items: center;
6015
6123
  flex-shrink: 0;
6016
6124
  color: var(--color-text-secondary);
6017
6125
  }
6018
- .dp-row.selected .dp-icon {
6019
- color: var(--color-accent);
6020
- }
6021
- /* Name */
6022
6126
  .dp-name {
6023
6127
  flex: 1;
6024
6128
  overflow: hidden;
6025
6129
  text-overflow: ellipsis;
6026
6130
  white-space: nowrap;
6027
6131
  color: var(--color-text-primary);
6132
+ font-size: 0.875rem;
6133
+ }
6134
+ .dp-name-input {
6135
+ flex: 1;
6136
+ border: 1px solid var(--color-accent, #3b82f6);
6137
+ border-radius: 4px;
6138
+ padding: 1px 4px;
6139
+ font-size: 0.875rem;
6140
+ background: var(--color-bg-primary);
6141
+ color: var(--color-text-primary);
6142
+ outline: none;
6028
6143
  }
6029
- /* Children container */
6030
- .dp-children {
6031
- display: flex;
6032
- flex-direction: column;
6033
- }/* Loading / empty / error states */
6034
6144
  .dp-loading,
6035
6145
  .dp-empty,
6036
6146
  .dp-error {
6037
- padding: 0.5rem 1rem;
6147
+ padding: 2rem 1rem;
6148
+ text-align: center;
6038
6149
  color: var(--color-text-tertiary);
6039
- font-size: 0.75rem;
6040
- font-style: italic;
6041
- }
6042
- .dp-error {
6043
- color: var(--color-text-danger, #ef4444);
6150
+ font-size: 0.8125rem;
6044
6151
  }
6045
- /* Model name combobox */
6046
- .model-name-combobox {
6047
- position: relative;
6152
+ .dp-error { color: var(--color-text-danger, #ef4444); }
6153
+
6154
+ /* Footer */
6155
+ .dp-footer {
6048
6156
  display: flex;
6049
- gap: 0;
6157
+ align-items: center;
6158
+ justify-content: space-between;
6159
+ padding: 0.75rem 1rem;
6160
+ border-top: 1px solid var(--color-border-primary);
6161
+ background: var(--color-bg-secondary);
6162
+ flex-shrink: 0;
6163
+ }
6164
+ .dp-footer-actions {
6165
+ display: flex;
6166
+ gap: 0.5rem;
6167
+ }
6168
+ .dp-newfolder-btn {
6169
+ display: inline-flex;
6170
+ align-items: center;
6171
+ gap: 0.25rem;
6172
+ font-size: 0.8125rem;
6173
+ }
6174
+ /* Model name combobox */
6175
+ .model-name-combobox {
6176
+ position: relative;
6177
+ display: flex;
6178
+ gap: 0;
6050
6179
  border: 1px solid var(--color-border-primary);
6051
6180
  border-radius: 7px;
6052
6181
  transition: border-color .15s, box-shadow .15s;
@@ -6206,6 +6335,9 @@ body {
6206
6335
  font-size: 0.75rem;
6207
6336
  flex: 1;
6208
6337
  }
6338
+ .model-test-result:empty {
6339
+ display: none;
6340
+ }
6209
6341
  .result-ok { color: var(--color-success); }
6210
6342
  .result-fail { color: var(--color-error); }
6211
6343
  .result-testing { color: var(--color-text-secondary); }
@@ -7435,7 +7567,7 @@ body {
7435
7567
  }
7436
7568
  .extensions-filter-tab-active {
7437
7569
  color: var(--color-text-primary);
7438
- border-bottom-color: var(--color-accent, #6366f1);
7570
+ border-bottom-color: var(--color-accent-primary);
7439
7571
  }
7440
7572
  .extensions-search {
7441
7573
  flex: 1;
@@ -8170,6 +8302,127 @@ body {
8170
8302
  border-radius: 4px;
8171
8303
  }
8172
8304
 
8305
+ /* ── Markdown split-pane layout ─────────────────────────────────────────── */
8306
+ .code-editor-modal--md {
8307
+ max-width: 1280px;
8308
+ width: 98%;
8309
+ height: 90vh;
8310
+ max-height: 960px;
8311
+ }
8312
+ .code-editor-body--split {
8313
+ display: flex;
8314
+ flex-direction: row;
8315
+ overflow: hidden;
8316
+ }
8317
+ .code-editor-split-left {
8318
+ flex: 1;
8319
+ min-width: 0;
8320
+ overflow: hidden;
8321
+ border-right: 1px solid var(--color-border-primary);
8322
+ display: flex;
8323
+ flex-direction: column;
8324
+ }
8325
+ .code-editor-split-left .cm-editor {
8326
+ height: 100%;
8327
+ flex: 1;
8328
+ }
8329
+ .code-editor-split-left > .cm-editor {
8330
+ height: 100%;
8331
+ }
8332
+ .code-editor-split-divider {
8333
+ display: none;
8334
+ }
8335
+ .code-editor-split-right {
8336
+ flex: 1;
8337
+ min-width: 0;
8338
+ display: flex;
8339
+ flex-direction: column;
8340
+ overflow: hidden;
8341
+ }
8342
+ .code-editor-markdown-preview {
8343
+ flex: 1;
8344
+ overflow-y: auto;
8345
+ padding: 0 1.25rem;
8346
+ font-size: 0.875rem;
8347
+ line-height: 1.7;
8348
+ color: var(--color-text-primary);
8349
+ }
8350
+ .code-editor-markdown-preview h1,
8351
+ .code-editor-markdown-preview h2,
8352
+ .code-editor-markdown-preview h3,
8353
+ .code-editor-markdown-preview h4 {
8354
+ margin-top: 1.25em;
8355
+ margin-bottom: 0.5em;
8356
+ font-weight: 600;
8357
+ }
8358
+ .code-editor-markdown-preview h1:first-child,
8359
+ .code-editor-markdown-preview h2:first-child,
8360
+ .code-editor-markdown-preview h3:first-child { margin-top: 0; }
8361
+ .code-editor-markdown-preview h1 { font-size: 1.375rem; }
8362
+ .code-editor-markdown-preview h2 { font-size: 1.125rem; border-bottom: 1px solid var(--color-border); padding-bottom: 0.25em; }
8363
+ .code-editor-markdown-preview h3 { font-size: 1rem; }
8364
+ .code-editor-markdown-preview p { margin: 0.5em 0; }
8365
+ .code-editor-markdown-preview ul,
8366
+ .code-editor-markdown-preview ol { padding-left: 1.5em; margin: 0.5em 0; }
8367
+ .code-editor-markdown-preview li { margin: 0.2em 0; }
8368
+ .code-editor-markdown-preview code {
8369
+ font-family: var(--font-mono, 'SF Mono', 'Fira Code', monospace);
8370
+ font-size: 0.8125em;
8371
+ background: rgba(128, 128, 128, 0.15);
8372
+ border-radius: 4px;
8373
+ padding: 0.15em 0.4em;
8374
+ }
8375
+ .code-editor-markdown-preview pre {
8376
+ background: rgba(128, 128, 128, 0.15);
8377
+ border-radius: 8px;
8378
+ padding: 0.875em;
8379
+ overflow-x: auto;
8380
+ margin: 0.625em 0;
8381
+ }
8382
+ .code-editor-markdown-preview pre code {
8383
+ background: none;
8384
+ padding: 0;
8385
+ font-size: 0.8125rem;
8386
+ }
8387
+ .code-editor-markdown-preview blockquote {
8388
+ border-left: 3px solid var(--color-accent-primary, #7c3aed);
8389
+ margin: 0.75em 0;
8390
+ padding: 0.25em 1em;
8391
+ color: var(--color-text-secondary);
8392
+ }
8393
+ .code-editor-markdown-preview a {
8394
+ color: var(--color-accent-primary);
8395
+ text-decoration: none;
8396
+ }
8397
+ .code-editor-markdown-preview a:hover { text-decoration: underline; }
8398
+ .code-editor-markdown-preview img {
8399
+ display: inline;
8400
+ vertical-align: middle;
8401
+ max-width: 100%;
8402
+ height: auto;
8403
+ }
8404
+ .code-editor-markdown-preview hr {
8405
+ border: none;
8406
+ border-top: 1px solid var(--color-border-primary);
8407
+ margin: 1.25em 0;
8408
+ }
8409
+ .code-editor-markdown-preview table {
8410
+ border-collapse: collapse;
8411
+ width: 100%;
8412
+ margin: 0.75em 0;
8413
+ font-size: 0.8125rem;
8414
+ }
8415
+ .code-editor-markdown-preview th,
8416
+ .code-editor-markdown-preview td {
8417
+ border: 1px solid var(--color-border-primary);
8418
+ padding: 0.375em 0.75em;
8419
+ text-align: left;
8420
+ }
8421
+ .code-editor-markdown-preview th {
8422
+ background: rgba(128, 128, 128, 0.15);
8423
+ font-weight: 600;
8424
+ }
8425
+
8173
8426
  /* ── Skills sidebar section ──────────────────────────────────────────────── */
8174
8427
  #skill-list-items { padding: 0 0.5rem 0.5rem; display: flex; flex-direction: column; gap: 2px; }
8175
8428
 
@@ -8959,6 +9212,42 @@ body.setup-mode[data-theme="dark"] {
8959
9212
  }
8960
9213
 
8961
9214
  /* ── Brand & License settings section ───────────────────────────────────── */
9215
+ .platform-source-card {
9216
+ background: var(--color-bg-secondary);
9217
+ border: 1px solid var(--color-border-primary);
9218
+ border-radius: 10px;
9219
+ padding: 1rem 1.25rem;
9220
+ display: flex;
9221
+ flex-direction: column;
9222
+ gap: 0.75rem;
9223
+ }
9224
+ .platform-source-desc {
9225
+ font-size: 0.8125rem;
9226
+ color: var(--color-text-secondary);
9227
+ line-height: 1.5;
9228
+ margin: 0;
9229
+ }
9230
+ .platform-source-field {
9231
+ display: flex;
9232
+ flex-direction: column;
9233
+ gap: 0.375rem;
9234
+ }
9235
+ .platform-source-label {
9236
+ font-size: 0.75rem;
9237
+ color: var(--color-text-secondary);
9238
+ }
9239
+ .platform-source-row {
9240
+ display: flex;
9241
+ align-items: center;
9242
+ gap: 0.5rem;
9243
+ flex-wrap: wrap;
9244
+ }
9245
+ .platform-source-row .field-input {
9246
+ flex: 1;
9247
+ min-width: 12rem;
9248
+ font-family: var(--font-mono, monospace);
9249
+ }
9250
+
8962
9251
  .brand-status-card {
8963
9252
  background: var(--color-bg-secondary);
8964
9253
  border: 1px solid var(--color-border-primary);
@@ -10600,6 +10889,28 @@ body.setup-mode[data-theme="dark"] {
10600
10889
  font-size: 0.6875rem;
10601
10890
  color: var(--color-text-muted);
10602
10891
  }
10892
+ .trash-session-project-badge {
10893
+ display: inline-flex;
10894
+ align-items: center;
10895
+ gap: 0.25rem;
10896
+ padding: 0.125rem 0.4rem;
10897
+ border-radius: 4px;
10898
+ background: var(--color-bg-tertiary, var(--color-bg-primary));
10899
+ border: 1px solid var(--color-border-primary);
10900
+ color: var(--color-text-secondary);
10901
+ font-size: 0.625rem;
10902
+ white-space: nowrap;
10903
+ max-width: 8rem;
10904
+ overflow: hidden;
10905
+ text-overflow: ellipsis;
10906
+ }
10907
+ .trash-session-project-dot {
10908
+ width: 6px;
10909
+ height: 6px;
10910
+ border-radius: 50%;
10911
+ background: var(--color-text-muted);
10912
+ flex-shrink: 0;
10913
+ }
10603
10914
  .trash-session-card-actions {
10604
10915
  display: flex;
10605
10916
  align-items: center;
@@ -10697,6 +11008,38 @@ body.setup-mode[data-theme="dark"] {
10697
11008
  border-color: var(--color-accent-primary);
10698
11009
  color: #fff;
10699
11010
  }
11011
+ /* Project filter dropdown */
11012
+ .trash-filter-project-wrap {
11013
+ display: inline-flex;
11014
+ align-items: center;
11015
+ gap: 0.3rem;
11016
+ padding: 0.2rem 0.45rem 0.2rem 0.55rem;
11017
+ border-radius: 5px;
11018
+ border: 1px solid var(--color-border-primary);
11019
+ background: transparent;
11020
+ color: var(--color-text-muted);
11021
+ cursor: pointer;
11022
+ transition: border-color 0.14s, color 0.14s;
11023
+ }
11024
+ .trash-filter-project-wrap:focus-within {
11025
+ border-color: var(--color-accent-primary);
11026
+ color: var(--color-text-primary);
11027
+ }
11028
+ .trash-filter-project-icon {
11029
+ flex-shrink: 0;
11030
+ pointer-events: none;
11031
+ }
11032
+ .trash-filter-project-select {
11033
+ font-size: 0.6875rem;
11034
+ color: inherit;
11035
+ background: transparent;
11036
+ border: none;
11037
+ outline: none;
11038
+ cursor: pointer;
11039
+ padding: 0;
11040
+ max-width: 130px;
11041
+ appearance: auto;
11042
+ }
10700
11043
  .trash-actions {
10701
11044
  display: flex;
10702
11045
  align-items: center;
@@ -11055,7 +11398,7 @@ body.setup-mode[data-theme="dark"] {
11055
11398
  .billing-share-btn:hover {
11056
11399
  background: var(--color-bg-tertiary);
11057
11400
  color: var(--color-text-primary);
11058
- border-color: var(--color-text-secondary);
11401
+ border-color: var(--color-accent-primary);
11059
11402
  }
11060
11403
  .billing-clear-popup {
11061
11404
  position: absolute;
@@ -12858,7 +13201,7 @@ body.setup-mode[data-theme="dark"] {
12858
13201
  margin-left: 0 !important;
12859
13202
  }
12860
13203
  /* active session: always show ⋯ button (no hover on touch) */
12861
- .session-item.active .session-actions-btn { display: flex; }
13204
+ .session-item.active .session-actions-btn { width: 1.5rem; opacity: 1; pointer-events: auto; }
12862
13205
  #sidebar.hidden {
12863
13206
  transform: translateX(-100%);
12864
13207
  margin-left: 0 !important;
@@ -13354,3 +13697,570 @@ body.setup-mode[data-theme="dark"] {
13354
13697
  background: var(--color-bg-primary);
13355
13698
  }
13356
13699
  }
13700
+
13701
+ /* ══════════════════════════════════════════════════════════════════════════════
13702
+ Projects sidebar section
13703
+ ══════════════════════════════════════════════════════════════════════════════ */
13704
+
13705
+ /* ── Empty hint ────────────────────────────────────────────────────────────── */
13706
+ .project-empty-hint {
13707
+ padding: 0.375rem 0.75rem;
13708
+ font-size: 0.75rem;
13709
+ color: var(--color-text-muted);
13710
+ }
13711
+
13712
+ /* ── Section-level collapse ────────────────────────────────────────────────── */
13713
+ .projects-section-title {
13714
+ display: inline-flex;
13715
+ align-items: center;
13716
+ gap: 3px;
13717
+ cursor: pointer;
13718
+ }
13719
+ .projects-section-chevron {
13720
+ flex-shrink: 0;
13721
+ color: var(--color-text-muted);
13722
+ opacity: 0;
13723
+ transition: transform 0.2s ease, opacity 0.15s ease;
13724
+ margin-left: 1px;
13725
+ }
13726
+ #projects-section-header:hover .projects-section-chevron {
13727
+ opacity: 1;
13728
+ }
13729
+ .projects-section-collapsed .projects-section-chevron {
13730
+ opacity: 1;
13731
+ transform: rotate(-90deg);
13732
+ }
13733
+ .project-list-collapsed {
13734
+ display: none;
13735
+ }
13736
+
13737
+ /* ── Project group header row ──────────────────────────────────────────────── */
13738
+ .project-group-header {
13739
+ display: flex;
13740
+ align-items: center;
13741
+ gap: 0.375rem;
13742
+ padding: 0.3125rem 0.625rem;
13743
+ border-radius: var(--radius-sm);
13744
+ cursor: pointer;
13745
+ user-select: none;
13746
+ transition: background var(--transition-fast);
13747
+ }
13748
+ .project-group-header:hover {
13749
+ background: var(--color-bg-hover);
13750
+ }
13751
+
13752
+ .project-name {
13753
+ flex: 1;
13754
+ min-width: 0;
13755
+ overflow: hidden;
13756
+ text-overflow: ellipsis;
13757
+ white-space: nowrap;
13758
+ font-size: 0.8125rem;
13759
+ color: var(--color-text-primary);
13760
+ }
13761
+
13762
+ /* Actions button (⋯) — shown only on hover */
13763
+ .project-actions-btn {
13764
+ flex-shrink: 0;
13765
+ display: flex;
13766
+ align-items: center;
13767
+ justify-content: center;
13768
+ width: 0;
13769
+ height: 1.375rem;
13770
+ overflow: hidden;
13771
+ background: transparent;
13772
+ border: none;
13773
+ border-radius: 4px;
13774
+ color: var(--color-text-secondary);
13775
+ cursor: pointer;
13776
+ padding: 0;
13777
+ opacity: 0;
13778
+ pointer-events: none;
13779
+ transition: background var(--transition-fast), color var(--transition-fast), opacity var(--transition-fast), width var(--transition-fast);
13780
+ }
13781
+ .project-group-header:hover .project-actions-btn {
13782
+ width: 1.375rem;
13783
+ opacity: 1;
13784
+ pointer-events: auto;
13785
+ }
13786
+ .project-actions-btn:hover {
13787
+ background: var(--color-border-primary);
13788
+ color: var(--color-text-primary);
13789
+ }
13790
+
13791
+ /* ── Session group (indented children) ────────────────────────────────────── */
13792
+ .project-session-group {
13793
+ padding-left: 0.875rem;
13794
+ margin-top: 0.08rem;
13795
+ }
13796
+
13797
+ .project-sessions-empty {
13798
+ padding: 0.25rem 0.5rem 0.25rem 0.625rem;
13799
+ font-size: 0.75rem;
13800
+ color: var(--color-text-muted);
13801
+ }
13802
+
13803
+ /* ── Project hover tooltip ─────────────────────────────────────────────────── */
13804
+ .project-tooltip {
13805
+ position: fixed;
13806
+ z-index: 1200;
13807
+ background: var(--color-bg-secondary);
13808
+ border: 1px solid var(--color-border-primary);
13809
+ border-radius: 10px;
13810
+ box-shadow: 0 8px 24px rgba(0,0,0,.10), 0 2px 8px rgba(0,0,0,.06);
13811
+ padding: 0.75rem 0.875rem 0.75rem 1.125rem; /* extra left padding = visual gap */
13812
+ min-width: 13rem;
13813
+ max-width: 18rem;
13814
+ animation: fadeIn 0.12s ease;
13815
+ }
13816
+ /* Transparent bridge on the left side fills the gap between sidebar and tooltip */
13817
+ .project-tooltip::before {
13818
+ content: "";
13819
+ position: absolute;
13820
+ top: 0;
13821
+ left: -8px;
13822
+ width: 8px;
13823
+ height: 100%;
13824
+ }
13825
+ [data-theme="dark"] .project-tooltip {
13826
+ box-shadow: 0 8px 28px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.35);
13827
+ }
13828
+
13829
+ .project-tooltip-header {
13830
+ display: flex;
13831
+ align-items: center;
13832
+ gap: 0.4rem;
13833
+ margin-bottom: 0.75rem;
13834
+ }
13835
+ .project-tooltip-icon {
13836
+ flex-shrink: 0;
13837
+ display: flex;
13838
+ align-items: center;
13839
+ justify-content: center;
13840
+ color: var(--color-text-secondary);
13841
+ line-height: 0;
13842
+ }
13843
+ .project-tooltip-icon svg {
13844
+ display: block;
13845
+ flex-shrink: 0;
13846
+ }
13847
+ .project-tooltip-name {
13848
+ flex: 1;
13849
+ min-width: 0;
13850
+ font-size: 0.8125rem;
13851
+ font-weight: 600;
13852
+ color: var(--color-text-primary);
13853
+ overflow: hidden;
13854
+ text-overflow: ellipsis;
13855
+ white-space: nowrap;
13856
+ }
13857
+ .project-tooltip-rows {
13858
+ display: flex;
13859
+ flex-direction: column;
13860
+ gap: 0.3rem;
13861
+ }
13862
+ .project-tooltip-row {
13863
+ display: flex;
13864
+ align-items: center;
13865
+ gap: 0.4rem;
13866
+ font-size: 0.75rem;
13867
+ color: var(--color-text-secondary);
13868
+ min-width: 0;
13869
+ }
13870
+ .project-tooltip-row--clickable {
13871
+ cursor: pointer;
13872
+ border-radius: 4px;
13873
+ margin: 0 -0.25rem;
13874
+ padding: 0.15rem 0.25rem;
13875
+ transition: background var(--transition-fast);
13876
+ }
13877
+ .project-tooltip-row--clickable:hover {
13878
+ background: var(--color-bg-hover);
13879
+ }
13880
+
13881
+ .project-tooltip-divider {
13882
+ height: 1px;
13883
+ background: var(--color-border-primary);
13884
+ margin: 0.25rem 0;
13885
+ }
13886
+
13887
+ .project-tooltip-row-icon {
13888
+ flex-shrink: 0;
13889
+ color: var(--color-text-muted);
13890
+ display: flex;
13891
+ align-items: center;
13892
+ line-height: 0;
13893
+ }
13894
+ .project-tooltip-row-icon svg {
13895
+ display: block;
13896
+ flex-shrink: 0;
13897
+ }
13898
+ .project-tooltip-row-text {
13899
+ min-width: 0;
13900
+ overflow: hidden;
13901
+ text-overflow: ellipsis;
13902
+ white-space: nowrap;
13903
+ line-height: 1.4;
13904
+ }
13905
+
13906
+ /* ── Project context menu (rename / delete) ────────────────────────────────── */
13907
+ .project-actions-menu {
13908
+ background: var(--color-bg-secondary);
13909
+ border: 1px solid var(--color-border-primary);
13910
+ border-radius: 8px;
13911
+ box-shadow: 0 6px 20px rgba(0,0,0,.08), 0 2px 6px rgba(0,0,0,.04);
13912
+ padding: 0.25rem;
13913
+ min-width: 9rem;
13914
+ z-index: 1000;
13915
+ animation: fadeIn 0.15s ease;
13916
+ }
13917
+ [data-theme="dark"] .project-actions-menu {
13918
+ box-shadow: 0 8px 24px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.3);
13919
+ }
13920
+ .project-actions-menu-item {
13921
+ display: block;
13922
+ width: 100%;
13923
+ padding: 0.375rem 0.625rem;
13924
+ border: none;
13925
+ background: transparent;
13926
+ border-radius: 5px;
13927
+ cursor: pointer;
13928
+ color: var(--color-text-primary);
13929
+ font-size: 0.8125rem;
13930
+ text-align: left;
13931
+ transition: background .12s ease, color .12s ease;
13932
+ }
13933
+ .project-actions-menu-item:hover {
13934
+ background: var(--color-bg-hover);
13935
+ }
13936
+ .project-actions-menu-item.danger {
13937
+ color: var(--color-error);
13938
+ margin-top: 0.25rem;
13939
+ position: relative;
13940
+ }
13941
+ .project-actions-menu-item.danger::before {
13942
+ content: "";
13943
+ position: absolute;
13944
+ left: 0;
13945
+ right: 0;
13946
+ top: -0.1875rem;
13947
+ height: 1px;
13948
+ background: var(--color-border-secondary);
13949
+ }
13950
+ .project-actions-menu-item.danger:hover {
13951
+ background: var(--color-error-bg);
13952
+ }
13953
+
13954
+ /* ── Organize menu (view-mode toggle) ──────────────────────────────────────── */
13955
+ .project-organize-menu {
13956
+ background: var(--color-bg-secondary);
13957
+ border: 1px solid var(--color-border-primary);
13958
+ border-radius: 8px;
13959
+ box-shadow: 0 6px 20px rgba(0,0,0,.08), 0 2px 6px rgba(0,0,0,.04);
13960
+ padding: 0.25rem;
13961
+ min-width: 10rem;
13962
+ z-index: 1000;
13963
+ animation: fadeIn 0.15s ease;
13964
+ }
13965
+ [data-theme="dark"] .project-organize-menu {
13966
+ box-shadow: 0 8px 24px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.3);
13967
+ }
13968
+ .project-organize-divider {
13969
+ height: 1px;
13970
+ background: var(--color-border-primary);
13971
+ margin: 0.25rem 0.375rem;
13972
+ }
13973
+ .project-organize-section-label {
13974
+ padding: 0.25rem 0.625rem 0.125rem;
13975
+ font-size: 0.6875rem;
13976
+ color: var(--color-text-secondary);
13977
+ font-weight: 500;
13978
+ letter-spacing: 0.01em;
13979
+ }
13980
+ .project-organize-item {
13981
+ display: block;
13982
+ width: 100%;
13983
+ padding: 0.375rem 0.625rem;
13984
+ border: none;
13985
+ background: transparent;
13986
+ border-radius: 5px;
13987
+ cursor: pointer;
13988
+ color: var(--color-text-primary);
13989
+ font-size: 0.8125rem;
13990
+ text-align: left;
13991
+ transition: background .12s ease, color .12s ease;
13992
+ }
13993
+ .project-organize-item:hover {
13994
+ background: var(--color-bg-hover);
13995
+ }
13996
+ .project-organize-item.active {
13997
+ color: var(--color-accent-primary);
13998
+ font-weight: 500;
13999
+ }
14000
+
14001
+ /* ── Flat mode ─────────────────────────────────────────────────────────────── */
14002
+ .project-session-tag {
14003
+ padding: 0 0.625rem 0.1rem;
14004
+ font-size: 0.6875rem;
14005
+ font-weight: 500;
14006
+ color: var(--project-color, var(--color-accent-primary));
14007
+ opacity: 0.85;
14008
+ white-space: nowrap;
14009
+ overflow: hidden;
14010
+ text-overflow: ellipsis;
14011
+ }
14012
+
14013
+ /* ── Project icon badge (sidebar header) ─────────────────────────────────── */
14014
+ .project-icon-badge {
14015
+ display: inline-flex;
14016
+ align-items: center;
14017
+ justify-content: center;
14018
+ flex-shrink: 0;
14019
+ width: 1rem;
14020
+ height: 1rem;
14021
+ }
14022
+ .project-icon-badge svg {
14023
+ display: block;
14024
+ }
14025
+
14026
+ /* ── Create-project modal: input row (trigger + name input) ──────────────── */
14027
+ .create-project-input-row {
14028
+ display: flex;
14029
+ align-items: center;
14030
+ gap: 0.5rem;
14031
+ }
14032
+
14033
+ /* Trigger button (icon preview) */
14034
+ .project-icon-trigger {
14035
+ flex-shrink: 0;
14036
+ display: inline-flex;
14037
+ align-items: center;
14038
+ justify-content: center;
14039
+ width: 2.25rem;
14040
+ height: 2.25rem;
14041
+ border-radius: 6px;
14042
+ border: 1px solid var(--color-border-primary);
14043
+ background: transparent;
14044
+ color: var(--color-text-primary);
14045
+ cursor: pointer;
14046
+ padding: 0;
14047
+ transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.1s;
14048
+ }
14049
+ .project-icon-trigger:hover {
14050
+ background: var(--color-bg-hover);
14051
+ border-color: var(--color-border-secondary);
14052
+ }
14053
+ .project-icon-trigger svg {
14054
+ display: block;
14055
+ pointer-events: none;
14056
+ }
14057
+
14058
+ /* Name input fills remaining space */
14059
+ .create-project-name-input {
14060
+ flex: 1;
14061
+ min-width: 0;
14062
+ }
14063
+
14064
+ /* Source folders section */
14065
+ .create-project-folder-section {
14066
+ margin-top: 0.75rem;
14067
+ }
14068
+
14069
+ .create-project-folder-label {
14070
+ font-size: 0.78rem;
14071
+ font-weight: 500;
14072
+ color: var(--color-text-secondary);
14073
+ margin-bottom: 0.4rem;
14074
+ }
14075
+
14076
+ .create-project-folder-area {
14077
+ border: 1px solid var(--color-border-primary);
14078
+ border-radius: var(--radius-md);
14079
+ background: var(--color-bg-secondary);
14080
+ min-height: 52px;
14081
+ display: flex;
14082
+ align-items: center;
14083
+ justify-content: center;
14084
+ padding: 0.4rem 0.6rem;
14085
+ cursor: pointer;
14086
+ transition: border-color 0.15s, background 0.15s;
14087
+ }
14088
+ .create-project-folder-area:hover {
14089
+ border-color: var(--color-border-secondary);
14090
+ background: var(--color-bg-hover);
14091
+ }
14092
+
14093
+ .create-project-folder-empty {
14094
+ display: flex;
14095
+ flex-direction: column;
14096
+ align-items: center;
14097
+ gap: 0.25rem;
14098
+ color: var(--color-text-muted);
14099
+ font-size: 0.78rem;
14100
+ pointer-events: none;
14101
+ }
14102
+ .create-project-folder-empty svg {
14103
+ opacity: 0.5;
14104
+ width: 18px;
14105
+ height: 18px;
14106
+ }
14107
+
14108
+ /* Selected folder card */
14109
+ .create-project-folder-card {
14110
+ display: flex;
14111
+ align-items: center;
14112
+ gap: 0.4rem;
14113
+ width: 100%;
14114
+ color: var(--color-text-primary);
14115
+ font-size: 0.8rem;
14116
+ cursor: default;
14117
+ }
14118
+ .create-project-folder-card > svg {
14119
+ flex-shrink: 0;
14120
+ color: var(--color-accent-primary);
14121
+ width: 14px;
14122
+ height: 14px;
14123
+ }
14124
+ .create-project-folder-name {
14125
+ flex: 1;
14126
+ min-width: 0;
14127
+ overflow: hidden;
14128
+ text-overflow: ellipsis;
14129
+ white-space: nowrap;
14130
+ }
14131
+ .create-project-folder-remove {
14132
+ flex-shrink: 0;
14133
+ display: inline-flex;
14134
+ align-items: center;
14135
+ justify-content: center;
14136
+ width: 1.25rem;
14137
+ height: 1.25rem;
14138
+ border-radius: 4px;
14139
+ border: none;
14140
+ background: transparent;
14141
+ color: var(--color-text-muted);
14142
+ cursor: pointer;
14143
+ padding: 0;
14144
+ transition: background 0.12s, color 0.12s;
14145
+ }
14146
+ .create-project-folder-remove:hover {
14147
+ background: rgba(0, 0, 0, 0.09);
14148
+ color: var(--color-text-primary);
14149
+ }
14150
+
14151
+ /* ── Project picker popup (floating panel) ───────────────────────────────── */
14152
+ .project-picker-popup {
14153
+ display: none; /* hidden by default; JS shows it via style.display */
14154
+ position: fixed;
14155
+ z-index: 9999;
14156
+ background: var(--color-bg-primary);
14157
+ border: 1px solid var(--color-border);
14158
+ border-radius: var(--radius-md);
14159
+ box-shadow: 0 8px 24px rgba(0,0,0,0.18);
14160
+ padding: 0.75rem;
14161
+ user-select: none;
14162
+ }
14163
+
14164
+ /* "No color" option — grey with a diagonal slash */
14165
+ .project-picker-color-none {
14166
+ background: var(--color-bg-tertiary);
14167
+ position: relative;
14168
+ overflow: hidden;
14169
+ }
14170
+ .project-picker-color-none::after {
14171
+ content: "";
14172
+ position: absolute;
14173
+ inset: 0;
14174
+ background: linear-gradient(
14175
+ to bottom right,
14176
+ transparent calc(50% - 1px),
14177
+ var(--color-error) calc(50% - 1px),
14178
+ var(--color-error) calc(50% + 1px),
14179
+ transparent calc(50% + 1px)
14180
+ );
14181
+ }
14182
+
14183
+ /* Color row */
14184
+ .project-picker-colors {
14185
+ display: flex;
14186
+ flex-wrap: wrap;
14187
+ gap: 0.5rem;
14188
+ margin-bottom: 0.5rem;
14189
+ }
14190
+ .project-picker-color-option {
14191
+ width: 1.6rem;
14192
+ height: 1.6rem;
14193
+ border-radius: 50%;
14194
+ border: 2.5px solid transparent;
14195
+ cursor: pointer;
14196
+ padding: 0;
14197
+ transition: transform 0.1s, box-shadow 0.1s;
14198
+ flex-shrink: 0;
14199
+ }
14200
+ .project-picker-color-option:hover {
14201
+ transform: scale(1.15);
14202
+ }
14203
+ .project-picker-color-option--selected {
14204
+ box-shadow: 0 0 0 2px var(--color-bg-primary), 0 0 0 4px var(--color-text-primary);
14205
+ }
14206
+
14207
+ /* Divider */
14208
+ .project-picker-divider {
14209
+ height: 1px;
14210
+ background: var(--color-border);
14211
+ margin: 0.5rem 0;
14212
+ }
14213
+
14214
+ /* Icon grid */
14215
+ .project-picker-icons {
14216
+ display: grid;
14217
+ grid-template-columns: repeat(6, 1fr);
14218
+ gap: 0.25rem;
14219
+ }
14220
+ .project-picker-icon-option {
14221
+ display: inline-flex;
14222
+ align-items: center;
14223
+ justify-content: center;
14224
+ width: 2rem;
14225
+ height: 2rem;
14226
+ border-radius: var(--radius-sm);
14227
+ border: 1.5px solid transparent;
14228
+ background: transparent;
14229
+ color: var(--color-text-secondary);
14230
+ cursor: pointer;
14231
+ padding: 0;
14232
+ transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
14233
+ }
14234
+ .project-picker-icon-option:hover {
14235
+ background: var(--color-bg-hover);
14236
+ color: var(--color-text-primary);
14237
+ }
14238
+ .project-picker-icon-option--selected {
14239
+ background: var(--color-accent-subtle, rgba(236,72,153,0.12));
14240
+ border-color: var(--color-accent-primary);
14241
+ color: var(--color-accent-primary);
14242
+ }
14243
+ .project-picker-icon-option svg {
14244
+ pointer-events: none;
14245
+ }
14246
+
14247
+ /* Done button */
14248
+ .project-picker-footer {
14249
+ margin-top: 0.5rem;
14250
+ display: flex;
14251
+ justify-content: flex-end;
14252
+ }
14253
+ .project-picker-done-btn {
14254
+ font-size: 0.8125rem;
14255
+ padding: 0.3rem 0.875rem;
14256
+ border-radius: var(--radius-sm);
14257
+ border: 1px solid var(--color-border);
14258
+ background: var(--color-bg-secondary);
14259
+ color: var(--color-text-primary);
14260
+ cursor: pointer;
14261
+ transition: background var(--transition-fast);
14262
+ }
14263
+ .project-picker-done-btn:hover {
14264
+ background: var(--color-bg-hover);
14265
+ }
14266
+