collavre 0.11.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/collavre/actiontext.css +26 -12
  3. data/app/assets/stylesheets/collavre/code_highlight.css +208 -0
  4. data/app/assets/stylesheets/collavre/comment_snapshots.css +26 -0
  5. data/app/assets/stylesheets/collavre/comments_popup.css +158 -3
  6. data/app/assets/stylesheets/collavre/creatives.css +84 -25
  7. data/app/assets/stylesheets/collavre/gnb.css +0 -94
  8. data/app/assets/stylesheets/collavre/image_lightbox.css +141 -0
  9. data/app/assets/stylesheets/collavre/popup.css +53 -4
  10. data/app/assets/stylesheets/collavre/print.css +0 -1
  11. data/app/assets/stylesheets/collavre/search_popup.css +261 -0
  12. data/app/assets/stylesheets/collavre/trigger_status.css +17 -0
  13. data/app/channels/collavre/comments_presence_channel.rb +17 -0
  14. data/app/channels/collavre/creatives_channel.rb +80 -0
  15. data/app/components/collavre/inbox/badge_component.rb +33 -12
  16. data/app/components/collavre/popup_menu_component.html.erb +1 -1
  17. data/app/components/collavre/popup_menu_component.rb +3 -2
  18. data/app/controllers/collavre/admin/settings_controller.rb +12 -0
  19. data/app/controllers/collavre/comment_read_pointers_controller.rb +5 -17
  20. data/app/controllers/collavre/comments/snapshots_controller.rb +55 -0
  21. data/app/controllers/collavre/comments_controller.rb +88 -48
  22. data/app/controllers/collavre/concerns/shareable.rb +16 -8
  23. data/app/controllers/collavre/creatives_controller.rb +202 -4
  24. data/app/controllers/collavre/topics_controller.rb +3 -1
  25. data/app/controllers/concerns/collavre/users_controller/profile_and_settings.rb +0 -2
  26. data/app/helpers/collavre/application_helper.rb +42 -0
  27. data/app/helpers/collavre/creatives_helper.rb +4 -3
  28. data/app/javascript/collavre.js +0 -2
  29. data/app/javascript/components/InlineLexicalEditor.jsx +86 -2
  30. data/app/javascript/components/creative_tree_row.js +22 -3
  31. data/app/javascript/controllers/__tests__/popup_menu_controller.test.js +196 -0
  32. data/app/javascript/controllers/comment_badge_controller.js +30 -0
  33. data/app/javascript/controllers/comment_controller.js +32 -0
  34. data/app/javascript/controllers/comments/__tests__/form_controller_review.test.js +26 -0
  35. data/app/javascript/controllers/comments/__tests__/list_controller_selection.test.js +12 -0
  36. data/app/javascript/controllers/comments/__tests__/popup_controller.test.js +26 -1
  37. data/app/javascript/controllers/comments/__tests__/presence_controller.test.js +123 -0
  38. data/app/javascript/controllers/comments/__tests__/topics_controller_override.test.js +60 -0
  39. data/app/javascript/controllers/comments/drop_trigger_controller.js +249 -0
  40. data/app/javascript/controllers/comments/form_controller.js +20 -1
  41. data/app/javascript/controllers/comments/list_controller.js +22 -3
  42. data/app/javascript/controllers/comments/popup_controller.js +320 -3
  43. data/app/javascript/controllers/comments/presence_controller.js +96 -6
  44. data/app/javascript/controllers/comments/topics_controller.js +32 -2
  45. data/app/javascript/controllers/creatives/sync_controller.js +131 -0
  46. data/app/javascript/controllers/creatives/tree_controller.js +49 -0
  47. data/app/javascript/controllers/image_lightbox_controller.js +433 -0
  48. data/app/javascript/controllers/index.js +16 -4
  49. data/app/javascript/controllers/popup_menu_controller.js +69 -15
  50. data/app/javascript/controllers/search_popup_controller.js +138 -0
  51. data/app/javascript/creatives/tree_renderer.js +61 -2
  52. data/app/javascript/lib/__tests__/chat_history.test.js +152 -0
  53. data/app/javascript/lib/chat_history.js +194 -0
  54. data/app/javascript/lib/touch_drag.js +262 -0
  55. data/app/javascript/lib/turbo_stream_actions.js +325 -14
  56. data/app/javascript/lib/utils/markdown.js +111 -3
  57. data/app/javascript/modules/creative_row_editor.js +102 -2
  58. data/app/javascript/modules/inbox_panel.js +15 -227
  59. data/app/javascript/services/creatives_channel.js +77 -0
  60. data/app/jobs/collavre/ai_agent_job.rb +7 -7
  61. data/app/jobs/collavre/compress_job.rb +19 -3
  62. data/app/jobs/collavre/creative_broadcast_job.rb +247 -0
  63. data/app/jobs/collavre/cron_action_job.rb +3 -1
  64. data/app/jobs/collavre/drop_trigger_job.rb +174 -0
  65. data/app/jobs/collavre/merge_comments_job.rb +12 -1
  66. data/app/jobs/collavre/trigger_loop_check_job.rb +299 -0
  67. data/app/jobs/collavre/trigger_loop_verify_job.rb +185 -0
  68. data/app/jobs/concerns/collavre/comment_serializable.rb +30 -0
  69. data/app/jobs/concerns/collavre/trigger_loop_helpers.rb +41 -0
  70. data/app/models/collavre/comment/broadcastable.rb +32 -1
  71. data/app/models/collavre/comment/notifiable.rb +92 -26
  72. data/app/models/collavre/comment.rb +45 -0
  73. data/app/models/collavre/comment_snapshot.rb +26 -0
  74. data/app/models/collavre/creative/realtime_broadcastable.rb +256 -0
  75. data/app/models/collavre/creative.rb +59 -0
  76. data/app/models/collavre/creative_presence_store.rb +58 -0
  77. data/app/models/collavre/creative_share.rb +60 -11
  78. data/app/models/collavre/system_setting.rb +15 -0
  79. data/app/models/collavre/task.rb +28 -0
  80. data/app/models/collavre/user.rb +2 -4
  81. data/app/models/concerns/collavre/has_inbox_creative.rb +24 -0
  82. data/app/services/collavre/ai_agent/response_finalizer.rb +1 -0
  83. data/app/services/collavre/ai_agent_service.rb +2 -1
  84. data/app/services/collavre/comment_snapshot_restore_service.rb +81 -0
  85. data/app/services/collavre/creatives/create_service.rb +4 -0
  86. data/app/services/collavre/creatives/index_query.rb +2 -1
  87. data/app/services/collavre/creatives/tree_builder.rb +2 -1
  88. data/app/services/collavre/markdown_importer.rb +5 -0
  89. data/app/services/collavre/orchestration/stuck_detector.rb +13 -6
  90. data/app/services/collavre/tools/creative_create_service.rb +4 -0
  91. data/app/services/collavre/tools/creative_update_service.rb +20 -16
  92. data/app/views/collavre/admin/settings/_uiux_tab.html.erb +20 -0
  93. data/app/views/collavre/comments/_comment.html.erb +34 -4
  94. data/app/views/collavre/comments/_comments_popup.html.erb +25 -4
  95. data/app/views/collavre/creatives/index.html.erb +17 -22
  96. data/app/views/collavre/shared/_navigation.html.erb +27 -14
  97. data/app/views/collavre/shared/navigation/_help_button.html.erb +1 -1
  98. data/app/views/collavre/shared/navigation/_inbox_button.html.erb +13 -3
  99. data/app/views/collavre/shared/navigation/_mobile_inbox_button.html.erb +12 -1
  100. data/app/views/collavre/shared/navigation/_panels.html.erb +1 -11
  101. data/app/views/collavre/shared/navigation/_search_form.html.erb +108 -6
  102. data/app/views/collavre/users/show.html.erb +0 -8
  103. data/app/views/inbox/badge_component/_count.html.erb +5 -2
  104. data/config/locales/admin.en.yml +5 -0
  105. data/config/locales/admin.ko.yml +5 -0
  106. data/config/locales/comments.en.yml +23 -0
  107. data/config/locales/comments.ko.yml +23 -0
  108. data/config/locales/creatives.en.yml +2 -0
  109. data/config/locales/creatives.ko.yml +2 -0
  110. data/config/locales/drop_trigger.en.yml +34 -0
  111. data/config/locales/drop_trigger.ko.yml +34 -0
  112. data/config/locales/search_popup.en.yml +12 -0
  113. data/config/locales/search_popup.ko.yml +12 -0
  114. data/config/routes.rb +9 -4
  115. data/db/migrate/20260319132153_create_comment_snapshots.rb +18 -0
  116. data/db/migrate/20260331000000_remove_display_settings_from_users.rb +8 -0
  117. data/db/migrate/20260401120000_remove_emoji_prefix_from_inbox_creatives.rb +19 -0
  118. data/lib/collavre/engine.rb +15 -49
  119. data/lib/collavre/version.rb +1 -1
  120. data/lib/collavre/view_extensions.rb +75 -0
  121. data/lib/collavre.rb +1 -0
  122. data/lib/tasks/inbox_backfill.rake +36 -0
  123. metadata +40 -15
  124. data/app/components/collavre/plans_timeline_component.html.erb +0 -14
  125. data/app/components/collavre/plans_timeline_component.rb +0 -53
  126. data/app/controllers/collavre/creative_plans_controller.rb +0 -69
  127. data/app/controllers/collavre/plans_controller.rb +0 -166
  128. data/app/javascript/controllers/creatives/set_plan_modal_controller.js +0 -107
  129. data/app/javascript/modules/plans_menu.js +0 -49
  130. data/app/javascript/modules/plans_timeline.js +0 -408
  131. data/app/models/collavre/plan.rb +0 -43
  132. data/app/services/collavre/creatives/plan_tagger.rb +0 -64
  133. data/app/views/collavre/creatives/_set_plan_modal.html.erb +0 -25
  134. data/app/views/collavre/shared/navigation/_mobile_plans_button.html.erb +0 -1
  135. data/app/views/collavre/shared/navigation/_plans_button.html.erb +0 -3
  136. data/config/locales/plans.en.yml +0 -16
  137. data/config/locales/plans.ko.yml +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 827b436efe65b08a5c9e523f49835e24a2bf137af670dd00d0892627f46baace
