@tldraw/commenting 0.0.0-bootstrap → 5.3.0-internal.5f14a24c179e

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 (174) hide show
  1. package/commenting.css +280 -151
  2. package/dist-cjs/canvas/comment-body.js +1 -1
  3. package/dist-cjs/canvas/comment-body.js.map +2 -2
  4. package/dist-cjs/canvas/comment-drafts.js +54 -0
  5. package/dist-cjs/canvas/comment-drafts.js.map +7 -0
  6. package/dist-cjs/canvas/comment-render.js +2 -0
  7. package/dist-cjs/canvas/comment-render.js.map +2 -2
  8. package/dist-cjs/canvas/comment-tool.js +55 -11
  9. package/dist-cjs/canvas/comment-tool.js.map +2 -2
  10. package/dist-cjs/canvas/comments-filter-menu.js +55 -56
  11. package/dist-cjs/canvas/comments-filter-menu.js.map +2 -2
  12. package/dist-cjs/canvas/comments-overflow-menu.js +21 -19
  13. package/dist-cjs/canvas/comments-overflow-menu.js.map +2 -2
  14. package/dist-cjs/canvas/comments-overlay.js +271 -109
  15. package/dist-cjs/canvas/comments-overlay.js.map +2 -2
  16. package/dist-cjs/canvas/comments-sidebar.js +12 -18
  17. package/dist-cjs/canvas/comments-sidebar.js.map +2 -2
  18. package/dist-cjs/canvas/comments-visibility-toggle.js +67 -0
  19. package/dist-cjs/canvas/comments-visibility-toggle.js.map +7 -0
  20. package/dist-cjs/canvas/sidebar-filters.js +2 -2
  21. package/dist-cjs/canvas/sidebar-filters.js.map +2 -2
  22. package/dist-cjs/canvas/state.js +11 -0
  23. package/dist-cjs/canvas/state.js.map +2 -2
  24. package/dist-cjs/canvas/thread-state.js +8 -1
  25. package/dist-cjs/canvas/thread-state.js.map +2 -2
  26. package/dist-cjs/clustering/runtime.js +119 -7
  27. package/dist-cjs/clustering/runtime.js.map +2 -2
  28. package/dist-cjs/index.d.ts +100 -39
  29. package/dist-cjs/index.js +7 -1
  30. package/dist-cjs/index.js.map +2 -2
  31. package/dist-cjs/ui/avatar.js +14 -6
  32. package/dist-cjs/ui/avatar.js.map +2 -2
  33. package/dist-cjs/ui/byline.js +4 -4
  34. package/dist-cjs/ui/byline.js.map +2 -2
  35. package/dist-cjs/ui/comment-author.js +17 -0
  36. package/dist-cjs/ui/comment-author.js.map +7 -0
  37. package/dist-cjs/ui/comment-card.js +4 -4
  38. package/dist-cjs/ui/comment-card.js.map +2 -2
  39. package/dist-cjs/ui/comment-composer.js +92 -29
  40. package/dist-cjs/ui/comment-composer.js.map +2 -2
  41. package/dist-cjs/ui/comment-mention.js +1 -1
  42. package/dist-cjs/ui/comment-mention.js.map +2 -2
  43. package/dist-cjs/ui/comment-pin.js +23 -3
  44. package/dist-cjs/ui/comment-pin.js.map +2 -2
  45. package/dist-cjs/ui/comment-text.js +1 -1
  46. package/dist-cjs/ui/comment-text.js.map +2 -2
  47. package/dist-cjs/ui/comment-thread.js +6 -6
  48. package/dist-cjs/ui/comment-thread.js.map +2 -2
  49. package/dist-cjs/ui/comments-list.js +12 -12
  50. package/dist-cjs/ui/comments-list.js.map +2 -2
  51. package/dist-cjs/ui/count-badge.js +1 -1
  52. package/dist-cjs/ui/count-badge.js.map +2 -2
  53. package/dist-cjs/ui/empty-state.js +3 -3
  54. package/dist-cjs/ui/empty-state.js.map +2 -2
  55. package/dist-cjs/ui/format-time.js +3 -0
  56. package/dist-cjs/ui/format-time.js.map +2 -2
  57. package/dist-cjs/ui/mention-list.js +8 -8
  58. package/dist-cjs/ui/mention-list.js.map +2 -2
  59. package/dist-cjs/ui/mention-suggestion.js +3 -3
  60. package/dist-cjs/ui/mention-suggestion.js.map +2 -2
  61. package/dist-cjs/ui/mention.js +1 -1
  62. package/dist-cjs/ui/mention.js.map +2 -2
  63. package/dist-cjs/ui/reaction.js +11 -4
  64. package/dist-cjs/ui/reaction.js.map +2 -2
  65. package/dist-cjs/ui/reactions.js +10 -2
  66. package/dist-cjs/ui/reactions.js.map +2 -2
  67. package/dist-cjs/ui/send-button.js +1 -1
  68. package/dist-cjs/ui/send-button.js.map +2 -2
  69. package/dist-esm/canvas/comment-body.mjs +1 -1
  70. package/dist-esm/canvas/comment-body.mjs.map +2 -2
  71. package/dist-esm/canvas/comment-drafts.mjs +34 -0
  72. package/dist-esm/canvas/comment-drafts.mjs.map +7 -0
  73. package/dist-esm/canvas/comment-render.mjs +2 -0
  74. package/dist-esm/canvas/comment-render.mjs.map +2 -2
  75. package/dist-esm/canvas/comment-tool.mjs +56 -12
  76. package/dist-esm/canvas/comment-tool.mjs.map +2 -2
  77. package/dist-esm/canvas/comments-filter-menu.mjs +55 -56
  78. package/dist-esm/canvas/comments-filter-menu.mjs.map +2 -2
  79. package/dist-esm/canvas/comments-overflow-menu.mjs +22 -19
  80. package/dist-esm/canvas/comments-overflow-menu.mjs.map +2 -2
  81. package/dist-esm/canvas/comments-overlay.mjs +289 -111
  82. package/dist-esm/canvas/comments-overlay.mjs.map +2 -2
  83. package/dist-esm/canvas/comments-sidebar.mjs +15 -21
  84. package/dist-esm/canvas/comments-sidebar.mjs.map +2 -2
  85. package/dist-esm/canvas/comments-visibility-toggle.mjs +47 -0
  86. package/dist-esm/canvas/comments-visibility-toggle.mjs.map +7 -0
  87. package/dist-esm/canvas/sidebar-filters.mjs +2 -2
  88. package/dist-esm/canvas/sidebar-filters.mjs.map +2 -2
  89. package/dist-esm/canvas/state.mjs +11 -0
  90. package/dist-esm/canvas/state.mjs.map +2 -2
  91. package/dist-esm/canvas/thread-state.mjs +8 -1
  92. package/dist-esm/canvas/thread-state.mjs.map +2 -2
  93. package/dist-esm/clustering/runtime.mjs +119 -7
  94. package/dist-esm/clustering/runtime.mjs.map +2 -2
  95. package/dist-esm/index.d.mts +100 -39
  96. package/dist-esm/index.mjs +11 -1
  97. package/dist-esm/index.mjs.map +2 -2
  98. package/dist-esm/ui/avatar.mjs +14 -6
  99. package/dist-esm/ui/avatar.mjs.map +2 -2
  100. package/dist-esm/ui/byline.mjs +4 -4
  101. package/dist-esm/ui/byline.mjs.map +2 -2
  102. package/dist-esm/ui/comment-author.mjs +1 -0
  103. package/dist-esm/ui/comment-author.mjs.map +7 -0
  104. package/dist-esm/ui/comment-card.mjs +4 -4
  105. package/dist-esm/ui/comment-card.mjs.map +2 -2
  106. package/dist-esm/ui/comment-composer.mjs +93 -30
  107. package/dist-esm/ui/comment-composer.mjs.map +2 -2
  108. package/dist-esm/ui/comment-mention.mjs +1 -1
  109. package/dist-esm/ui/comment-mention.mjs.map +2 -2
  110. package/dist-esm/ui/comment-pin.mjs +23 -3
  111. package/dist-esm/ui/comment-pin.mjs.map +2 -2
  112. package/dist-esm/ui/comment-text.mjs +1 -1
  113. package/dist-esm/ui/comment-text.mjs.map +2 -2
  114. package/dist-esm/ui/comment-thread.mjs +6 -6
  115. package/dist-esm/ui/comment-thread.mjs.map +2 -2
  116. package/dist-esm/ui/comments-list.mjs +12 -12
  117. package/dist-esm/ui/comments-list.mjs.map +2 -2
  118. package/dist-esm/ui/count-badge.mjs +1 -1
  119. package/dist-esm/ui/count-badge.mjs.map +2 -2
  120. package/dist-esm/ui/empty-state.mjs +3 -3
  121. package/dist-esm/ui/empty-state.mjs.map +2 -2
  122. package/dist-esm/ui/format-time.mjs +3 -0
  123. package/dist-esm/ui/format-time.mjs.map +2 -2
  124. package/dist-esm/ui/mention-list.mjs +8 -8
  125. package/dist-esm/ui/mention-list.mjs.map +2 -2
  126. package/dist-esm/ui/mention-suggestion.mjs +3 -3
  127. package/dist-esm/ui/mention-suggestion.mjs.map +2 -2
  128. package/dist-esm/ui/mention.mjs +1 -1
  129. package/dist-esm/ui/mention.mjs.map +2 -2
  130. package/dist-esm/ui/reaction.mjs +11 -4
  131. package/dist-esm/ui/reaction.mjs.map +2 -2
  132. package/dist-esm/ui/reactions.mjs +10 -2
  133. package/dist-esm/ui/reactions.mjs.map +2 -2
  134. package/dist-esm/ui/send-button.mjs +1 -1
  135. package/dist-esm/ui/send-button.mjs.map +2 -2
  136. package/package.json +3 -3
  137. package/src/canvas/canvas.css +79 -36
  138. package/src/canvas/comment-body.tsx +1 -1
  139. package/src/canvas/comment-drafts.test.ts +55 -0
  140. package/src/canvas/comment-drafts.ts +46 -0
  141. package/src/canvas/comment-render.test.ts +1 -1
  142. package/src/canvas/comment-render.ts +7 -2
  143. package/src/canvas/comment-tool.tsx +87 -15
  144. package/src/canvas/comments-filter-menu.tsx +14 -16
  145. package/src/canvas/comments-overflow-menu.tsx +11 -15
  146. package/src/canvas/comments-overlay.tsx +399 -141
  147. package/src/canvas/comments-sidebar.tsx +27 -28
  148. package/src/canvas/comments-visibility-toggle.tsx +51 -0
  149. package/src/canvas/sidebar-filters.ts +4 -3
  150. package/src/canvas/state.ts +22 -0
  151. package/src/canvas/thread-state.ts +13 -1
  152. package/src/clustering/runtime.test.ts +183 -7
  153. package/src/clustering/runtime.ts +164 -15
  154. package/src/index.ts +6 -0
  155. package/src/ui/avatar.tsx +15 -11
  156. package/src/ui/byline.tsx +6 -5
  157. package/src/ui/comment-author.ts +15 -0
  158. package/src/ui/comment-card.tsx +6 -5
  159. package/src/ui/comment-composer.tsx +122 -33
  160. package/src/ui/comment-mention.ts +2 -2
  161. package/src/ui/comment-pin.tsx +35 -4
  162. package/src/ui/comment-text.tsx +1 -1
  163. package/src/ui/comment-thread.tsx +8 -6
  164. package/src/ui/comments-list.tsx +19 -14
  165. package/src/ui/comments.css +201 -115
  166. package/src/ui/count-badge.tsx +1 -1
  167. package/src/ui/empty-state.tsx +3 -3
  168. package/src/ui/format-time.ts +5 -0
  169. package/src/ui/mention-list.tsx +13 -16
  170. package/src/ui/mention-suggestion.tsx +3 -3
  171. package/src/ui/mention.tsx +1 -1
  172. package/src/ui/reaction.tsx +6 -3
  173. package/src/ui/reactions.tsx +6 -2
  174. package/src/ui/send-button.tsx +1 -1