4
- data.tar.gz: a29b7075c71eeee5da6a674ea9e7e8943cd013a060f278f875bcd61b169897da
3
+ metadata.gz: bfb336e9ba2c33ae2bebe02cb641ca55078e8a9e7b7534a2296fb9fe344e8ab8
4
+ data.tar.gz: 92446cc1f6e94e96c85bb3d623675671b3a1c918dbe18f365ea4cadcf9844a8f
5
5
  SHA512:
6
- metadata.gz: 5dfa7f4059f316c5e6193129ad37266f1bd17d0ad68a5d8558f695c5f313de043e7aec78a76343708500328ed055902051df8dd0feb670f29193ee5e9d4a566a
7
- data.tar.gz: 4bd468cdc42fa97398fca215d242b74138ebdf5afd1898361d30b691b789caa7f920da6c5942f22c4dd4935714b78cab4b2cfcb147a4b8c0424690d76fe6df87
6
+ metadata.gz: ef40b534cba46f348398f4097be26d8398dade4008cbef542fb8faaccebe5a7bc2647ba3666e5020cf1e32d29e8c9e4d37d877036c6b443c67247735221e68c0
7
+ data.tar.gz: 5dd19bdf5053beea83aeba18edc324df6fc86f429abf4f3e2a160d4728cc4c35a638adaace885d87855d0e5f71c8c578aa8280877126fada04b2e9ec29d0ca3b
@@ -39,6 +39,7 @@
39
39
  display: inline-flex;