package/commenting.css CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  /* Real comment UI components. Co-located so styles travel to any view (studio,
6
6
  canvas), and themed via tldraw's --tl-color tokens so they follow light/dark. */
7
- .cmt-card {
7
+ .tlui-cmt-card {
8
8
  position: relative;
9
9
  display: flex;
10
10
  gap: 10px;
@@ -16,7 +16,7 @@
16
16
  }
17
17
 
18
18
  /* hover-revealed controls (edit…) at the card's top-right */
19
- .cmt-card__actions {
19
+ .tlui-cmt-card__actions {
20
20
  position: absolute;
21
21
  top: 6px;
22
22
  right: 6px;
@@ -24,65 +24,68 @@
24
24
  gap: 2px;
25
25
  opacity: 0;
26
26
  }
27
- .cmt-card:hover .cmt-card__actions,
28
- .cmt-card:focus-within .cmt-card__actions {
27
+ .tlui-cmt-card:hover .tlui-cmt-card__actions,
28
+ .tlui-cmt-card:focus-within .tlui-cmt-card__actions {
29
29
  opacity: 1;
30
30
  }
31
31
 
32
- .cmt-body {
32
+ .tlui-cmt-body {
33
33
  flex: 1;
34
34
  min-width: 0;
35
35
  }
36
36
 
37
- .cmt-head {
37
+ .tlui-cmt-head {
38
38
  display: flex;
39
39
  align-items: baseline;
40
40
  gap: 6px;
41
41
  }
42
42
 
43
- .cmt-author {
43
+ .tlui-cmt-author {
44
44
  font-weight: 600;
45
45
  font-size: 13px;
46
46
  color: var(--tl-color-text-1);
47
47
  }
48
48
 
49
- .cmt-time {
49
+ .tlui-cmt-time {
50
50
  font-size: 11px;
51
51
  color: var(--tl-color-text-3);
52
52
  }
53
53
 
54
- .cmt-text {
54
+ .tlui-cmt-text {
55
55
  margin: 3px 0 0;
56
56
  font-size: 13px;
57
57
  line-height: 1.4;
58
58
  color: var(--tl-color-text-1);
59
+ /* Break long unbroken strings (URLs, keyboard-mashing) so they wrap inside the card instead of
60
+ overflowing it. `anywhere` also lets the flex body shrink to the card width. */
61
+ overflow-wrap: anywhere;
59
62
  }
60
63
 
61
- .cmt-edited {
64
+ .tlui-cmt-edited {
62
65
  font-style: italic;
63
66
  }
64
67
 
65
68
  /* rendered rich text inside a comment body — bare tags emitted by the comment renderer
66
69
  (paragraphs, lists, code, highlight, links), matching the limited comment extension set. */
67
- .cmt-text p {
70
+ .tlui-cmt-text p {
68
71
  margin: 0;
69
72
  }
70
73
 
71
- .cmt-text p + p,
72
- .cmt-text p + ul,
73
- .cmt-text p + ol,
74
- .cmt-text ul + p,
75
- .cmt-text ol + p {
74
+ .tlui-cmt-text p + p,
75
+ .tlui-cmt-text p + ul,
76
+ .tlui-cmt-text p + ol,
77
+ .tlui-cmt-text ul + p,
78
+ .tlui-cmt-text ol + p {
76
79
  margin-top: 6px;
77
80
  }
78
81
 
79
- .cmt-text ul,
80
- .cmt-text ol {
82
+ .tlui-cmt-text ul,
83
+ .tlui-cmt-text ol {
81
84
  margin: 0;
82
85
  padding-left: 18px;
83
86
  }
84
87
 
85
- .cmt-text code {
88
+ .tlui-cmt-text code {
86
89
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
87
90
  font-size: 0.92em;
88
91
  background: var(--tl-color-muted-2);
@@ -90,18 +93,18 @@
90
93
  padding: 0 3px;
91
94
  }
92
95
 
93
- .cmt-text mark {
96
+ .tlui-cmt-text mark {
94
97
  background: color-mix(in srgb, #ffeb3b 60%, transparent);
95
98
  color: inherit;
96
99
  border-radius: 2px;
97
100
  }
98
101
 
99
- .cmt-text a {
102
+ .tlui-cmt-text a {
100
103
  color: var(--tl-color-selected);
101
104
  text-decoration: underline;
102
105
  }
103
106
 
104
- .cmt-avatar {
107
+ .tlui-cmt-avatar {
105
108
  width: 28px;
106
109
  height: 28px;
107
110
  border-radius: 50%;
@@ -115,7 +118,7 @@
115
118
  flex-shrink: 0;
116
119
  }
117
120
 
118
- .cmt-avatar--image {
121
+ .tlui-cmt-avatar--image {
119
122
  object-fit: cover;
120
123
  background: none;
121
124
  }
@@ -123,14 +126,14 @@
123
126
  /* composer — an avatar beside a rounded-rect field holding the rich-text input and the send button.
124
127
  Formatting is applied via markdown and keyboard shortcuts (no toolbar). The avatar aligns to the
125
128
  top so it stays put as the field grows to multiple lines. */
126
- .cmt-composer {
129
+ .tlui-cmt-composer {
127
130
  display: flex;
128
131
  align-items: flex-start;
129
132
  gap: 10px;
130
133
  padding: 4px 0 8px 4px;
131
134
  }
132
135
 
133
- .cmt-composer__field {
136
+ .tlui-cmt-composer__field {
134
137
  flex: 1;
135
138
  min-width: 0;
136
139
  display: flex;
@@ -142,19 +145,47 @@
142
145
  border-radius: var(--tl-radius-3);
143
146
  }
144
147
 
145
- .cmt-composer__field:focus-within {
148
+ .tlui-cmt-composer__field:focus-within {
146
149
  border-color: var(--tl-color-selected);
147
150
  }
148
151
 
152
+ /* Expanded: the content no longer fits on one line beside the send button, so the input takes
153
+ the full width and the send button drops to its own row, right-aligned. */
154
+ .tlui-cmt-composer__field--expanded {
155
+ flex-wrap: wrap;
156
+ }
157
+ .tlui-cmt-composer__field--expanded .tlui-cmt-composer__input-wrap {
158
+ flex-basis: 100%;
159
+ /* The field pads 12px left but only 3px right (the send button's inset). With the input
160
+ spanning the full width, give the text the same 12px on the right. */
161
+ padding-right: 9px;
162
+ }
163
+ .tlui-cmt-composer__field--expanded .tlui-cmt-send {
164
+ margin-left: auto;
165
+ }
166
+
149
167
  /* the editable area, with the placeholder overlaid while it's empty */
150
- .cmt-composer__input-wrap {
168
+ .tlui-cmt-composer__input-wrap {
151
169
  position: relative;
152
170
  flex: 1;
153
171
  min-width: 0;
154
172
  padding: 3px 0;
155
173
  }
156
174
 
157
- .cmt-input {
175
+ /* The hidden single-line measuring clone of the editor's content (see CommentComposer). */
176
+ .tlui-cmt-composer__mirror {
177
+ position: absolute;
178
+ top: 0;
179
+ left: 0;
180
+ visibility: hidden;
181
+ pointer-events: none;
182
+ white-space: nowrap;
183
+ width: max-content;
184
+ max-height: none;
185
+ overflow: visible;
186
+ }
187
+
188
+ .tlui-cmt-input {
158
189
  font: inherit;
159
190
  font-size: 13px;
160
191
  line-height: 1.4;
@@ -167,23 +198,23 @@
167
198
  word-break: break-word;
168
199
  }
169
200
 
170
- .cmt-input p {
201
+ .tlui-cmt-input p {
171
202
  margin: 0;
172
203
  }
173
204
 
174
- .cmt-input p + p,
175
- .cmt-input p + ul,
176
- .cmt-input p + ol {
205
+ .tlui-cmt-input p + p,
206
+ .tlui-cmt-input p + ul,
207
+ .tlui-cmt-input p + ol {
177
208
  margin-top: 4px;
178
209
  }
179
210
 
180
- .cmt-input ul,
181
- .cmt-input ol {
211
+ .tlui-cmt-input ul,
212
+ .tlui-cmt-input ol {
182
213
  margin: 0;
183
214
  padding-left: 18px;
184
215
  }
185
216
 
186
- .cmt-input__placeholder {
217
+ .tlui-cmt-input__placeholder {
187
218
  position: absolute;
188
219
  top: 3px;
189
220
  left: 0;
@@ -193,7 +224,7 @@
193
224
  pointer-events: none;
194
225
  }
195
226
 
196
- .cmt-send {
227
+ .tlui-cmt-send {
197
228
  border: 0;
198
229
  border-radius: var(--tl-radius-2);
199
230
  background: var(--tl-color-selected);
@@ -206,33 +237,33 @@
206
237
  align-self: flex-end;
207
238
  }
208
239
 
209
- .cmt-send:hover,
210
- .pseudo-hover .cmt-send {
240
+ .tlui-cmt-send:hover,
241
+ .pseudo-hover .tlui-cmt-send {
211
242
  background: color-mix(in srgb, var(--tl-color-selected) 88%, black);
212
243
  }
213
244
 
214
- .cmt-send:active,
215
- .pseudo-active .cmt-send {
245
+ .tlui-cmt-send:active,
246
+ .pseudo-active .tlui-cmt-send {
216
247
  background: color-mix(in srgb, var(--tl-color-selected) 78%, black);
217
248
  }
218
249
 
219
- .cmt-send:focus-visible,
220
- .pseudo-focus-visible .cmt-send {
250
+ .tlui-cmt-send:focus-visible,
251
+ .pseudo-focus-visible .tlui-cmt-send {
221
252
  outline: 2px solid var(--tl-color-selected);
222
253
  outline-offset: 2px;
223
254
  }
224
255
 
225
- .cmt-send:disabled {
256
+ .tlui-cmt-send:disabled {
226
257
  opacity: 0.45;
227
258
  cursor: not-allowed;
228
259
  }
229
260
 
230
261
  /* pin */
231
- .cmt-pin {
262
+ .tlui-cmt-pin {
232
263
  width: 34px;
233
264
  height: 34px;
234
265
  border-radius: 50% 50% 50% 3px;
235
- background: var(--tl-color-selected);
266
+ background: var(--tlui-cmt-pin-color, var(--tl-color-selected));
236
267
  color: #fff;
237
268
  display: flex;
238
269
  align-items: center;
@@ -246,33 +277,39 @@
246
277
  box-shadow 0.08s ease;
247
278
  }
248
279
 
249
- .cmt-pin:hover,
250
- .pseudo-hover .cmt-pin {
280
+ .tlui-cmt-pin:hover,
281
+ .pseudo-hover .tlui-cmt-pin {
251
282
  transform: scale(1.08);
283
+ }
284
+
285
+ /* The hover shadow is for closed pins only — an open pin keeps its selection ring, which this
286
+ box-shadow would otherwise override (the hover selector outranks the --open rule). */
287
+ .tlui-cmt-pin:not(.tlui-cmt-pin--open):hover,
288
+ .pseudo-hover .tlui-cmt-pin:not(.tlui-cmt-pin--open) {
252
289
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.32);
253
290
  }
254
291
 
255
- /* open: the thread is showing — a selection ring marks the active pin */
256
- .cmt-pin--open {
292
+ /* open: the thread is showing — a selection ring marks the active pin (in the pin's own tint) */
293
+ .tlui-cmt-pin--open {
257
294
  box-shadow:
258
295
  0 0 0 3px var(--tl-color-panel),
259
- 0 0 0 5px var(--tl-color-selected),
296
+ 0 0 0 5px var(--tlui-cmt-pin-color, var(--tl-color-selected)),
260
297
  0 2px 6px rgba(0, 0, 0, 0.25);
261
298
  }
262
299
 
263
300
  /* resolved: a solid, muted grey (the default --tl-color-muted-1 is 10% black, so it goes
264
301
  translucent over the canvas). Dark mode gets its own grey — the token's dark value is near-black. */
265
- .cmt-pin--resolved {
302
+ .tlui-cmt-pin--resolved {
266
303
  background: #dfe0e1;
267
304
  color: hsl(214, 8%, 42%);
268
305
  }
269
- .tl-theme__dark .cmt-pin--resolved {
306
+ .tl-theme__dark .tlui-cmt-pin--resolved {
270
307
  background: hsl(240, 5%, 30%);
271
308
  color: hsl(0, 0%, 72%);
272
309
  }
273
310
 
274
311
  /* count badge */
275
- .cmt-count-badge {
312
+ .tlui-cmt-count-badge {
276
313
  width: 34px;
277
314
  height: 34px;
278
315
  border-radius: 50%;
@@ -288,14 +325,14 @@
288
325
  }
289
326
 
290
327
  /* thread */
291
- .cmt-thread {
328
+ .tlui-cmt-thread {
292
329
  display: flex;
293
330
  flex-direction: column;
294
331
  gap: 8px;
295
332
  width: 300px;
296
333
  }
297
334
 
298
- .cmt-thread__head {
335
+ .tlui-cmt-thread__head {
299
336
  display: flex;
300
337
  align-items: center;
301
338
  gap: 8px;
@@ -306,7 +343,7 @@
306
343
  letter-spacing: 0.04em;
307
344
  }
308
345
 
309
- .cmt-badge {
346
+ .tlui-cmt-badge {
310
347
  font-size: 10px;
311
348
  font-weight: 600;
312
349
  text-transform: none;
@@ -318,12 +355,12 @@
318
355
  }
319
356
 
320
357
  /* reactions */
321
- .cmt-reactions {
358
+ .tlui-cmt-reactions {
322
359
  display: flex;
323
360
  gap: 6px;
324
361
  }
325
362
 
326
- .cmt-reaction {
363
+ .tlui-cmt-reaction {
327
364
  display: inline-flex;
328
365
  align-items: center;
329
366
  gap: 5px;
@@ -337,27 +374,27 @@
337
374
  cursor: pointer;
338
375
  }
339
376
 
340
- .cmt-reaction:hover,
341
- .pseudo-hover .cmt-reaction {
377
+ .tlui-cmt-reaction:hover,
378
+ .pseudo-hover .tlui-cmt-reaction {
342
379
  border-color: var(--tl-color-selected);
343
380
  }
344
381
 
345
- .cmt-reaction--active {
382
+ .tlui-cmt-reaction--active {
346
383
  border-color: var(--tl-color-selected);
347
384
  background: color-mix(in srgb, var(--tl-color-selected) 12%, var(--tl-color-panel));
348
385
  }
349
386
 
350
- .cmt-reaction__count {
387
+ .tlui-cmt-reaction__count {
351
388
  color: var(--tl-color-text-3);
352
389
  }
353
390
 
354
- .cmt-reaction--add {
391
+ .tlui-cmt-reaction--add {
355
392
  color: var(--tl-color-text-3);
356
393
  font-weight: 600;
357
394
  }
358
395
 
359
396
  /* mention */
360
- .cmt-mention {
397
+ .tlui-cmt-mention {
361
398
  color: var(--tl-color-selected);
362
399
  font-weight: 600;
363
400
  background: color-mix(in srgb, var(--tl-color-selected) 12%, transparent);
@@ -366,7 +403,7 @@
366
403
  }
367
404
 
368
405
  /* mention picker */
369
- .cmt-mention-list {
406
+ .tlui-cmt-mention-list {
370
407
  display: flex;
371
408
  flex-direction: column;
372
409
  gap: 1px;
@@ -382,7 +419,7 @@
382
419
  box-shadow: var(--tl-shadow-2, 0 2px 12px rgba(0, 0, 0, 0.14));
383
420
  }
384
421
 
385
- .cmt-mention-list__item {
422
+ .tlui-cmt-mention-list__item {
386
423
  display: flex;
387
424
  align-items: center;
388
425
  gap: 8px;
@@ -396,19 +433,19 @@
396
433
  font: inherit;
397
434
  }
398
435
 
399
- .cmt-mention-list__item--active,
400
- .cmt-mention-list__item:hover {
436
+ .tlui-cmt-mention-list__item--active,
437
+ .tlui-cmt-mention-list__item:hover {
401
438
  background: var(--tl-color-muted-2, rgba(0, 0, 0, 0.06));
402
439
  }
403
440
 
404
- .cmt-mention-list__text {
441
+ .tlui-cmt-mention-list__text {
405
442
  display: flex;
406
443
  flex-direction: column;
407
444
  min-width: 0;
408
445
  line-height: 1.3;
409
446
  }
410
447
 
411
- .cmt-mention-list__name {
448
+ .tlui-cmt-mention-list__name {
412
449
  font-size: 13px;
413
450
  font-weight: 500;
414
451
  white-space: nowrap;
@@ -416,13 +453,13 @@
416
453
  text-overflow: ellipsis;
417
454
  }
418
455
 
419
- .cmt-mention-list__you {
456
+ .tlui-cmt-mention-list__you {
420
457
  margin-left: 4px;
421
458
  font-weight: 400;
422
459
  color: var(--tl-color-text-3);
423
460
  }
424
461
 
425
- .cmt-mention-list__secondary {
462
+ .tlui-cmt-mention-list__secondary {
426
463
  font-size: 12px;
427
464
  color: var(--tl-color-text-3);
428
465
  white-space: nowrap;
@@ -430,7 +467,7 @@
430
467
  text-overflow: ellipsis;
431
468
  }
432
469
 
433
- .cmt-mention-list--empty {
470
+ .tlui-cmt-mention-list--empty {
434
471
  padding: 8px 10px;
435
472
  width: 100%;
436
473
  box-sizing: border-box;
@@ -439,13 +476,13 @@
439
476
  }
440
477
 
441
478
  /* the @-picker popup — caret-anchored above the page, positioned by the suggestion plugin */
442
- .cmt-mention-popup {
479
+ .tlui-cmt-mention-popup {
443
480
  position: fixed;
444
481
  z-index: var(--tl-layer-menus);
445
482
  }
446
483
 
447
484
  /* empty state */
448
- .cmt-empty {
485
+ .tlui-cmt-empty {
449
486
  display: flex;
450
487
  flex-direction: column;
451
488
  align-items: center;
@@ -455,11 +492,11 @@
455
492
  width: 240px;
456
493
  }
457
494
 
458
- .cmt-empty__icon {
495
+ .tlui-cmt-empty__icon {
459
496
  font-size: 28px;
460
497
  }
461
498
 
462
- .cmt-empty__message {
499
+ .tlui-cmt-empty__message {
463
500
  margin: 0;
464
501
  color: var(--tl-color-text-3);
465
502
  font-size: 13px;
@@ -468,7 +505,7 @@
468
505
 
469
506
  /* a comment thread: an elevated panel — the same surface treatment as the toolbar — holding a
470
507
  header, an optional resolved banner, the comments, and a reply composer */
471
- .cmt-thread {
508
+ .tlui-cmt-thread {
472
509
  display: flex;
473
510
  flex-direction: column;
474
511
  gap: 6px;
@@ -478,22 +515,22 @@
478
515
  border-radius: var(--tl-radius-4);
479
516
  box-shadow: var(--tl-shadow-2);
480
517
  }
481
- .cmt-thread__header {
518
+ .tlui-cmt-thread__header {
482
519
  display: flex;
483
520
  align-items: center;
484
521
  justify-content: space-between;
485
522
  padding: 2px 2px 2px 4px;
486
523
  }
487
- .cmt-thread__title {
524
+ .tlui-cmt-thread__title {
488
525
  font-size: 12px;
489
526
  font-weight: 600;
490
527
  color: var(--tl-color-text-1);
491
528
  }
492
- .cmt-thread__actions {
529
+ .tlui-cmt-thread__actions {
493
530
  display: flex;
494
531
  gap: 2px;
495
532
  }
496
- .cmt-thread__action {
533
+ .tlui-cmt-thread__action {
497
534
  display: flex;
498
535
  align-items: center;
499
536
  justify-content: center;
@@ -508,25 +545,55 @@
508
545
  line-height: 1;
509
546
  cursor: pointer;
510
547
  }
511
- .cmt-thread__action:hover {
548
+ .tlui-cmt-thread__action:hover {
512
549
  background: var(--tl-color-muted-2);
513
550
  color: var(--tl-color-text-1);
514
551
  }
515
- .cmt-thread__resolved {
552
+ .tlui-cmt-thread__resolved {
516
553
  padding: 6px 10px;
517
554
  border-radius: 8px;
518
555
  background: var(--tl-color-muted-2);
519
556
  font-size: 12px;
520
557
  color: var(--tl-color-text-3);
521
558
  }
522
- .cmt-thread__list {
559
+ .tlui-cmt-thread__list {
523
560
  display: flex;
524
561
  flex-direction: column;
525
562
  gap: 6px;
526
563
  }
564
+ /* Inside a thread, author identity is a small colour dot, no initial — the letter doesn't fit
565
+ at this size. */
566
+ .tlui-cmt-thread .tlui-cmt-avatar {
567
+ width: 14px;
568
+ height: 14px;
569
+ font-size: 0;
570
+ margin-top: 2px;
571
+ }
572
+
573
+ /* The reply composer carries no avatar at all — the field spans the thread's full width. */
574
+ .tlui-cmt-thread .tlui-cmt-composer .tlui-cmt-avatar {
575
+ display: none;
576
+ }
577
+
578
+ /* The sidebar's rows use the same small colour dot as the thread view. */
579
+ .tlui-cmt-list .tlui-cmt-avatar {
580
+ width: 14px;
581
+ height: 14px;
582
+ font-size: 0;
583
+ margin-top: 2px;
584
+ }
585
+
586
+ /* The dot treatment is for colour-only identity — an image avatar stays full size. */
587
+ .tlui-cmt-thread .tlui-cmt-avatar--image,
588
+ .tlui-cmt-list .tlui-cmt-avatar--image {
589
+ width: 24px;
590
+ height: 24px;
591
+ margin-top: 0;
592
+ }
593
+
527
594
  /* inside the panel, comments are plain content — no surrounding box; the composer's field carries
528
595
  its own surface. */
529
- .cmt-thread .cmt-card {
596
+ .tlui-cmt-thread .tlui-cmt-card {
530
597
  width: 100%;
531
598
  padding: 6px 0 6px 4px;
532
599
  background: transparent;
@@ -534,13 +601,13 @@
534
601
  }
535
602
 
536
603
  /* comments list — thread summaries, one per row (used by the canvas sidebar) */
537
- .cmt-list {
604
+ .tlui-cmt-list {
538
605
  display: flex;
539
606
  flex-direction: column;
540
607
  width: 100%;
541
608
  min-height: 0;
542
609
  }
543
- .cmt-list__header {
610
+ .tlui-cmt-list__header {
544
611
  flex-shrink: 0;
545
612
  display: flex;
546
613
  align-items: center;
@@ -549,16 +616,14 @@
549
616
  padding: 6px 6px 6px 14px;
550
617
  border-bottom: 1px solid var(--tl-color-divider);
551
618
  }
552
- .cmt-list__header-title {
553
- font-size: 11px;
619
+ .tlui-cmt-list__header-title {
620
+ font-size: 13px;
554
621
  font-weight: 600;
555
- letter-spacing: 0.06em;
556
- text-transform: uppercase;
557
- color: var(--tl-color-text-3);
622
+ color: var(--tl-color-text-1);
558
623
  }
559
624
 
560
625
  /* a small square icon button in the sidebar header (filter funnel, overflow …) */
561
- .cmt-header-btn {
626
+ .tlui-cmt-header-btn {
562
627
  display: flex;
563
628
  align-items: center;
564
629
  justify-content: center;
@@ -571,19 +636,24 @@
571
636
  color: var(--tl-color-text-2);
572
637
  cursor: pointer;
573
638
  }
574
- .cmt-header-btn:hover,
575
- .cmt-header-btn[data-state='open'] {
639
+ .tlui-cmt-header-btn:hover,
640
+ .tlui-cmt-header-btn[data-state='open'] {
576
641
  background: var(--tl-color-muted-2);
577
642
  color: var(--tl-color-text-1);
578
643
  }
579
- .cmt-list__header-actions {
644
+ .tlui-cmt-list__header-actions {
580
645
  display: flex;
581
646
  align-items: center;
582
647
  gap: 2px;
583
648
  }
584
649
 
650
+ /* The commenting dropdowns' surface — a little air between the items and the menu edge. */
651
+ .tlui-cmt-menu {
652
+ padding: 4px;
653
+ }
654
+
585
655
  /* a menu row with a label and a right-aligned shortcut hint (overflow menu) */
586
- .cmt-menu-item {
656
+ .tlui-cmt-menu-item {
587
657
  display: flex;
588
658
  align-items: center;
589
659
  justify-content: space-between;
@@ -594,28 +664,33 @@
594
664
  border-radius: 6px;
595
665
  background: transparent;
596
666
  font: inherit;
597
- font-size: 13px;
667
+ font-size: 12px;
598
668
  color: var(--tl-color-text-1);
599
669
  cursor: pointer;
600
670
  }
601
- .cmt-menu-item:hover {
671
+ .tlui-cmt-menu-item:hover {
602
672
  background: var(--tl-color-muted-2);
603
673
  }
604
- .cmt-menu-item__shortcut {
674
+ /* Destructive menu entries (delete) — the same danger colour as tldraw's danger buttons. */
675
+ .tlui-cmt-menu-item--danger {
676
+ color: var(--tl-color-danger);
677
+ }
678
+
679
+ .tlui-cmt-menu-item__shortcut {
605
680
  color: var(--tl-color-text-3);
606
681
  font-size: 12px;
607
682
  }
608
- .cmt-list__items {
683
+ .tlui-cmt-list__items {
609
684
  flex: 1;
610
685
  min-height: 0;
611
686
  overflow-y: auto;
612
687
  }
613
- .cmt-list__empty {
688
+ .tlui-cmt-list__empty {
614
689
  padding: 20px 14px;
615
690
  color: var(--tl-color-text-3);
616
691
  font-size: 13px;
617
692
  }
618
- .cmt-list__item {
693
+ .tlui-cmt-list__item {
619
694
  display: flex;
620
695
  gap: 10px;
621
696
  width: 100%;
@@ -627,22 +702,30 @@
627
702
  text-align: left;
628
703
  cursor: pointer;
629
704
  }
630
- .cmt-list__item:hover {
705
+ .tlui-cmt-list__item:hover {
631
706
  background: var(--tl-color-muted-2);
632
707
  }
633
- .cmt-list__item--selected {
634
- background: var(--tl-color-muted-1);
708
+ /* Selected sits a step above hover so the open thread's row stays distinguishable while
709
+ pointing at other rows — but only a step: the muted-1 token (10%) reads too heavy here.
710
+ These rows sit on the opaque sidebar panel, so a translucent tint composes safely. */
711
+ .tlui-cmt-list__item--selected,
712
+ .tlui-cmt-list__item--selected:hover {
713
+ background: hsl(0, 0%, 0%, 5%);
714
+ }
715
+ .tl-theme__dark .tlui-cmt-list__item--selected,
716
+ .tl-theme__dark .tlui-cmt-list__item--selected:hover {
717
+ background: hsl(0, 0%, 100%, 5%);
635
718
  }
636
719
  /* resolved rows mute their content but keep the "Resolved" marker legible */
637
- .cmt-list__item[data-resolved] .cmt-head,
638
- .cmt-list__item[data-resolved] .cmt-list__item-preview {
720
+ .tlui-cmt-list__item[data-resolved] .tlui-cmt-head,
721
+ .tlui-cmt-list__item[data-resolved] .tlui-cmt-list__item-preview {
639
722
  opacity: 0.55;
640
723
  }
641
- .cmt-list__item-body {
724
+ .tlui-cmt-list__item-body {
642
725
  flex: 1;
643
726
  min-width: 0;
644
727
  }
645
- .cmt-list__item-preview {
728
+ .tlui-cmt-list__item-preview {
646
729
  margin-top: 2px;
647
730
  font-size: 13px;
648
731
  color: var(--tl-color-text-1);
@@ -651,9 +734,12 @@
651
734
  display: -webkit-box;
652
735
  -webkit-line-clamp: 2;
653
736
  -webkit-box-orient: vertical;
737
+ /* Long unbroken strings (URLs, mashed keys) wrap onto the clamped lines instead of clipping
738
+ mid-string — same treatment as the card body. */
739
+ overflow-wrap: anywhere;
654
740
  }
655
741
  /* meta line under the preview: page label and/or a resolved marker */
656
- .cmt-list__item-meta {
742
+ .tlui-cmt-list__item-meta {
657
743
  display: flex;
658
744
  align-items: center;
659
745
  gap: 8px;
@@ -661,20 +747,20 @@
661
747
  font-size: 11px;
662
748
  color: var(--tl-color-text-3);
663
749
  }
664
- .cmt-list__item-resolved {
750
+ .tlui-cmt-list__item-resolved {
665
751
  display: inline-flex;
666
752
  align-items: center;
667
753
  gap: 3px;
668
754
  font-weight: 600;
669
755
  }
670
- .cmt-list__item-page {
756
+ .tlui-cmt-list__item-page {
671
757
  display: inline-flex;
672
758
  align-items: center;
673
759
  padding: 1px 6px;
674
760
  border-radius: 4px;
675
761
  background: var(--tl-color-muted-2);
676
762
  }
677
- .cmt-list__item-count {
763
+ .tlui-cmt-list__item-count {
678
764
  flex-shrink: 0;
679
765
  align-self: center;
680
766
  font-size: 12px;
@@ -683,70 +769,76 @@
683
769
 
684
770
  /* The comments layer is portaled into the editor container. Pins live in the canvas-in-front layer
685
771
  (beneath the UI panels at z-index 300), so the toolbar and style panel draw over them; the open
686
- thread's popover portals up to the menus layer separately (`.cmt-canvas-popover`) so it isn't
772
+ thread's popover portals up to the menus layer separately (`.tlui-cmt-canvas-popover`) so it isn't
687
773
  clipped. Click-through except on its own children. */
688
- .cmt-canvas-layer {
774
+ .tlui-cmt-canvas-layer {
689
775
  position: absolute;
690
776
  inset: 0;
691
777
  z-index: var(--tl-layer-canvas-in-front);
692
778
  pointer-events: none;
693
779
  }
694
780
 
695
- .cmt-canvas-pin,
696
- .cmt-canvas-cluster,
697
- .cmt-canvas-composer {
781
+ .tlui-cmt-canvas-pin,
782
+ .tlui-cmt-canvas-cluster,
783
+ .tlui-cmt-canvas-composer {
698
784
  position: absolute;
699
785
  }
700
786
 
701
- .cmt-canvas-pin,
702
- .cmt-canvas-composer {
787
+ .tlui-cmt-canvas-composer {
703
788
  pointer-events: auto;
704
789
  }
705
790
 
791
+ /* The pin's only interactive surface is the square hit layer below — the wrapper itself is
792
+ inert. Its box sits at the anchor point, not over the (translated) visual, so letting it take
793
+ events would put a phantom hit zone beside the pin. */
794
+ .tlui-cmt-canvas-pin {
795
+ pointer-events: none;
796
+ }
797
+
706
798
  /* Badges are clickable (zoom to the cluster's first split). */
707
- .cmt-canvas-cluster {
799
+ .tlui-cmt-canvas-cluster {
708
800
  transform: translate(-50%, -50%);
709
801
  pointer-events: auto;
710
802
  cursor: pointer;
711
803
  }
712
804
 
713
- .cmt-cluster-fade {
805
+ .tlui-cmt-cluster-fade {
714
806
  opacity: 1;
715
807
  transition: opacity 150ms ease;
716
808
  }
717
809
 
718
- .cmt-cluster-fade--entering {
810
+ .tlui-cmt-cluster-fade--entering {
719
811
  opacity: 0;
720
812
  }
721
813
 
722
- .cmt-cluster-fade--present {
814
+ .tlui-cmt-cluster-fade--present {
723
815
  opacity: 1;
724
816
  }
725
817
 
726
- .cmt-cluster-fade--exiting {
818
+ .tlui-cmt-cluster-fade--exiting {
727
819
  opacity: 0;
728
820
  }
729
821
 
730
- .cmt-cluster-fade--entering *,
731
- .cmt-cluster-fade--exiting * {
822
+ .tlui-cmt-cluster-fade--entering *,
823
+ .tlui-cmt-cluster-fade--exiting * {
732
824
  pointer-events: none !important;
733
825
  }
734
826
 
735
827
  @media (prefers-reduced-motion: reduce) {
736
- .cmt-cluster-fade {
828
+ .tlui-cmt-cluster-fade {
737
829
  transition: none;
738
830
  }
739
831
  }
740
832
 
741
833
  /* The open thread (its pin + popover) sits above the other pins, so nearby markers don't
742
834
  overlap its popover — they tuck behind it. */
743
- .cmt-canvas-pin--open {
835
+ .tlui-cmt-canvas-pin--open {
744
836
  z-index: 1;
745
837
  }
746
838
 
747
839
  /* A region anchor's area: a dashed box under the pins, non-interactive so canvas events pass
748
840
  through. Drawn for the live drag draft and for a region thread while hovered or open. */
749
- .cmt-canvas-region {
841
+ .tlui-cmt-canvas-region {
750
842
  position: absolute;
751
843
  pointer-events: none;
752
844
  border: 2px dashed var(--tl-color-selected);
@@ -756,13 +848,13 @@
756
848
 
757
849
  /* A movable region body (the 'body'/'both' move modes): draggable to translate the whole region.
758
850
  Interactive, so it captures the interior while shown — the tradeoff of dragging the body. */
759
- .cmt-canvas-region--movable {
851
+ .tlui-cmt-canvas-region--movable {
760
852
  pointer-events: auto;
761
853
  cursor: move;
762
854
  }
763
855
 
764
856
  /* Corner resize handles on a region box (three corners; the pin corner is the move handle). */
765
- .cmt-canvas-region-handle {
857
+ .tlui-cmt-canvas-region-handle {
766
858
  position: absolute;
767
859
  width: 9px;
768
860
  height: 9px;
@@ -774,19 +866,47 @@
774
866
  touch-action: none;
775
867
  }
776
868
 
777
- /* Centre the pin marker on its anchor point. */
778
- .cmt-canvas-pin__marker {
869
+ /* Anchor the pin by its bottom-left corner, so the marker's one sharp corner (the pin shape's
870
+ 3px bottom-left) points at the exact anchor point. */
871
+ .tlui-cmt-canvas-pin__marker {
872
+ position: relative;
779
873
  width: max-content;
780
- transform: translate(-50%, -50%);
781
- cursor: grab;
874
+ transform: translate(0, -100%);
875
+ /* Default at rest, like hovering a shape; the editor's move cursor while dragging (below). */
876
+ cursor: var(--tl-cursor-default);
782
877
  touch-action: none;
878
+ pointer-events: none;
879
+ }
880
+
881
+ /* Dragging a pin shows the same move cursor as dragging a shape. */
882
+ .tlui-cmt-canvas-pin--dragging .tlui-cmt-canvas-pin__marker {
883
+ cursor: var(--tl-cursor-move);
884
+ }
885
+
886
+ /* The predictable hit area: a fixed square over the marker's box, and the only part of the pin
887
+ that takes pointer events. Events over it target the marker (a pseudo-element's events report
888
+ its originating element), so the marker's handlers and :hover keep working — but the hit area
889
+ no longer stretches with pin content or scales with the hover transform. */
890
+ .tlui-cmt-canvas-pin__marker::after {
891
+ content: '';
892
+ position: absolute;
893
+ inset: 0;
894
+ pointer-events: auto;
783
895
  }
784
- .cmt-canvas-pin__marker:active {
785
- cursor: grabbing;
896
+
897
+ /* With the hit layer targeting the marker, the pin visual is never the hovered element itself
898
+ (`:hover` matches the target and its ancestors, and the pin is the marker's child) — so the
899
+ canvas pin's hover styling keys off the marker. The hover shadow is for closed pins only: an
900
+ open pin keeps its selection ring, which the shadow would otherwise override. */
901
+ .tlui-cmt-canvas-pin__marker:hover .tlui-cmt-pin {
902
+ transform: scale(1.08);
903
+ }
904
+ .tlui-cmt-canvas-pin__marker:hover .tlui-cmt-pin:not(.tlui-cmt-pin--open) {
905
+ box-shadow: 0 3px 10px rgba(0, 0, 0, 0.32);
786
906
  }
787
907
 
788
908
  /* The open thread's popover — portaled to the menus layer (above the UI), positioned at the pin. */
789
- .cmt-canvas-popover {
909
+ .tlui-cmt-canvas-popover {
790
910
  position: absolute;
791
911
  z-index: var(--tl-layer-menus);
792
912
  pointer-events: auto;
@@ -795,32 +915,41 @@
795
915
  /* The placement composer — a distinct floating view (portaled to the menus layer, below the click
796
916
  point): a pencil "draft" avatar beside a pill field that is itself the surface (no wrapping
797
917
  panel). Scoped here so the in-thread reply composer keeps its own squarer look. */
798
- .cmt-canvas-composer {
918
+ .tlui-cmt-canvas-composer {
799
919
  position: absolute;
800
920
  z-index: var(--tl-layer-menus);
801
921
  pointer-events: auto;
802
- transform: translateY(8px);
922
+ /* Anchor the draft avatar bottom-left like the pins it becomes: it is 34px wide and sits 4px
923
+ into the row, so its bottom-left corner is 4px right of and 4 + 34 = 38px below the
924
+ composer's top-left corner. */
925
+ transform: translate(-4px, -38px);
803
926
  /* The rich-text editor has no intrinsic width (unlike the old <input>), so give the floating
804
927
  placement composer a definite width or it collapses to nothing. */
805
928
  width: 280px;
806
929
  }
807
- .cmt-canvas-composer .cmt-composer__field {
930
+
931
+ /* A region placement centres the draft avatar on the region's pin corner — the pin it becomes
932
+ straddles that corner. The avatar's centre sits 4 + 34/2 = 21px into the composer. */
933
+ .tlui-cmt-canvas-composer--region {
934
+ transform: translate(-21px, -21px);
935
+ }
936
+ .tlui-cmt-canvas-composer .tlui-cmt-composer__field {
808
937
  background: var(--tl-color-panel);
809
938
  border-color: transparent;
810
939
  border-radius: var(--tl-radius-4);
811
940
  box-shadow: var(--tl-shadow-2);
812
941
  }
813
942
 
814
- /* The comments list panel — a right-side surface shown while the comment tool is active. Below
815
- the popover layer, so an open thread still draws over it. Sits under the top-right share panel
816
- (top offset clears its ~48px height) and sizes to its content, scrolling past max-height rather
817
- than stretching the full canvas height. */
818
- .cmt-canvas-sidebar {
943
+ /* The comments list panel — a right-side surface shown while the comments sidebar is open. Below
944
+ the popover layer, so an open thread still draws over it. Its top aligns flush with the style
945
+ panel (48px from the top, clearing the share panel) and it sizes to its content, scrolling past
946
+ max-height rather than stretching the full canvas height. */
947
+ .tlui-cmt-canvas-sidebar {
819
948
  position: absolute;
820
- top: 56px;
949
+ top: 48px;
821
950
  right: 8px;
822
951
  width: 280px;
823
- max-height: calc(100% - 64px);
952
+ max-height: calc(100% - 56px);
824
953
  z-index: var(--tl-layer-panels);
825
954
  pointer-events: auto;
826
955
  display: flex;