40
40
  align-items: center;
41
41
  gap: var(--space-1);
42
+ height: 30px;
42
43
  }
43
44
 
44
45
  .lexical-toolbar-color__swatch {
@@ -77,29 +78,35 @@
77
78
 
78
79
  .lexical-toolbar-btn--small {
79
80
  min-width: auto;
80
- padding: 0.2rem 0.4rem;
81
- font-size: var(--text-0);
81
+ height: 24px;
82
+ padding: 0 var(--space-1);
83
+ font-size: var(--text-00);
82
84
  }
83
85
 
84
86
  .lexical-toolbar-btn {
85
87
  appearance: none;
86
- background: var(--surface-btn);
88
+ background: transparent;
87
89
  border: 1px solid var(--border-color);
88
- border-radius: var(--radius-1);
89
- color: var(--text-on-btn);
90
+ border-radius: var(--radius-2);
91
+ color: var(--text-secondary);
90
92
  cursor: pointer;
91
- font-size: 0.85rem;
93
+ font-size: var(--text-0);
92
94
  font-weight: var(--weight-6);
93
- line-height: 1.2;
94
- min-width: var(--space-7);
95
- padding: var(--space-1) 0.4rem;
96
- text-align: center;
97
- transition: background 0.15s ease, border-color 0.15s ease;
95
+ line-height: 1;
96
+ height: 30px;
97
+ min-width: 30px;
98
+ padding: 0 var(--space-2);
99
+ display: inline-flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ transition: background 0.15s var(--ease-out-2), color 0.15s var(--ease-out-2), border-color 0.15s var(--ease-out-2);
98
103
  }
99
104
 
100
105
  .lexical-toolbar-btn:hover,
101
106
  .lexical-toolbar-btn:focus-visible {
102
- filter: brightness(var(--hover-brightness, 0.95));
107
+ background: var(--surface-hover);
108
+ color: var(--text-primary);
109
+ border-color: var(--text-muted);
103
110
  outline: none;
104
111
  }
105
112
 
@@ -109,6 +116,13 @@
109
116
  color: var(--color-accent-text);
110
117
  }
111
118
 
119
+ .lexical-toolbar-btn:disabled {
120
+ opacity: 0.4;
121
+ color: var(--text-muted);
122
+ cursor: not-allowed;
123
+ pointer-events: none;
124
+ }
125
+
112
126
  .lexical-toolbar-separator {
113
127
  align-self: stretch;
114
128
  border-left: 1px solid var(--border-color);
@@ -0,0 +1,208 @@
1
+ /*
2
+ * Code Syntax Highlighting Theme
3
+ *
4
+ * Uses Collavre design tokens (--color-code-bg, --color-code-text, --font-mono).
5
+ * Syntax color tokens defined as CSS variables — overridden per theme context.
6
+ * Based on GitHub-style highlighting.
7
+ */
8
+
9
+ /* ============================================================================
10
+ * SYNTAX COLOR TOKENS (light mode defaults)
11
+ * ============================================================================ */
12
+ :root {
13
+ --syntax-comment: #6a737d;
14
+ --syntax-keyword: #d73a49;
15
+ --syntax-string: #032f62;
16
+ --syntax-number: #005cc5;
17
+ --syntax-builtin: #6f42c1;
18
+ --syntax-title: #6f42c1;
19
+ --syntax-attr: #005cc5;
20
+ --syntax-variable: #e36209;
21
+ --syntax-regexp: #032f62;
22
+ --syntax-tag: #22863a;
23
+ --syntax-name: #22863a;
24
+ --syntax-selector: #6f42c1;
25
+ --syntax-meta: #6a737d;
26
+ --syntax-deletion-text: #b31d28;
27
+ --syntax-deletion-bg: #ffeef0;
28
+ --syntax-addition-text: #22863a;
29
+ --syntax-addition-bg: #f0fff4;
30
+ }
31
+
32
+ /* ============================================================================
33
+ * DARK MODE SYNTAX TOKENS
34
+ * ============================================================================ */
35
+ body.dark-mode {
36
+ --syntax-comment: #8b949e;
37
+ --syntax-keyword: #ff7b72;
38
+ --syntax-string: #a5d6ff;
39
+ --syntax-number: #79c0ff;
40
+ --syntax-builtin: #d2a8ff;
41
+ --syntax-title: #d2a8ff;
42
+ --syntax-attr: #79c0ff;
43
+ --syntax-variable: #ffa657;
44
+ --syntax-regexp: #a5d6ff;
45
+ --syntax-tag: #7ee787;
46
+ --syntax-name: #7ee787;
47
+ --syntax-selector: #d2a8ff;
48
+ --syntax-meta: #8b949e;
49
+ --syntax-deletion-text: #ffa198;
50
+ --syntax-deletion-bg: rgba(248, 81, 73, 0.15);
51
+ --syntax-addition-text: #7ee787;
52
+ --syntax-addition-bg: rgba(63, 185, 80, 0.15);
53
+ }
54
+
55
+ @media (prefers-color-scheme: dark) {
56
+ body:not(.light-mode):not(.dark-mode) {
57
+ --syntax-comment: #8b949e;
58
+ --syntax-keyword: #ff7b72;
59
+ --syntax-string: #a5d6ff;
60
+ --syntax-number: #79c0ff;
61
+ --syntax-builtin: #d2a8ff;
62
+ --syntax-title: #d2a8ff;
63
+ --syntax-attr: #79c0ff;
64
+ --syntax-variable: #ffa657;
65
+ --syntax-regexp: #a5d6ff;
66
+ --syntax-tag: #7ee787;
67
+ --syntax-name: #7ee787;
68
+ --syntax-selector: #d2a8ff;
69
+ --syntax-meta: #8b949e;
70
+ --syntax-deletion-text: #ffa198;
71
+ --syntax-deletion-bg: rgba(248, 81, 73, 0.15);
72
+ --syntax-addition-text: #7ee787;
73
+ --syntax-addition-bg: rgba(63, 185, 80, 0.15);
74
+ }
75
+ }
76
+
77
+ /* ============================================================================
78
+ * CODE BLOCK CONTAINER
79
+ * ============================================================================ */
80
+ .comment-content pre {
81
+ background: var(--color-code-bg);
82
+ color: var(--color-code-text);
83
+ border: var(--border-1) solid var(--border-color);
84
+ border-radius: var(--radius-2);
85
+ padding: var(--space-2) var(--space-3);
86
+ margin: var(--space-2) 0;
87
+ overflow-x: auto;
88
+ font-family: var(--font-mono);
89
+ font-size: var(--text-0);
90
+ line-height: var(--leading-3);
91
+ }
92
+
93
+ .comment-content pre code {
94
+ background: none;
95
+ border: none;
96
+ padding: 0;
97
+ border-radius: 0;
98
+ font-family: inherit;
99
+ font-size: inherit;
100
+ color: inherit;
101
+ }
102
+
103
+ /* Inline code */
104
+ .comment-content code {
105
+ background: var(--color-code-bg);
106
+ color: var(--color-code-text);
107
+ border-radius: var(--radius-1);
108
+ padding: 0.15em 0.35em;
109
+ font-family: var(--font-mono);
110
+ font-size: 0.9em;
111
+ }
112
+
113
+ /* ============================================================================
114
+ * SYNTAX HIGHLIGHTING RULES (token-based, theme-agnostic)
115
+ * ============================================================================ */
116
+ .comment-content .hljs-comment,
117
+ .comment-content .hljs-quote {
118
+ color: var(--syntax-comment);
119
+ font-style: italic;
120
+ }
121
+
122
+ .comment-content .hljs-keyword,
123
+ .comment-content .hljs-selector-tag,
124
+ .comment-content .hljs-type {
125
+ color: var(--syntax-keyword);
126
+ }
127
+
128
+ .comment-content .hljs-string {
129
+ color: var(--syntax-string);
130
+ }
131
+
132
+ .comment-content .hljs-number,
133
+ .comment-content .hljs-literal {
134
+ color: var(--syntax-number);
135
+ }
136
+
137
+ .comment-content .hljs-built_in,
138
+ .comment-content .hljs-builtin-name {
139
+ color: var(--syntax-builtin);
140
+ }
141
+
142
+ .comment-content .hljs-title,
143
+ .comment-content .hljs-title.function_ {
144
+ color: var(--syntax-title);
145
+ }
146
+
147
+ .comment-content .hljs-attr,
148
+ .comment-content .hljs-attribute {
149
+ color: var(--syntax-attr);
150
+ }
151
+
152
+ .comment-content .hljs-variable,
153
+ .comment-content .hljs-template-variable {
154
+ color: var(--syntax-variable);
155
+ }
156
+
157
+ .comment-content .hljs-params {
158
+ color: var(--color-code-text);
159
+ }
160
+
161
+ .comment-content .hljs-regexp {
162
+ color: var(--syntax-regexp);
163
+ }
164
+
165
+ .comment-content .hljs-tag {
166
+ color: var(--syntax-tag);
167
+ }
168
+
169
+ .comment-content .hljs-name {
170
+ color: var(--syntax-name);
171
+ }
172
+
173
+ .comment-content .hljs-selector-class,
174
+ .comment-content .hljs-selector-id {
175
+ color: var(--syntax-selector);
176
+ }
177
+
178
+ .comment-content .hljs-selector-attr,
179
+ .comment-content .hljs-selector-pseudo {
180
+ color: var(--syntax-attr);
181
+ }
182
+
183
+ .comment-content .hljs-symbol,
184
+ .comment-content .hljs-bullet {
185
+ color: var(--syntax-number);
186
+ }
187
+
188
+ .comment-content .hljs-meta {
189
+ color: var(--syntax-meta);
190
+ }
191
+
192
+ .comment-content .hljs-deletion {
193
+ color: var(--syntax-deletion-text);
194
+ background: var(--syntax-deletion-bg);
195
+ }
196
+
197
+ .comment-content .hljs-addition {
198
+ color: var(--syntax-addition-text);
199
+ background: var(--syntax-addition-bg);
200
+ }
201
+
202
+ .comment-content .hljs-emphasis {
203
+ font-style: italic;
204
+ }
205
+
206
+ .comment-content .hljs-strong {
207
+ font-weight: var(--weight-7);
208
+ }
@@ -0,0 +1,26 @@
1
+ .comment-snapshot-restore {
2
+ margin-top: var(--space-2);
3
+ }
4
+
5
+ .restore-snapshot-btn {
6
+ background: none;
7
+ border: 1px solid var(--border-color);
8
+ border-radius: var(--radius-1);
9
+ cursor: pointer;
10
+ padding: var(--space-1) var(--space-3);
11
+ font-size: var(--text-xs);
12
+ line-height: 1.6;
13
+ color: var(--text-muted);
14
+ transition: background 0.15s, color 0.15s, border-color 0.15s;
15
+ }
16
+
17
+ .restore-snapshot-btn:hover:not(:disabled) {
18
+ background: var(--surface-hover);
19
+ color: var(--text-primary);
20
+ border-color: var(--color-accent-border);
21
+ }
22
+
23
+ .restore-snapshot-btn:disabled {
24
+ opacity: 0.4;
25
+ cursor: default;
26
+ }
@@ -52,13 +52,126 @@ body.chat-fullscreen {
52
52
  display: flex;
53
53
  align-items: center;
54
54
  justify-content: space-between;
55
- gap: 0.75em;
55
+ gap: var(--space-1);
56
56
  padding-bottom: var(--space-1);
57
57
  }
58
58
 
59
59
  .comments-popup-header h3 {
60
60
  margin: 0;
61
61
  line-height: 1.3;
62
+ min-width: 0;
63
+ flex: 1;
64
+ overflow: hidden;
65
+ text-overflow: ellipsis;
66
+ white-space: nowrap;
67
+ text-align: left;
68
+ }
69
+
70
+ /* Chat navigation back/forward buttons */
71
+ .chat-nav-buttons {
72
+ display: inline-flex;
73
+ align-items: center;
74
+ gap: var(--space-1);
75
+ flex-shrink: 0;
76
+ position: relative;
77
+ }
78
+
79
+ .chat-nav-btn {
80
+ background: none;
81
+ border: none;
82
+ color: var(--color-text);
83
+ cursor: pointer;
84
+ padding: var(--space-1);
85
+ display: inline-flex;
86
+ align-items: center;
87
+ justify-content: center;
88
+ border-radius: var(--radius-1);
89
+ transition: opacity 0.15s var(--ease-out-2), background-color 0.15s var(--ease-out-2);
90
+ }
91
+
92
+ .chat-nav-btn:hover:not(:disabled) {
93
+ background-color: var(--surface-hover);
94
+ }
95
+
96
+ .chat-nav-btn:disabled {
97
+ opacity: 0.25;
98
+ cursor: default;
99
+ pointer-events: none;
100
+ }
101
+
102
+ .chat-nav-icon {
103
+ width: var(--space-px-4);
104
+ height: var(--space-px-4);
105
+ stroke: currentColor;
106
+ fill: none;
107
+ }
108
+
109
+ /* Recent chats dropdown */
110
+ .chat-nav-dropdown {
111
+ position: absolute;
112
+ top: 100%;
113
+ left: 0;
114
+ min-width: 200px;
115
+ max-width: 300px;
116
+ max-height: 320px;
117
+ overflow-y: auto;
118
+ background: var(--surface-section);
119
+ border: 1px solid var(--border-color);
120
+ border-radius: var(--radius-2);
121
+ box-shadow: var(--shadow-3);
122
+ z-index: var(--layer-modal);
123
+ padding: var(--space-1) 0;
124
+ }
125
+
126
+ .chat-nav-dropdown-item {
127
+ display: flex;
128
+ align-items: center;
129
+ width: 100%;
130
+ padding: 0;
131
+ background: none;
132
+ border: none;
133
+ font-size: var(--text-1);
134
+ color: var(--color-text);
135
+ line-height: 1.4;
136
+ }
137
+
138
+ .chat-nav-dropdown-item:hover {
139
+ background-color: var(--surface-hover);
140
+ }
141
+
142
+ .chat-nav-dropdown-item.current {
143
+ font-weight: var(--weight-7);
144
+ }
145
+
146
+ .chat-nav-dropdown-label {
147
+ flex: 1;
148
+ min-width: 0;
149
+ padding: var(--space-1) var(--space-3);
150
+ background: none;
151
+ border: none;
152
+ text-align: left;
153
+ cursor: pointer;
154
+ font: inherit;
155
+ color: inherit;
156
+ white-space: nowrap;
157
+ overflow: hidden;
158
+ text-overflow: ellipsis;
159
+ }
160
+
161
+ .chat-nav-dropdown-remove {
162
+ flex-shrink: 0;
163
+ background: none;
164
+ border: none;
165
+ color: var(--color-muted);
166
+ cursor: pointer;
167
+ font-size: var(--text-2);
168
+ padding: var(--space-1) var(--space-2);
169
+ line-height: 1;
170
+ transition: color 0.15s var(--ease-out-2);
171
+ }
172
+
173
+ .chat-nav-dropdown-remove:hover {
174
+ color: var(--color-text);
62
175
  }
63
176
 
64
177
  .comments-popup-actions {
@@ -187,6 +300,8 @@ body.chat-fullscreen {
187
300
  .comment-item.selected-for-move {
188
301
  background-color: var(--color-section-bg);
189
302
  border-color: var(--color-border);
303
+ -webkit-user-select: none;
304
+ user-select: none;
190
305
  }
191
306
 
192
307
  .comment-select {
@@ -208,7 +323,6 @@ body.chat-fullscreen {
208
323
  .comment-content pre {
209
324
  white-space: pre-wrap;
210
325
  word-break: break-word;
211
- overflow-x: auto;
212
326
  }
213
327
 
214
328
  .comment-content pre code {
@@ -957,7 +1071,8 @@ body.chat-fullscreen {
957
1071
  }
958
1072
 
959
1073
  .context-chip svg,
960
- .context-toggle-btn svg {
1074
+ .context-toggle-btn svg,
1075
+ .drop-trigger-toggle-btn svg {
961
1076
  vertical-align: middle;
962
1077
  flex-shrink: 0;
963
1078
  }
@@ -1076,6 +1191,34 @@ body.chat-fullscreen {
1076
1191
  border-color: var(--color-secondary-active);
1077
1192
  }
1078
1193
 
1194
+ /* Drop trigger toggle button */
1195
+ .drop-trigger-toggle-btn {
1196
+ font-size: 0.75em;
1197
+ padding: 0.15em 0.4em;
1198
+ border-radius: 8px;
1199
+ background: none;
1200
+ border: 1px solid transparent;
1201
+ cursor: pointer;
1202
+ transition: all 0.2s;
1203
+ white-space: nowrap;
1204
+ }
1205
+
1206
+ .drop-trigger-toggle-btn:hover {
1207
+ background: var(--color-secondary-background);
1208
+ }
1209
+
1210
+ .drop-trigger-toggle-btn.drop-trigger-active {
1211
+ background: color-mix(in srgb, var(--color-warning) 20%, transparent);
1212
+ color: var(--color-warning);
1213
+ border-color: var(--color-warning);
1214
+ }
1215
+
1216
+ .drop-trigger-toggle-btn.drop-trigger-active svg {
1217
+ stroke: var(--color-warning);
1218
+ fill: var(--color-warning);
1219
+ fill-opacity: 0.2;
1220
+ }
1221
+
1079
1222
  .comment-topics-list {
1080
1223
  display: flex;
1081
1224
  flex-wrap: nowrap;
@@ -1111,6 +1254,13 @@ body.chat-fullscreen {
1111
1254
  box-sizing: border-box;
1112
1255
  }
1113
1256
 
1257
+ .topic-agent-avatar-wrapper {
1258
+ position: relative;
1259
+ display: inline-flex;
1260
+ flex-shrink: 0;
1261
+ vertical-align: middle;
1262
+ }
1263
+
1114
1264
  .topic-agent-avatar {
1115
1265
  width: 16px;
1116
1266
  height: 16px;
@@ -1119,6 +1269,10 @@ body.chat-fullscreen {
1119
1269
  flex-shrink: 0;
1120
1270
  }
1121
1271
 
1272
+ .topic-agent-avatar-wrapper .avatar-initial {
1273
+ font-size: var(--text-00);
1274
+ }
1275
+
1122
1276
  .ai-agent-draggable {
1123
1277
  cursor: grab;
1124
1278
  }
@@ -1452,6 +1606,7 @@ body.chat-fullscreen {
1452
1606
  margin-top: var(--space-1);
1453
1607
  }
1454
1608
 
1609
+ /* Hide drag hint on touch devices (no touch drag-and-drop) */
1455
1610
  @media (pointer: coarse) {
1456
1611
  .selection-action-bar-hint.no-touch {
1457
1612
  display: none;
@@ -142,35 +142,12 @@ html.creative-alignment-ready .page-title {
142
142
  }
143
143
 
144
144
  /* === Overflow popup menu — GNB style === */
145
+ /* #creative-overflow-menu inherits base styles from .popup-menu in popup.css */
145
146
  #creative-overflow-menu {
146
147
  min-width: 200px;
147
- border: 1px solid var(--border-color);
148
- border-radius: var(--radius-3);
149
- box-shadow: var(--shadow-2);
150
- padding: var(--space-1);
151
- background: var(--surface-section);
152
148
  }
153
149
 
154
- #creative-overflow-menu .popup-menu-item {
155
- display: flex;
156
- align-items: center;
157
- gap: var(--space-2);
158
- width: 100%;
159
- text-align: left;
160
- padding: var(--space-1) var(--space-2);
161
- border-radius: var(--radius-2);
162
- border: none;
163
- background: none;
164
- color: var(--text-primary);
165
- font-size: var(--text-1);
166
- cursor: pointer;
167
- transition: background 0.15s var(--ease-out-2);
168
- white-space: nowrap;
169
- }
170
-
171
- #creative-overflow-menu .popup-menu-item:hover {
172
- background: var(--surface-hover);
173
- }
150
+ /* popup-menu-item base styles are now in popup.css */
174
151
 
175
152
  #creative-overflow-menu .popup-menu-item.active {
176
153
  background: color-mix(in srgb, var(--color-active) 15%, transparent);
@@ -912,3 +889,85 @@ creative-tree-row[archived] .creative-row {
912
889
  border-color: var(--color-accent-border);
913
890
  background-color: var(--surface-input);
914
891
  }
892
+
893
+ /* --- Creative Presence Avatars --- */
894
+ .creative-presence-avatars {
895
+ display: inline-flex;
896
+ align-items: center;
897
+ gap: 2px;
898
+ margin-left: var(--space-2, 8px);
899
+ vertical-align: middle;
900
+ }
901
+
902
+ .creative-presence-user {
903
+ display: inline-flex;
904
+ align-items: center;
905
+ justify-content: center;
906
+ position: relative;
907
+ }
908
+
909
+ .creative-presence-user .avatar {
910
+ border: 2px solid var(--color-active, #4caf50);
911
+ width: 20px;
912
+ height: 20px;
913
+ }
914
+
915
+ /* --- Editing Conflict Indicator --- */
916
+ creative-tree-row.is-being-edited {
917
+ position: relative;
918
+ }
919
+
920
+ creative-tree-row.is-being-edited .creative-tree {
921
+ border-left: 3px solid var(--color-warning, #ff9800);
922
+ }
923
+
924
+ .creative-editing-indicator {
925
+ display: inline-flex;
926
+ align-items: center;
927
+ gap: var(--space-1, 4px);
928
+ font-size: var(--text-xs, 0.75rem);
929
+ color: var(--color-warning, #ff9800);
930
+ margin-left: var(--space-2, 8px);
931
+ white-space: nowrap;
932
+ animation: editing-pulse 1.5s ease-in-out infinite;
933
+ }
934
+
935
+ @keyframes editing-pulse {
936
+ 0%, 100% { opacity: 1; }
937
+ 50% { opacity: 0.5; }
938
+ }
939
+
940
+ /* Editing presence avatars */
941
+ .creative-editing-avatars {
942
+ display: inline-flex;
943
+ align-items: center;
944
+ gap: var(--space-1, 2px);
945
+ margin-left: var(--space-1, 4px);
946
+ }
947
+
948
+ .creative-editing-avatar-img {
949
+ border-radius: var(--radius-round, 50%);
950
+ border: 2px solid var(--color-accent, #4a9eff);
951
+ object-fit: cover;
952
+ }
953
+
954
+ .creative-editing-avatar-initials {
955
+ display: inline-flex;
956
+ align-items: center;
957
+ justify-content: center;
958
+ width: 24px;
959
+ height: 24px;
960
+ border-radius: var(--radius-round, 50%);
961
+ background: var(--color-accent, #4a9eff);
962
+ color: var(--color-on-accent, white);
963
+ font-size: var(--text-xs, 11px);
964
+ font-weight: var(--weight-semibold, 600);
965
+ border: 2px solid var(--color-accent, #4a9eff);
966
+ }
967
+
968
+ /* Wrapper for progressHtml so DOM can be synced back to Lit state
969
+ after Turbo Streams mutations (e.g. badge count updates).
970
+ display:contents ensures no layout impact. */
971
+ .creative-progress-area {
972
+ display: contents;
973
+ }