@slotted/styles 0.1.0-beta.1 → 0.1.0-beta.10

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 (176) hide show
  1. package/package.json +1 -1
  2. package/src/accordion/accordion.css +10 -10
  3. package/src/action-bar/action-bar.css +31 -32
  4. package/src/action-sheet/action-sheet.css +36 -36
  5. package/src/alert/alert.css +43 -35
  6. package/src/alert/alert.tokens.json +5 -0
  7. package/src/app-shell/app-shell.css +356 -301
  8. package/src/aspect-ratio/aspect-ratio.css +9 -9
  9. package/src/attachment/attachment.css +91 -99
  10. package/src/avatar/avatar.css +71 -41
  11. package/src/avatar/avatar.tokens.json +7 -0
  12. package/src/avatar-group/avatar-group.css +21 -22
  13. package/src/badge/badge.css +45 -37
  14. package/src/badge/badge.tokens.json +5 -0
  15. package/src/breadcrumb/breadcrumb.css +37 -37
  16. package/src/button/button.css +139 -64
  17. package/src/button/button.tokens.json +10 -0
  18. package/src/button-group/button-group.css +76 -72
  19. package/src/button-group/button-group.tokens.json +2 -0
  20. package/src/calendar/calendar.css +93 -103
  21. package/src/card/card.css +54 -61
  22. package/src/carousel/carousel.css +150 -161
  23. package/src/cascader/cascader.css +152 -153
  24. package/src/cascader/cascader.tokens.json +1 -0
  25. package/src/chart/chart.css +242 -239
  26. package/src/chart/chart.tokens.json +1 -0
  27. package/src/checkbox/checkbox.css +119 -124
  28. package/src/checkbox-group/checkbox-group.css +7 -7
  29. package/src/code-block/code-block.css +81 -85
  30. package/src/collapsible/collapsible.css +69 -76
  31. package/src/color-picker/color-picker.css +83 -91
  32. package/src/column-manager/column-manager.css +106 -114
  33. package/src/combobox/combobox.css +132 -107
  34. package/src/combobox/combobox.tokens.json +1 -0
  35. package/src/command-palette/command-palette.css +84 -90
  36. package/src/container/container.css +24 -24
  37. package/src/context-menu/context-menu.css +8 -8
  38. package/src/currency-field/currency-field.css +210 -88
  39. package/src/currency-field/currency-field.tokens.json +13 -0
  40. package/src/dashboard-grid/dashboard-grid.css +148 -116
  41. package/src/data-grid/data-grid.css +504 -469
  42. package/src/data-grid/data-grid.tokens.json +2 -0
  43. package/src/data-list/data-list.css +81 -70
  44. package/src/data-list/data-list.tokens.json +2 -1
  45. package/src/date-field/date-field.css +55 -52
  46. package/src/date-field/date-field.tokens.json +1 -0
  47. package/src/date-picker/date-picker.css +40 -42
  48. package/src/date-range-picker/date-range-picker.css +114 -118
  49. package/src/datetime-field/datetime-field.css +78 -80
  50. package/src/datetime-field/datetime-field.tokens.json +1 -0
  51. package/src/datetime-picker/datetime-picker.css +61 -63
  52. package/src/datetime-range-picker/datetime-range-picker.css +149 -156
  53. package/src/description-list/description-list.css +61 -64
  54. package/src/detail-panel/detail-panel.css +70 -70
  55. package/src/dialog/dialog.css +334 -153
  56. package/src/dialog/dialog.tokens.json +5 -0
  57. package/src/divider/divider.css +18 -18
  58. package/src/drawer/drawer.css +186 -209
  59. package/src/entity-picker/entity-picker.css +238 -241
  60. package/src/entity-picker/entity-picker.tokens.json +1 -0
  61. package/src/event-calendar/event-calendar.css +343 -385
  62. package/src/field/field.css +74 -78
  63. package/src/field-group/field-group.css +22 -25
  64. package/src/filter-bar/filter-bar.css +193 -209
  65. package/src/form/form.css +34 -24
  66. package/src/form/form.tokens.json +1 -0
  67. package/src/fullscreen/fullscreen.css +24 -25
  68. package/src/grid/grid.css +28 -28
  69. package/src/highlight/highlight.css +6 -6
  70. package/src/hover-card/hover-card.css +6 -6
  71. package/src/icon/icon.css +19 -15
  72. package/src/icon/icon.tokens.json +1 -0
  73. package/src/image/image.css +39 -39
  74. package/src/import-export-center/import-export-center.css +135 -156
  75. package/src/inline/inline.css +27 -27
  76. package/src/inline-message/inline-message.css +52 -28
  77. package/src/inline-message/inline-message.tokens.json +4 -0
  78. package/src/kbd/kbd.css +30 -26
  79. package/src/link/link.css +15 -15
  80. package/src/list/list.css +44 -17
  81. package/src/list/list.tokens.json +4 -0
  82. package/src/list-item/list-item.css +80 -66
  83. package/src/list-item/list-item.tokens.json +7 -0
  84. package/src/listbox/listbox.css +56 -59
  85. package/src/loading-overlay/loading-overlay.css +75 -92
  86. package/src/markdown/markdown.css +17 -17
  87. package/src/menu/menu.css +83 -63
  88. package/src/menubar/menubar.css +13 -13
  89. package/src/message/message.css +182 -202
  90. package/src/message/message.tokens.json +5 -0
  91. package/src/message-scroller/message-scroller.css +41 -42
  92. package/src/multi-select/multi-select.css +152 -145
  93. package/src/multi-select/multi-select.tokens.json +1 -0
  94. package/src/navigation-menu/navigation-menu.css +167 -188
  95. package/src/notification-center/notification-center.css +140 -148
  96. package/src/notification-center/notification-center.tokens.json +3 -0
  97. package/src/number-field/number-field.css +84 -83
  98. package/src/number-field/number-field.tokens.json +1 -0
  99. package/src/otp-input/otp-input.css +67 -57
  100. package/src/otp-input/otp-input.tokens.json +1 -0
  101. package/src/page/page.css +23 -23
  102. package/src/page-header/page-header.css +268 -281
  103. package/src/page-header/page-header.tokens.json +1 -0
  104. package/src/pagination/pagination.css +68 -72
  105. package/src/popover/popover.css +40 -49
  106. package/src/progress-indicator/progress-indicator.css +177 -120
  107. package/src/progress-indicator/progress-indicator.tokens.json +1 -1
  108. package/src/prompt-composer/prompt-composer.css +221 -102
  109. package/src/prompt-composer/prompt-composer.tokens.json +15 -0
  110. package/src/prose/prose.css +71 -75
  111. package/src/radio-group/radio-group.css +98 -103
  112. package/src/rating/rating.css +136 -132
  113. package/src/rating/rating.tokens.json +1 -0
  114. package/src/result-state/result-state.css +74 -77
  115. package/src/runtime-properties.mjs +2 -0
  116. package/src/saved-views/saved-views.css +41 -47
  117. package/src/scroll-area/scroll-area.css +39 -32
  118. package/src/section/section.css +161 -41
  119. package/src/section/section.tokens.json +7 -2
  120. package/src/segmented-control/segmented-control.css +254 -97
  121. package/src/segmented-control/segmented-control.tokens.json +15 -11
  122. package/src/select/select.css +118 -117
  123. package/src/select/select.tokens.json +1 -0
  124. package/src/side-navigation/side-navigation.css +179 -182
  125. package/src/side-navigation/side-navigation.tokens.json +1 -0
  126. package/src/skeleton/skeleton.css +47 -48
  127. package/src/slider/slider.css +86 -88
  128. package/src/sparkline/sparkline.css +62 -40
  129. package/src/sparkline/sparkline.tokens.json +2 -0
  130. package/src/spinner/spinner.css +39 -182
  131. package/src/spinner/spinner.tokens.json +0 -2
  132. package/src/split-button/split-button.css +30 -31
  133. package/src/split-button/split-button.tokens.json +1 -0
  134. package/src/splitter/splitter.css +35 -35
  135. package/src/stack/stack.css +24 -24
  136. package/src/stat-card/stat-card.css +341 -224
  137. package/src/stat-card/stat-card.tokens.json +3 -0
  138. package/src/status-indicator/status-indicator.css +28 -28
  139. package/src/stepper/stepper.css +58 -62
  140. package/src/switch/switch.css +86 -92
  141. package/src/table/table.css +310 -165
  142. package/src/table/table.tokens.json +6 -0
  143. package/src/table-of-contents/table-of-contents.css +51 -54
  144. package/src/tabs/tabs.css +330 -302
  145. package/src/tabs/tabs.tokens.json +8 -5
  146. package/src/tag/tag.css +79 -71
  147. package/src/tag/tag.tokens.json +9 -0
  148. package/src/tags-input/tags-input.css +145 -82
  149. package/src/tags-input/tags-input.tokens.json +7 -1
  150. package/src/text-field/text-field.css +132 -136
  151. package/src/text-field/text-field.tokens.json +1 -0
  152. package/src/textarea/textarea.css +31 -28
  153. package/src/textarea/textarea.tokens.json +1 -0
  154. package/src/time-field/time-field.css +72 -69
  155. package/src/time-field/time-field.tokens.json +1 -0
  156. package/src/time-picker/time-picker.css +56 -58
  157. package/src/time-range-picker/time-range-picker.css +126 -133
  158. package/src/timeline/timeline.css +254 -266
  159. package/src/timeline/timeline.tokens.json +5 -0
  160. package/src/toast/toast.css +89 -90
  161. package/src/toast/toast.tokens.json +5 -0
  162. package/src/toggle/toggle.css +62 -25
  163. package/src/toggle/toggle.tokens.json +8 -0
  164. package/src/toggle-group/toggle-group.css +106 -60
  165. package/src/toggle-group/toggle-group.tokens.json +10 -0
  166. package/src/toolbar/toolbar.css +30 -35
  167. package/src/tooltip/tooltip.css +26 -26
  168. package/src/top-navigation/top-navigation.css +243 -259
  169. package/src/tour/tour.css +51 -60
  170. package/src/transfer/transfer.css +160 -164
  171. package/src/tree/tree.css +103 -111
  172. package/src/typography/typography.css +40 -36
  173. package/src/typography/typography.tokens.json +1 -0
  174. package/src/upload/upload.css +224 -224
  175. package/src/visually-hidden/visually-hidden.css +1 -1
  176. package/src/wizard/wizard.css +185 -197
@@ -13,7 +13,7 @@
13
13
  * both `Message` and `Bubble`, and two answers to one question can disagree
14
14
  * (`docs/history/designs/2026-09-30-message-design.md` §2.2).
15
15
  */
16
- [data-ui='message'][data-part='root'] {
16
+ [data-ui-message][data-part-root] {
17
17
  /**
18
18
  * The avatar column is the small avatar step, which the theme restates per
19
19
  * density; ReUI's 32 has no step there (dossier §3), and a row that follows
@@ -62,16 +62,15 @@
62
62
  * `MessageAvatar` in each of them (`c-message-6`); the column is read here
63
63
  * from the DOM instead.
64
64
  */
65
- [data-ui='message'][data-part='root']:has(> [data-part='avatar']),
66
- [data-ui='message'][data-part='group']:has([data-part='avatar'])
67
- > [data-ui='message'][data-part='root'] {
65
+ [data-ui-message][data-part-root]:has(> [data-part-avatar]),
66
+ [data-ui-message][data-part-group]:has([data-part-avatar]) > [data-ui-message][data-part-root] {
68
67
  grid-template-areas: 'avatar body';
69
68
  grid-template-columns: var(--_avatar-size) minmax(0, 1fr);
70
69
  }
71
70
 
72
- [data-ui='message'][data-part='root'][data-align='end']:has(> [data-part='avatar']),
73
- [data-ui='message'][data-part='group']:has([data-part='avatar'])
74
- > [data-ui='message'][data-part='root'][data-align='end'] {
71
+ [data-ui-message][data-part-root][data-align='end']:has(> [data-part-avatar]),
72
+ [data-ui-message][data-part-group]:has([data-part-avatar])
73
+ > [data-ui-message][data-part-root][data-align='end'] {
75
74
  grid-template-areas: 'body avatar';
76
75
  grid-template-columns: minmax(0, 1fr) var(--_avatar-size);
77
76
  }
@@ -81,7 +80,7 @@
81
80
  * rather than of the footer under it: in a run it marks where the run ends,
82
81
  * which is where the reader's eye arrives.
83
82
  */
84
- [data-ui='message'][data-part='root'] > [data-part='avatar'] {
83
+ [data-ui-message][data-part-root] > [data-part-avatar] {
85
84
  grid-area: avatar;
86
85
  display: flex;
87
86
  align-self: end;
@@ -90,12 +89,12 @@
90
89
  min-block-size: var(--_avatar-size);
91
90
  }
92
91
 
93
- [data-ui='message'][data-part='root']:has(> [data-part='body'] > [data-part='footer'])
94
- > [data-part='avatar'] {
92
+ [data-ui-message][data-part-root]:has(> [data-part-body] > [data-part-footer])
93
+ > [data-part-avatar] {
95
94
  margin-block-end: calc(var(--_meta-leading) + var(--_stack-gap));
96
95
  }
97
96
 
98
- [data-ui='message'][data-part='root'] > [data-part='body'] {
97
+ [data-ui-message][data-part-root] > [data-part-body] {
99
98
  grid-area: body;
100
99
  display: flex;
101
100
  flex-direction: column;
@@ -104,7 +103,7 @@
104
103
  min-inline-size: 0;
105
104
  }
106
105
 
107
- [data-ui='message'][data-part='root'][data-align='end'] > [data-part='body'] {
106
+ [data-ui-message][data-part-root][data-align='end'] > [data-part-body] {
108
107
  align-items: flex-end;
109
108
  }
110
109
 
@@ -116,7 +115,7 @@
116
115
  * sender's side drawn in, it reads as one speaker holding the floor. The
117
116
  * gap between runs belongs to whatever stacks them — the scroller gives it.
118
117
  */
119
- [data-ui='message'][data-part='group'] {
118
+ [data-ui-message][data-part-group] {
120
119
  display: flex;
121
120
  flex-direction: column;
122
121
  gap: var(--slotted-message-run-gap, var(--slotted-space-1, 0.125rem));
@@ -125,7 +124,7 @@
125
124
 
126
125
  /* ── Header and footer ──────────────────────────────────────────────── */
127
126
 
128
- [data-ui='message'][data-part='root'] :is([data-part='header'], [data-part='footer']) {
127
+ [data-ui-message][data-part-root] :is([data-part-header], [data-part-footer]) {
129
128
  display: flex;
130
129
  flex-wrap: wrap;
131
130
  align-items: center;
@@ -139,8 +138,7 @@
139
138
  line-height: var(--_meta-leading);
140
139
  }
141
140
 
142
- [data-ui='message'][data-part='root'][data-align='end']
143
- :is([data-part='header'], [data-part='footer']) {
141
+ [data-ui-message][data-part-root][data-align='end'] :is([data-part-header], [data-part-footer]) {
144
142
  justify-content: flex-end;
145
143
  }
146
144
 
@@ -150,7 +148,7 @@
150
148
  * read aloud, copied with the name and wrapped onto a line of its own.
151
149
  * ReUI asks the consumer to write the dot (`c-message-3`).
152
150
  */
153
- [data-ui='message'][data-part='root'] [data-part='header'] > * + [data-part='time']::before {
151
+ [data-ui-message][data-part-root] [data-part-header] > * + [data-part-time]::before {
154
152
  content: '';
155
153
  display: inline-block;
156
154
  inline-size: var(--slotted-space-2, 0.25rem);
@@ -162,14 +160,14 @@
162
160
  vertical-align: middle;
163
161
  }
164
162
 
165
- [data-ui='message'][data-part='root'] [data-part='author'] {
163
+ [data-ui-message][data-part-root] [data-part-author] {
166
164
  min-inline-size: 0;
167
165
  overflow: hidden;
168
166
  text-overflow: ellipsis;
169
167
  white-space: nowrap;
170
168
  }
171
169
 
172
- [data-ui='message'][data-part='root'] [data-part='time'] {
170
+ [data-ui-message][data-part-root] [data-part-time] {
173
171
  font-variant-numeric: tabular-nums;
174
172
  white-space: nowrap;
175
173
  }
@@ -183,14 +181,11 @@
183
181
  * word of twelve pixels is two voices saying one thing, and the two never
184
182
  * shared a centre line.
185
183
  */
186
- [data-ui='message'][data-part='root'] [data-part='footer'] > [data-part='receipt'] {
184
+ [data-ui-message][data-part-root] [data-part-footer] > [data-part-receipt] {
187
185
  white-space: nowrap;
188
186
  }
189
187
 
190
- [data-ui='message'][data-part='root']
191
- [data-part='footer']
192
- > [data-part='receipt']
193
- > [data-ui='icon'] {
188
+ [data-ui-message][data-part-root] [data-part-footer] > [data-part-receipt] > [data-ui-icon] {
194
189
  display: none;
195
190
  }
196
191
 
@@ -200,7 +195,7 @@
200
195
  * not with the words inside it — so the note reads as the bubble's caption.
201
196
  * The control that sends it again stands beside the surface (`retry`).
202
197
  */
203
- [data-ui='message'][data-part='root'][data-invalid] > [data-part='body'] > [data-part='footer'] {
198
+ [data-ui-message][data-part-root][data-invalid] > [data-part-body] > [data-part-footer] {
204
199
  padding-inline: var(--slotted-space-2, 0.25rem);
205
200
  color: var(--slotted-tone-danger-text);
206
201
  }
@@ -212,7 +207,7 @@
212
207
  * always on a screen that cannot hover: a reveal by hover alone would hide
213
208
  * them from the keyboard and from a finger.
214
209
  */
215
- [data-ui='message'][data-part='root'] [data-part='actions'] {
210
+ [data-ui-message][data-part-root] [data-part-actions] {
216
211
  display: inline-flex;
217
212
  align-items: center;
218
213
  gap: var(--slotted-space-1, 0.125rem);
@@ -220,15 +215,15 @@
220
215
  }
221
216
 
222
217
  @media (hover: hover) {
223
- [data-ui='message'][data-part='root'][data-actions='hover'] [data-part='actions'] {
218
+ [data-ui-message][data-part-root][data-actions='hover'] [data-part-actions] {
224
219
  opacity: 0;
225
220
  }
226
221
 
227
- [data-ui='message'][data-part='root'][data-actions='hover']:is(
222
+ [data-ui-message][data-part-root][data-actions='hover']:is(
228
223
  :hover:not([data-disabled]),
229
224
  :focus-within
230
225
  )
231
- [data-part='actions'] {
226
+ [data-part-actions] {
232
227
  opacity: 1;
233
228
  transition-timing-function: var(--slotted-easing-enter, ease-out);
234
229
  }
@@ -248,7 +243,7 @@
248
243
  * moves only while the step is current, and under reduced motion the words
249
244
  * stand in the plain ink.
250
245
  */
251
- [data-ui='message'][data-part='root'] [data-part='activity'] {
246
+ [data-ui-message][data-part-root] [data-part-activity] {
252
247
  display: inline-flex;
253
248
  flex-direction: column;
254
249
  gap: var(--slotted-space-3, 0.375rem);
@@ -265,7 +260,7 @@
265
260
  line-height: round(up, calc(1em * var(--slotted-line-height-md, 1.5)), 1px);
266
261
  }
267
262
 
268
- [data-ui='message'][data-part='root'] [data-part='activity-step'] {
263
+ [data-ui-message][data-part-root] [data-part-activity-step] {
269
264
  display: flex;
270
265
  align-items: center;
271
266
  gap: var(--slotted-space-4, 0.5rem);
@@ -282,7 +277,7 @@
282
277
  }
283
278
 
284
279
  /** The mark column: a tick, or the ring, in one box so the words line up. */
285
- [data-ui='message'][data-part='root'] [data-part='activity-step'] > :first-child {
280
+ [data-ui-message][data-part-root] [data-part-activity-step] > :first-child {
286
281
  --slotted-icon-size: var(--_glyph-size);
287
282
  --slotted-spinner-size: var(--_glyph-size);
288
283
 
@@ -293,19 +288,19 @@
293
288
  block-size: var(--_glyph-size);
294
289
  }
295
290
 
296
- [data-ui='message'][data-part='root'] [data-part='activity-step'][data-complete] > :first-child {
291
+ [data-ui-message][data-part-root] [data-part-activity-step][data-complete] > :first-child {
297
292
  color: var(--slotted-tone-success-text);
298
293
  }
299
294
 
300
- [data-ui='message'][data-part='root'] [data-part='activity-step'][data-current] {
295
+ [data-ui-message][data-part-root] [data-part-activity-step][data-current] {
301
296
  color: var(--slotted-text);
302
297
  }
303
298
 
304
- [data-ui='message'][data-part='root'] [data-part='activity-step'][data-current] > :first-child {
299
+ [data-ui-message][data-part-root] [data-part-activity-step][data-current] > :first-child {
305
300
  color: var(--slotted-tone-accent-text);
306
301
  }
307
302
 
308
- [data-ui='message'][data-part='root'] [data-part='activity-step'][data-current] > :last-child {
303
+ [data-ui-message][data-part-root] [data-part-activity-step][data-current] > :last-child {
309
304
  --_base: color-mix(in oklab, var(--slotted-text) 72%, var(--slotted-text-muted));
310
305
 
311
306
  background-image: linear-gradient(
@@ -337,20 +332,19 @@
337
332
  * `2 de 3` between two inner controls. The chevron is one glyph turned for
338
333
  * the previous control, and a right-to-left document turns both.
339
334
  */
340
- [data-ui='message'][data-part='root'] [data-part='versions'] {
335
+ [data-ui-message][data-part-root] [data-part-versions] {
341
336
  display: inline-flex;
342
337
  align-items: center;
343
338
  color: var(--slotted-text-muted);
344
339
  }
345
340
 
346
- [data-ui='message'][data-part='root'] [data-part='version-label'] {
341
+ [data-ui-message][data-part-root] [data-part-version-label] {
347
342
  padding-inline: var(--slotted-space-2, 0.25rem);
348
343
  font-variant-numeric: tabular-nums;
349
344
  white-space: nowrap;
350
345
  }
351
346
 
352
- [data-ui='message'][data-part='root']
353
- :is([data-part='version-previous'], [data-part='version-next']) {
347
+ [data-ui-message][data-part-root] :is([data-part-version-previous], [data-part-version-next]) {
354
348
  display: inline-grid;
355
349
  place-items: center;
356
350
  inline-size: var(--_inner-size);
@@ -367,45 +361,45 @@
367
361
  color var(--slotted-duration-short) var(--slotted-easing-standard, ease);
368
362
  }
369
363
 
370
- [data-ui='message'][data-part='root']
371
- :is([data-part='version-previous'], [data-part='version-next'])
372
- > [data-ui='icon'] {
364
+ [data-ui-message][data-part-root]
365
+ :is([data-part-version-previous], [data-part-version-next])
366
+ > [data-ui-icon] {
373
367
  --slotted-icon-size: var(--_glyph-size);
374
368
  }
375
369
 
376
- [data-ui='message'][data-part='root'] [data-part='version-previous'] > [data-ui='icon'] {
370
+ [data-ui-message][data-part-root] [data-part-version-previous] > [data-ui-icon] {
377
371
  scale: -1 1;
378
372
  }
379
373
 
380
- [data-ui='message'][data-part='root']:dir(rtl)
381
- :is([data-part='version-previous'], [data-part='version-next'])
382
- > [data-ui='icon'] {
374
+ [data-ui-message][data-part-root]:dir(rtl)
375
+ :is([data-part-version-previous], [data-part-version-next])
376
+ > [data-ui-icon] {
383
377
  scale: -1 1;
384
378
  }
385
379
 
386
- [data-ui='message'][data-part='root']:dir(rtl) [data-part='version-previous'] > [data-ui='icon'] {
380
+ [data-ui-message][data-part-root]:dir(rtl) [data-part-version-previous] > [data-ui-icon] {
387
381
  scale: 1 1;
388
382
  }
389
383
 
390
- [data-ui='message'][data-part='root']
391
- :is([data-part='version-previous'], [data-part='version-next']):hover:not(:disabled) {
384
+ [data-ui-message][data-part-root]
385
+ :is([data-part-version-previous], [data-part-version-next]):hover:not(:disabled) {
392
386
  background-color: var(--slotted-tone-secondary-subtle-hover);
393
387
  color: var(--slotted-text);
394
388
  }
395
389
 
396
- [data-ui='message'][data-part='root']
397
- :is([data-part='version-previous'], [data-part='version-next']):active:not(:disabled) {
390
+ [data-ui-message][data-part-root]
391
+ :is([data-part-version-previous], [data-part-version-next]):active:not(:disabled) {
398
392
  background-color: var(--slotted-tone-secondary-subtle-active);
399
393
  color: var(--slotted-text);
400
394
  }
401
395
 
402
- [data-ui='message'][data-part='root']
403
- :is([data-part='version-previous'], [data-part='version-next']):disabled {
396
+ [data-ui-message][data-part-root]
397
+ :is([data-part-version-previous], [data-part-version-next]):disabled {
404
398
  color: var(--slotted-disabled-foreground);
405
399
  }
406
400
 
407
- [data-ui='message'][data-part='root']
408
- :is([data-part='version-previous'], [data-part='version-next']):focus-visible {
401
+ [data-ui-message][data-part-root]
402
+ :is([data-part-version-previous], [data-part-version-next]):focus-visible {
409
403
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color);
410
404
  outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
411
405
  }
@@ -426,7 +420,7 @@
426
420
  * avatar at the top beside the name, the words unframed under it, and a
427
421
  * band under the pointer that says which message the actions belong to.
428
422
  */
429
- [data-ui='message'][data-part='root'][data-layout='thread'] {
423
+ [data-ui-message][data-part-root][data-layout='thread'] {
430
424
  --_avatar-size: var(--slotted-message-thread-avatar-size, var(--slotted-avatar-size-md, 36px));
431
425
  --_pad-inline: 0px;
432
426
 
@@ -436,18 +430,18 @@
436
430
  transition: background-color var(--slotted-duration-short) var(--slotted-easing-standard, ease);
437
431
  }
438
432
 
439
- [data-ui='message'][data-part='root'][data-layout='thread'] > [data-part='avatar'] {
433
+ [data-ui-message][data-part-root][data-layout='thread'] > [data-part-avatar] {
440
434
  align-self: start;
441
435
  margin-block-end: 0;
442
436
  }
443
437
 
444
- [data-ui='message'][data-part='root'][data-layout='thread'] [data-part='author'] {
438
+ [data-ui-message][data-part-root][data-layout='thread'] [data-part-author] {
445
439
  color: var(--slotted-text);
446
440
  font-size: var(--slotted-control-font-size-md, 13px);
447
441
  font-weight: var(--slotted-font-weight-semibold, 600);
448
442
  }
449
443
 
450
- [data-ui='message'][data-part='root'][data-layout='thread']:hover:not([data-disabled]) {
444
+ [data-ui-message][data-part-root][data-layout='thread']:hover:not([data-disabled]) {
451
445
  background-color: var(--slotted-tone-secondary-subtle-hover);
452
446
  }
453
447
 
@@ -459,14 +453,14 @@
459
453
  * A plate that is always painted, on a touch screen or with `always`, floated
460
454
  * over the words and covered them at 360 pixels.
461
455
  */
462
- [data-ui='message'][data-part='root'][data-layout='thread'] > [data-part='actions'] {
456
+ [data-ui-message][data-part-root][data-layout='thread'] > [data-part-actions] {
463
457
  grid-column: body;
464
458
  justify-self: start;
465
459
  }
466
460
 
467
461
  @media (hover: hover) {
468
- [data-ui='message'][data-part='root'][data-layout='thread'][data-actions='hover']
469
- > [data-part='actions'] {
462
+ [data-ui-message][data-part-root][data-layout='thread'][data-actions='hover']
463
+ > [data-part-actions] {
470
464
  position: absolute;
471
465
  inset-block-start: calc(var(--slotted-space-2, 0.25rem) * -1);
472
466
  inset-inline-end: var(--slotted-space-4, 0.5rem);
@@ -480,7 +474,7 @@
480
474
 
481
475
  /* ══ The bubble ════════════════════════════════════════════════════════ */
482
476
 
483
- [data-ui='message'][data-part='bubble'] {
477
+ [data-ui-message][data-part-bubble] {
484
478
  /**
485
479
  * The five tones, read into the roles a painting needs. `soft` writes in
486
480
  * the page's ink on the accent and secondary grounds — a paragraph set in
@@ -538,14 +532,14 @@
538
532
  max-inline-size: var(--slotted-message-bubble-share, 80%);
539
533
  }
540
534
 
541
- [data-ui='message'][data-part='bubble'][data-tone='accent'] {
535
+ [data-ui-message][data-part-bubble][data-tone='accent'] {
542
536
  --_solid: var(--slotted-tone-accent-solid);
543
537
  --_on-solid: var(--slotted-tone-accent-on-solid);
544
538
  --_surface: var(--slotted-tone-accent-surface);
545
539
  --_border: var(--slotted-tone-accent-border);
546
540
  }
547
541
 
548
- [data-ui='message'][data-part='bubble'][data-tone='success'] {
542
+ [data-ui-message][data-part-bubble][data-tone='success'] {
549
543
  --_solid: var(--slotted-tone-success-solid);
550
544
  --_on-solid: var(--slotted-tone-success-on-solid);
551
545
  --_surface: var(--slotted-tone-success-surface);
@@ -553,7 +547,15 @@
553
547
  --_soft-ink: var(--slotted-tone-success-text);
554
548
  }
555
549
 
556
- [data-ui='message'][data-part='bubble'][data-tone='warning'] {
550
+ [data-ui-message][data-part-bubble][data-tone='info'] {
551
+ --_solid: var(--slotted-tone-info-solid);
552
+ --_on-solid: var(--slotted-tone-info-on-solid);
553
+ --_surface: var(--slotted-tone-info-surface);
554
+ --_border: var(--slotted-tone-info-border);
555
+ --_soft-ink: var(--slotted-tone-info-text);
556
+ }
557
+
558
+ [data-ui-message][data-part-bubble][data-tone='warning'] {
557
559
  --_solid: var(--slotted-tone-warning-solid);
558
560
  --_on-solid: var(--slotted-tone-warning-on-solid);
559
561
  --_surface: var(--slotted-tone-warning-surface);
@@ -561,7 +563,7 @@
561
563
  --_soft-ink: var(--slotted-tone-warning-text);
562
564
  }
563
565
 
564
- [data-ui='message'][data-part='bubble'][data-tone='danger'] {
566
+ [data-ui-message][data-part-bubble][data-tone='danger'] {
565
567
  --_solid: var(--slotted-tone-danger-solid);
566
568
  --_on-solid: var(--slotted-tone-danger-on-solid);
567
569
  --_surface: var(--slotted-tone-danger-surface);
@@ -580,7 +582,7 @@
580
582
  * page's ground, `plain` no box at all — the unframed assistant answer that
581
583
  * takes the whole row.
582
584
  */
583
- [data-ui='message'][data-part='bubble'] > [data-part='content'] {
585
+ [data-ui-message][data-part-bubble] > [data-part-content] {
584
586
  --_ground: var(--_surface);
585
587
  --_ink: var(--_soft-ink);
586
588
  --_edge: color-mix(in oklab, var(--_surface), var(--slotted-border-subtle));
@@ -615,25 +617,25 @@
615
617
  unicode-bidi: plaintext;
616
618
  }
617
619
 
618
- [data-ui='message'][data-part='bubble'][data-variant='solid'] > [data-part='content'] {
620
+ [data-ui-message][data-part-bubble][data-variant='solid'] > [data-part-content] {
619
621
  --_ground: var(--_solid);
620
622
  --_ink: var(--_on-solid);
621
623
  --_edge: var(--_solid);
622
624
  }
623
625
 
624
- [data-ui='message'][data-part='bubble'][data-variant='outline'] > [data-part='content'] {
626
+ [data-ui-message][data-part-bubble][data-variant='outline'] > [data-part-content] {
625
627
  --_ground: var(--slotted-surface);
626
628
  --_ink: var(--slotted-text);
627
629
  --_edge: var(--_border);
628
630
  }
629
631
 
630
- [data-ui='message'][data-part='bubble'][data-variant='plain'] {
632
+ [data-ui-message][data-part-bubble][data-variant='plain'] {
631
633
  --_pad-inline: 0px;
632
634
 
633
635
  max-inline-size: 100%;
634
636
  }
635
637
 
636
- [data-ui='message'][data-part='bubble'][data-variant='plain'] > [data-part='content'] {
638
+ [data-ui-message][data-part-bubble][data-variant='plain'] > [data-part-content] {
637
639
  --_ground: transparent;
638
640
  --_ink: var(--slotted-text);
639
641
  --_edge: transparent;
@@ -647,13 +649,11 @@
647
649
  * The bubble sits on the sender's side, and so does everything it carries:
648
650
  * the corners that join a run are the ones that face the avatar.
649
651
  */
650
- [data-ui='message'][data-part='root'][data-align='end'] [data-part='bubble'] {
652
+ [data-ui-message][data-part-root][data-align='end'] [data-part-bubble] {
651
653
  align-items: flex-end;
652
654
  }
653
655
 
654
- [data-ui='message'][data-part='root'][data-align='end']
655
- [data-part='bubble']
656
- > [data-part='content'] {
656
+ [data-ui-message][data-part-root][data-align='end'] [data-part-bubble] > [data-part-content] {
657
657
  border-start-start-radius: var(--_radius);
658
658
  border-start-end-radius: var(--_top-side);
659
659
  border-end-start-radius: var(--_radius);
@@ -668,19 +668,19 @@
668
668
  * of a group. A run reads as one speaker by its shape, with no position
669
669
  * prop on each message (Chatscope asks for `first`, `normal`, `last`).
670
670
  */
671
- [data-ui='message'][data-part='bubble']:has(~ [data-part='bubble']),
672
- [data-ui='message'][data-part='group']
673
- > [data-ui='message'][data-part='root']:not(:last-child)
674
- > [data-part='body']
675
- > [data-part='bubble']:not(:has(~ [data-part='bubble'])) {
671
+ [data-ui-message][data-part-bubble]:has(~ [data-part-bubble]),
672
+ [data-ui-message][data-part-group]
673
+ > [data-ui-message][data-part-root]:not(:last-child)
674
+ > [data-part-body]
675
+ > [data-part-bubble]:not(:has(~ [data-part-bubble])) {
676
676
  --_bottom-side: var(--_radius-joined);
677
677
  }
678
678
 
679
- [data-ui='message'][data-part='bubble'] ~ [data-part='bubble'],
680
- [data-ui='message'][data-part='group']
681
- > [data-ui='message'][data-part='root']:not(:first-child)
682
- > [data-part='body']
683
- > [data-part='bubble']:not([data-part='bubble'] ~ [data-part='bubble']) {
679
+ [data-ui-message][data-part-bubble] ~ [data-part-bubble],
680
+ [data-ui-message][data-part-group]
681
+ > [data-ui-message][data-part-root]:not(:first-child)
682
+ > [data-part-body]
683
+ > [data-part-bubble]:not([data-part-bubble] ~ [data-part-bubble]) {
684
684
  --_top-side: var(--_radius-joined);
685
685
  }
686
686
 
@@ -694,7 +694,7 @@
694
694
  * `light`, 0.044 under the secondary ground, over the 0.02 step
695
695
  * `theme-conformance` asks of a hover, and the press twice that.
696
696
  */
697
- [data-ui='message'][data-part='bubble'] > [data-part='content']:is(button, a) {
697
+ [data-ui-message][data-part-bubble] > [data-part-content]:is(button, a) {
698
698
  --_ground-hover: color-mix(
699
699
  in oklab,
700
700
  var(--_ink) var(--slotted-message-state-layer-hover, 6%),
@@ -713,25 +713,24 @@
713
713
  border-color var(--slotted-duration-short) var(--slotted-easing-standard, ease);
714
714
  }
715
715
 
716
- [data-ui='message'][data-part='bubble'][data-variant='plain']
717
- > [data-part='content']:is(button, a) {
716
+ [data-ui-message][data-part-bubble][data-variant='plain'] > [data-part-content]:is(button, a) {
718
717
  padding-block: var(--slotted-space-1, 0.125rem);
719
718
  padding-inline: var(--slotted-space-2, 0.25rem);
720
719
  margin-inline: calc(var(--slotted-space-2, 0.25rem) * -1);
721
720
  border-radius: var(--slotted-radius-sm, 4px);
722
721
  }
723
722
 
724
- [data-ui='message'][data-part='bubble']
725
- > [data-part='content']:is(button, a):hover:not(:disabled):not([data-disabled]) {
723
+ [data-ui-message][data-part-bubble]
724
+ > [data-part-content]:is(button, a):hover:not(:disabled):not([data-disabled]) {
726
725
  background-color: var(--_ground-hover);
727
726
  }
728
727
 
729
- [data-ui='message'][data-part='bubble']
730
- > [data-part='content']:is(button, a):active:not(:disabled):not([data-disabled]) {
728
+ [data-ui-message][data-part-bubble]
729
+ > [data-part-content]:is(button, a):active:not(:disabled):not([data-disabled]) {
731
730
  background-color: var(--_ground-active);
732
731
  }
733
732
 
734
- [data-ui='message'][data-part='bubble'] > [data-part='content']:is(button, a):focus-visible {
733
+ [data-ui-message][data-part-bubble] > [data-part-content]:is(button, a):focus-visible {
735
734
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color);
736
735
  outline-offset: var(--slotted-focus-ring-offset, 2px);
737
736
  }
@@ -752,7 +751,7 @@
752
751
  * beside a line of text, the hanging meta read as misaligned. Read is the one state that changes the ink: full strength on a
753
752
  * solid fill, the accent on a tinted one; the other marks differ by shape.
754
753
  */
755
- [data-ui='message'][data-part='bubble'] [data-part='meta'] {
754
+ [data-ui-message][data-part-bubble] [data-part-meta] {
756
755
  /*
757
756
  * Ninety per cent of the bubble's ink: the lowest share at which the hour
758
757
  * keeps 4.5:1 on every fill — 4.50 on the accent in `dark`, 5.74 in
@@ -778,11 +777,11 @@
778
777
  translate: 0 1px;
779
778
  }
780
779
 
781
- [data-ui='message'][data-part='bubble'][data-variant='solid'] [data-part='meta'] {
780
+ [data-ui-message][data-part-bubble][data-variant='solid'] [data-part-meta] {
782
781
  --_read-ink: var(--_on-solid);
783
782
  }
784
783
 
785
- [data-ui='message'][data-part='bubble'] [data-part='meta'] [data-part='receipt'] {
784
+ [data-ui-message][data-part-bubble] [data-part-meta] [data-part-receipt] {
786
785
  display: inline-grid;
787
786
  place-items: center;
788
787
  }
@@ -792,17 +791,11 @@
792
791
  * the two share one box and one centre; two ticks at twelve pixels were two
793
792
  * scratches.
794
793
  */
795
- [data-ui='message'][data-part='bubble']
796
- [data-part='meta']
797
- [data-part='receipt']
798
- > [data-ui='icon'] {
794
+ [data-ui-message][data-part-bubble] [data-part-meta] [data-part-receipt] > [data-ui-icon] {
799
795
  --slotted-icon-size: var(--slotted-control-icon-size-sm, 14px);
800
796
  }
801
797
 
802
- [data-ui='message'][data-part='bubble']
803
- [data-part='meta']
804
- [data-part='receipt']
805
- > span:not([data-ui]) {
798
+ [data-ui-message][data-part-bubble] [data-part-meta] [data-part-receipt] > span:not([data-ui]) {
806
799
  position: absolute;
807
800
  inline-size: 1px;
808
801
  block-size: 1px;
@@ -811,17 +804,15 @@
811
804
  white-space: nowrap;
812
805
  }
813
806
 
814
- [data-ui='message'][data-part='bubble']
815
- [data-part='meta']
816
- [data-part='receipt'][data-status='read'] {
807
+ [data-ui-message][data-part-bubble] [data-part-meta] [data-part-receipt][data-status='read'] {
817
808
  color: var(--_read-ink);
818
809
  }
819
810
 
820
811
  /** A clock that breathes while the message is on its way. */
821
- [data-ui='message'][data-part='bubble']
822
- [data-part='meta']
823
- [data-part='receipt'][data-status='sending']
824
- > [data-ui='icon'] {
812
+ [data-ui-message][data-part-bubble]
813
+ [data-part-meta]
814
+ [data-part-receipt][data-status='sending']
815
+ > [data-ui-icon] {
825
816
  animation: slotted-message-pending var(--slotted-duration-loop-slow)
826
817
  var(--slotted-easing-standard, ease) infinite alternate;
827
818
  }
@@ -837,7 +828,7 @@
837
828
  }
838
829
 
839
830
  /** The meta of an unframed reply has no surface to ride in; it is the footer's. */
840
- [data-ui='message'][data-part='bubble'][data-variant='plain'] [data-part='meta'] {
831
+ [data-ui-message][data-part-bubble][data-variant='plain'] [data-part-meta] {
841
832
  display: none;
842
833
  }
843
834
 
@@ -853,8 +844,7 @@
853
844
  * text jump twice when a reply streaming above it reflows the column. The
854
845
  * chevron turning is the motion that answers the press.
855
846
  */
856
- [data-ui='message'][data-part='bubble'][data-clamped]:not([data-revealed])
857
- > [data-part='content'] {
847
+ [data-ui-message][data-part-bubble][data-clamped]:not([data-revealed]) > [data-part-content] {
858
848
  display: -webkit-box;
859
849
  -webkit-box-orient: vertical;
860
850
  -webkit-line-clamp: var(--slotted-message-max-lines, 6);
@@ -868,7 +858,7 @@
868
858
  overflow-clip-margin: content-box;
869
859
  }
870
860
 
871
- [data-ui='message'][data-part='bubble'] > [data-part='more'] {
861
+ [data-ui-message][data-part-bubble] > [data-part-more] {
872
862
  display: inline-flex;
873
863
  align-items: center;
874
864
  gap: var(--slotted-space-1, 0.125rem);
@@ -886,25 +876,25 @@
886
876
  transition: color var(--slotted-duration-short) var(--slotted-easing-standard, ease);
887
877
  }
888
878
 
889
- [data-ui='message'][data-part='bubble'] > [data-part='more'] > [data-ui='icon'] {
879
+ [data-ui-message][data-part-bubble] > [data-part-more] > [data-ui-icon] {
890
880
  --slotted-icon-size: var(--slotted-control-icon-size-sm, 14px);
891
881
 
892
882
  transition: rotate var(--slotted-duration-medium) var(--slotted-easing-standard, ease);
893
883
  }
894
884
 
895
- [data-ui='message'][data-part='bubble'][data-revealed] > [data-part='more'] > [data-ui='icon'] {
885
+ [data-ui-message][data-part-bubble][data-revealed] > [data-part-more] > [data-ui-icon] {
896
886
  rotate: 180deg;
897
887
  }
898
888
 
899
- [data-ui='message'][data-part='bubble'] > [data-part='more']:hover:not(:disabled) {
889
+ [data-ui-message][data-part-bubble] > [data-part-more]:hover:not(:disabled) {
900
890
  color: var(--slotted-text);
901
891
  }
902
892
 
903
- [data-ui='message'][data-part='bubble'] > [data-part='more']:active:not(:disabled) {
893
+ [data-ui-message][data-part-bubble] > [data-part-more]:active:not(:disabled) {
904
894
  color: var(--slotted-tone-accent-text);
905
895
  }
906
896
 
907
- [data-ui='message'][data-part='bubble'] > [data-part='more']:focus-visible {
897
+ [data-ui-message][data-part-bubble] > [data-part-more]:focus-visible {
908
898
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color);
909
899
  outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
910
900
  }
@@ -917,7 +907,7 @@
917
907
  * the accent fill included, where a rail in the ink would be the only
918
908
  * saturated stroke in the thread.
919
909
  */
920
- [data-ui='message'][data-part='bubble'] [data-part='quote'] {
910
+ [data-ui-message][data-part-bubble] [data-part-quote] {
921
911
  display: block;
922
912
  box-sizing: border-box;
923
913
  inline-size: 100%;
@@ -940,25 +930,25 @@
940
930
  -webkit-line-clamp: 3;
941
931
  }
942
932
 
943
- [data-ui='message'][data-part='bubble'] [data-part='quote-author'] {
933
+ [data-ui-message][data-part-bubble] [data-part-quote-author] {
944
934
  display: block;
945
935
  font-weight: var(--slotted-font-weight-semibold, 600);
946
936
  }
947
937
 
948
- [data-ui='message'][data-part='bubble'] button[data-part='quote'] {
938
+ [data-ui-message][data-part-bubble] button[data-part-quote] {
949
939
  cursor: pointer;
950
940
  transition: background-color var(--slotted-duration-short) var(--slotted-easing-standard, ease);
951
941
  }
952
942
 
953
- [data-ui='message'][data-part='bubble'] button[data-part='quote']:hover:not(:disabled) {
943
+ [data-ui-message][data-part-bubble] button[data-part-quote]:hover:not(:disabled) {
954
944
  background-color: color-mix(in oklab, currentColor 13%, transparent);
955
945
  }
956
946
 
957
- [data-ui='message'][data-part='bubble'] button[data-part='quote']:active:not(:disabled) {
947
+ [data-ui-message][data-part-bubble] button[data-part-quote]:active:not(:disabled) {
958
948
  background-color: color-mix(in oklab, currentColor 18%, transparent);
959
949
  }
960
950
 
961
- [data-ui='message'][data-part='bubble'] button[data-part='quote']:focus-visible {
951
+ [data-ui-message][data-part-bubble] button[data-part-quote]:focus-visible {
962
952
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color);
963
953
  outline-offset: var(--slotted-focus-ring-offset, 2px);
964
954
  }
@@ -986,11 +976,11 @@
986
976
  * stands lit and the typing dots stand at three strengths, so the state is
987
977
  * still drawn.
988
978
  */
989
- [data-ui='message'][data-part='bubble'] [data-part='stream'] {
979
+ [data-ui-message][data-part-bubble] [data-part-stream] {
990
980
  white-space: pre-wrap;
991
981
  }
992
982
 
993
- [data-ui='message'][data-part='bubble'] [data-part='stream-chunk'] {
983
+ [data-ui-message][data-part-bubble] [data-part-stream-chunk] {
994
984
  animation: slotted-message-word var(--slotted-duration-long) var(--slotted-easing-standard) both;
995
985
  }
996
986
 
@@ -1006,7 +996,7 @@
1006
996
  }
1007
997
  }
1008
998
 
1009
- [data-ui='message'][data-part='bubble'] [data-part='caret'] {
999
+ [data-ui-message][data-part-bubble] [data-part-caret] {
1010
1000
  --_dot: round(nearest, 0.6em, 2px);
1011
1001
 
1012
1002
  display: inline-block;
@@ -1026,9 +1016,9 @@
1026
1016
  }
1027
1017
 
1028
1018
  /* `filter`, not `opacity`: the breath animates opacity, and an animation outranks the rule. */
1029
- [data-ui='message'][data-part='bubble']
1030
- [data-part='stream']:has(> [data-part='stream-chunk'])
1031
- + [data-part='caret'] {
1019
+ [data-ui-message][data-part-bubble]
1020
+ [data-part-stream]:has(> [data-part-stream-chunk])
1021
+ + [data-part-caret] {
1032
1022
  filter: opacity(0);
1033
1023
  transition: filter var(--slotted-duration-short) var(--slotted-easing-exit);
1034
1024
  }
@@ -1059,7 +1049,7 @@
1059
1049
  * before, in the bubble of the person writing. The wave travels half a dot:
1060
1050
  * enough to read as a voice, not so much that the bubble seems to bounce.
1061
1051
  */
1062
- [data-ui='message'][data-part='bubble'] [data-part='typing'] {
1052
+ [data-ui-message][data-part-bubble] [data-part-typing] {
1063
1053
  --_dot: round(calc(var(--_leading) / 3), 1px);
1064
1054
 
1065
1055
  display: inline-flex;
@@ -1077,7 +1067,7 @@
1077
1067
  * behind. The circles are the surface's own fill and edge, so they answer
1078
1068
  * every painting and every scheme with the bubble.
1079
1069
  */
1080
- [data-ui='message'][data-part='bubble'] > [data-part='content']:has(> [data-part='typing']) {
1070
+ [data-ui-message][data-part-bubble] > [data-part-content]:has(> [data-part-typing]) {
1081
1071
  position: relative;
1082
1072
  padding-inline: calc(var(--_pad-inline) + var(--slotted-space-1, 0.125rem));
1083
1073
  transition:
@@ -1090,10 +1080,8 @@
1090
1080
  }
1091
1081
  }
1092
1082
 
1093
- [data-ui='message'][data-part='bubble']
1094
- > [data-part='content']:has(> [data-part='typing'])::before,
1095
- [data-ui='message'][data-part='bubble']
1096
- > [data-part='content']:has(> [data-part='typing'])::after {
1083
+ [data-ui-message][data-part-bubble] > [data-part-content]:has(> [data-part-typing])::before,
1084
+ [data-ui-message][data-part-bubble] > [data-part-content]:has(> [data-part-typing])::after {
1097
1085
  content: '';
1098
1086
  position: absolute;
1099
1087
  box-sizing: border-box;
@@ -1104,16 +1092,14 @@
1104
1092
  var(--slotted-easing-standard, ease) infinite alternate;
1105
1093
  }
1106
1094
 
1107
- [data-ui='message'][data-part='bubble']
1108
- > [data-part='content']:has(> [data-part='typing'])::before {
1095
+ [data-ui-message][data-part-bubble] > [data-part-content]:has(> [data-part-typing])::before {
1109
1096
  inset-block-end: calc(var(--slotted-space-1, 0.125rem) * -1);
1110
1097
  inset-inline-start: calc(var(--slotted-space-1, 0.125rem) * -1);
1111
1098
  inline-size: var(--slotted-space-4, 0.5rem);
1112
1099
  block-size: var(--slotted-space-4, 0.5rem);
1113
1100
  }
1114
1101
 
1115
- [data-ui='message'][data-part='bubble']
1116
- > [data-part='content']:has(> [data-part='typing'])::after {
1102
+ [data-ui-message][data-part-bubble] > [data-part-content]:has(> [data-part-typing])::after {
1117
1103
  inset-block-end: calc(var(--slotted-space-3, 0.375rem) * -1);
1118
1104
  inset-inline-start: calc(var(--slotted-space-3, 0.375rem) * -1);
1119
1105
  inline-size: var(--slotted-space-2, 0.25rem);
@@ -1122,9 +1108,9 @@
1122
1108
  }
1123
1109
 
1124
1110
  /** The line under a writing bubble clears the trail. */
1125
- [data-ui='message'][data-part='root']
1126
- > [data-part='body']:has(> [data-part='bubble'] [data-part='typing'])
1127
- > [data-part='footer'] {
1111
+ [data-ui-message][data-part-root]
1112
+ > [data-part-body]:has(> [data-part-bubble] [data-part-typing])
1113
+ > [data-part-footer] {
1128
1114
  margin-block-start: var(--slotted-space-2, 0.25rem);
1129
1115
  }
1130
1116
 
@@ -1138,7 +1124,7 @@
1138
1124
  }
1139
1125
  }
1140
1126
 
1141
- [data-ui='message'][data-part='bubble'] [data-part='typing'] > span {
1127
+ [data-ui-message][data-part-bubble] [data-part-typing] > span {
1142
1128
  inline-size: var(--_dot);
1143
1129
  block-size: var(--_dot);
1144
1130
  border-radius: var(--slotted-radius-full, 9999px);
@@ -1148,11 +1134,11 @@
1148
1134
  var(--slotted-easing-standard, ease) infinite;
1149
1135
  }
1150
1136
 
1151
- [data-ui='message'][data-part='bubble'] [data-part='typing'] > span:nth-child(2) {
1137
+ [data-ui-message][data-part-bubble] [data-part-typing] > span:nth-child(2) {
1152
1138
  animation-delay: calc(var(--slotted-duration-loop) / 6);
1153
1139
  }
1154
1140
 
1155
- [data-ui='message'][data-part='bubble'] [data-part='typing'] > span:nth-child(3) {
1141
+ [data-ui-message][data-part-bubble] [data-part-typing] > span:nth-child(3) {
1156
1142
  animation-delay: calc(var(--slotted-duration-loop) / 3);
1157
1143
  }
1158
1144
 
@@ -1178,7 +1164,7 @@
1178
1164
  * line. It is the way to send it again, and its arrow turns a little under
1179
1165
  * the pointer toward the way it will go.
1180
1166
  */
1181
- [data-ui='message'][data-part='bubble'] > [data-part='retry'] {
1167
+ [data-ui-message][data-part-bubble] > [data-part-retry] {
1182
1168
  --_size: max(var(--slotted-target-min, 24px), var(--slotted-control-inner-size-md, 24px));
1183
1169
  --_ground: var(--slotted-tone-danger-solid);
1184
1170
 
@@ -1206,13 +1192,11 @@
1206
1192
  transition: background-color var(--slotted-duration-short) var(--slotted-easing-standard, ease);
1207
1193
  }
1208
1194
 
1209
- [data-ui='message'][data-part='root'][data-align='end']
1210
- [data-part='bubble']
1211
- > [data-part='retry'] {
1195
+ [data-ui-message][data-part-root][data-align='end'] [data-part-bubble] > [data-part-retry] {
1212
1196
  inset-inline: auto calc(100% + var(--slotted-space-4, 0.5rem));
1213
1197
  }
1214
1198
 
1215
- [data-ui='message'][data-part='bubble'] > [data-part='retry'] > [data-ui='icon'] {
1199
+ [data-ui-message][data-part-bubble] > [data-part-retry] > [data-ui-icon] {
1216
1200
  --slotted-icon-size: var(--slotted-control-icon-size-sm, 14px);
1217
1201
 
1218
1202
  transition: rotate var(--slotted-duration-medium) var(--slotted-easing-emphasized, ease);
@@ -1223,8 +1207,8 @@
1223
1207
  * the 0.02 `theme-conformance` asks; the control's ink laid over the fill at
1224
1208
  * fourteen per cent answers visibly in every scheme.
1225
1209
  */
1226
- [data-ui='message'][data-part='bubble']
1227
- > [data-part='retry']:hover:not(:disabled):not([data-disabled]) {
1210
+ [data-ui-message][data-part-bubble]
1211
+ > [data-part-retry]:hover:not(:disabled):not([data-disabled]) {
1228
1212
  background-color: color-mix(
1229
1213
  in oklab,
1230
1214
  var(--slotted-tone-danger-on-solid) var(--slotted-message-retry-state-layer, 14%),
@@ -1232,48 +1216,46 @@
1232
1216
  );
1233
1217
  }
1234
1218
 
1235
- [data-ui='message'][data-part='bubble']
1236
- > [data-part='retry']:hover:not(:disabled):not([data-disabled])
1237
- > [data-ui='icon'] {
1219
+ [data-ui-message][data-part-bubble]
1220
+ > [data-part-retry]:hover:not(:disabled):not([data-disabled])
1221
+ > [data-ui-icon] {
1238
1222
  rotate: -45deg;
1239
1223
  }
1240
1224
 
1241
- [data-ui='message'][data-part='bubble']
1242
- > [data-part='retry']:active:not(:disabled):not([data-disabled]) {
1225
+ [data-ui-message][data-part-bubble]
1226
+ > [data-part-retry]:active:not(:disabled):not([data-disabled]) {
1243
1227
  background-color: var(--slotted-tone-danger-solid-active);
1244
1228
  }
1245
1229
 
1246
- [data-ui='message'][data-part='bubble'] > [data-part='retry']:focus-visible {
1230
+ [data-ui-message][data-part-bubble] > [data-part-retry]:focus-visible {
1247
1231
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color);
1248
1232
  outline-offset: var(--slotted-focus-ring-offset, 2px);
1249
1233
  }
1250
1234
 
1251
1235
  @media (prefers-reduced-motion: reduce) {
1252
- [data-ui='message'][data-part='bubble'] [data-part='caret'],
1253
- [data-ui='message'][data-part='bubble'] [data-part='stream-chunk'],
1254
- [data-ui='message'][data-part='bubble'] [data-part='typing'] > span,
1255
- [data-ui='message'][data-part='bubble']
1256
- > [data-part='content']:has(> [data-part='typing'])::before,
1257
- [data-ui='message'][data-part='bubble']
1258
- > [data-part='content']:has(> [data-part='typing'])::after,
1259
- [data-ui='message'][data-part='bubble']
1260
- [data-part='meta']
1261
- [data-part='receipt'][data-status='sending']
1262
- > [data-ui='icon'] {
1236
+ [data-ui-message][data-part-bubble] [data-part-caret],
1237
+ [data-ui-message][data-part-bubble] [data-part-stream-chunk],
1238
+ [data-ui-message][data-part-bubble] [data-part-typing] > span,
1239
+ [data-ui-message][data-part-bubble] > [data-part-content]:has(> [data-part-typing])::before,
1240
+ [data-ui-message][data-part-bubble] > [data-part-content]:has(> [data-part-typing])::after,
1241
+ [data-ui-message][data-part-bubble]
1242
+ [data-part-meta]
1243
+ [data-part-receipt][data-status='sending']
1244
+ > [data-ui-icon] {
1263
1245
  animation: none;
1264
1246
  }
1265
1247
 
1266
- [data-ui='message'][data-part='root'] [data-part='activity-step'][data-current] > :last-child {
1248
+ [data-ui-message][data-part-root] [data-part-activity-step][data-current] > :last-child {
1267
1249
  animation: none;
1268
1250
  background-image: none;
1269
1251
  color: inherit;
1270
1252
  }
1271
1253
 
1272
- [data-ui='message'][data-part='bubble'] [data-part='typing'] > span:nth-child(2) {
1254
+ [data-ui-message][data-part-bubble] [data-part-typing] > span:nth-child(2) {
1273
1255
  opacity: 0.55;
1274
1256
  }
1275
1257
 
1276
- [data-ui='message'][data-part='bubble'] [data-part='typing'] > span:nth-child(3) {
1258
+ [data-ui-message][data-part-bubble] [data-part-typing] > span:nth-child(3) {
1277
1259
  opacity: 0.8;
1278
1260
  }
1279
1261
  }
@@ -1288,11 +1270,11 @@
1288
1270
  * it (`c-bubble-4`). The pill draws its own edge and lift rather than a
1289
1271
  * ring in the colour of a card it assumes it is on.
1290
1272
  */
1291
- [data-ui='message'][data-part='bubble']:has(> [data-part='reactions']) {
1273
+ [data-ui-message][data-part-bubble]:has(> [data-part-reactions]) {
1292
1274
  padding-block-end: calc(var(--_reactions-size) - var(--_pad-block, 8px) / 2);
1293
1275
  }
1294
1276
 
1295
- [data-ui='message'][data-part='bubble'] > [data-part='reactions'] {
1277
+ [data-ui-message][data-part-bubble] > [data-part-reactions] {
1296
1278
  display: inline-flex;
1297
1279
  align-items: center;
1298
1280
  gap: var(--slotted-space-1, 0.125rem);
@@ -1306,9 +1288,7 @@
1306
1288
  box-shadow: var(--slotted-shadow-xs);
1307
1289
  }
1308
1290
 
1309
- [data-ui='message'][data-part='root'][data-align='end']
1310
- [data-part='bubble']
1311
- > [data-part='reactions'] {
1291
+ [data-ui-message][data-part-root][data-align='end'] [data-part-bubble] > [data-part-reactions] {
1312
1292
  inset-inline: var(--_pad-inline, 12px) auto;
1313
1293
  }
1314
1294
 
@@ -1316,11 +1296,11 @@
1316
1296
  * In a thread there is no surface to straddle: the reactions are a row in
1317
1297
  * the flow under the words, the way Slack and GitHub set them.
1318
1298
  */
1319
- [data-ui='message'][data-part='bubble'][data-variant='plain']:has(> [data-part='reactions']) {
1299
+ [data-ui-message][data-part-bubble][data-variant='plain']:has(> [data-part-reactions]) {
1320
1300
  padding-block-end: 0;
1321
1301
  }
1322
1302
 
1323
- [data-ui='message'][data-part='bubble'][data-variant='plain'] > [data-part='reactions'] {
1303
+ [data-ui-message][data-part-bubble][data-variant='plain'] > [data-part-reactions] {
1324
1304
  position: static;
1325
1305
  padding: 0;
1326
1306
  border: 0;
@@ -1329,7 +1309,7 @@
1329
1309
  translate: none;
1330
1310
  }
1331
1311
 
1332
- [data-ui='message'][data-part='bubble'] [data-part='reaction'] {
1312
+ [data-ui-message][data-part-bubble] [data-part-reaction] {
1333
1313
  display: inline-flex;
1334
1314
  align-items: center;
1335
1315
  gap: var(--slotted-space-1, 0.125rem);
@@ -1354,13 +1334,13 @@
1354
1334
  color var(--slotted-duration-short) var(--slotted-easing-standard, ease);
1355
1335
  }
1356
1336
 
1357
- [data-ui='message'][data-part='bubble'][data-variant='plain'] [data-part='reaction'] {
1337
+ [data-ui-message][data-part-bubble][data-variant='plain'] [data-part-reaction] {
1358
1338
  --_reaction-ground: var(--slotted-surface);
1359
1339
 
1360
1340
  border-color: var(--slotted-border-subtle);
1361
1341
  }
1362
1342
 
1363
- [data-ui='message'][data-part='bubble'] [data-part='reaction-count'] {
1343
+ [data-ui-message][data-part-bubble] [data-part-reaction-count] {
1364
1344
  color: var(--slotted-text-muted);
1365
1345
  font-weight: var(--slotted-font-weight-medium, 500);
1366
1346
  font-variant-numeric: tabular-nums;
@@ -1372,8 +1352,8 @@
1372
1352
  * ink laid over it at six and twelve per cent, so a pressed reaction answers
1373
1353
  * a hover and a press as clearly as a bare one and the two never match.
1374
1354
  */
1375
- [data-ui='message'][data-part='bubble']
1376
- [data-part='reaction']:hover:not(:disabled):not([data-disabled]) {
1355
+ [data-ui-message][data-part-bubble]
1356
+ [data-part-reaction]:hover:not(:disabled):not([data-disabled]) {
1377
1357
  background-color: color-mix(
1378
1358
  in oklab,
1379
1359
  var(--slotted-text) var(--slotted-message-state-layer-hover, 6%),
@@ -1381,8 +1361,8 @@
1381
1361
  );
1382
1362
  }
1383
1363
 
1384
- [data-ui='message'][data-part='bubble']
1385
- [data-part='reaction']:active:not(:disabled):not([data-disabled]) {
1364
+ [data-ui-message][data-part-bubble]
1365
+ [data-part-reaction]:active:not(:disabled):not([data-disabled]) {
1386
1366
  background-color: color-mix(
1387
1367
  in oklab,
1388
1368
  var(--slotted-text) var(--slotted-message-state-layer-active, 12%),
@@ -1395,24 +1375,24 @@
1395
1375
  * edge, and the count in the accent's ink. The pair carries the ratio the
1396
1376
  * ground alone cannot (`docs/token-foundation.md` › Semantic colour).
1397
1377
  */
1398
- [data-ui='message'][data-part='bubble'] [data-part='reaction'][data-pressed] {
1378
+ [data-ui-message][data-part-bubble] [data-part-reaction][data-pressed] {
1399
1379
  --_reaction-ground: var(--slotted-tone-accent-surface);
1400
1380
 
1401
1381
  border-color: var(--slotted-tone-accent-border);
1402
1382
  }
1403
1383
 
1404
- [data-ui='message'][data-part='bubble']
1405
- [data-part='reaction'][data-pressed]
1406
- > [data-part='reaction-count'] {
1384
+ [data-ui-message][data-part-bubble]
1385
+ [data-part-reaction][data-pressed]
1386
+ > [data-part-reaction-count] {
1407
1387
  color: var(--slotted-tone-accent-text);
1408
1388
  }
1409
1389
 
1410
- [data-ui='message'][data-part='bubble'] [data-part='reaction']:is(:disabled, [data-disabled]) {
1390
+ [data-ui-message][data-part-bubble] [data-part-reaction]:is(:disabled, [data-disabled]) {
1411
1391
  color: var(--slotted-disabled-foreground);
1412
1392
  cursor: default;
1413
1393
  }
1414
1394
 
1415
- [data-ui='message'][data-part='bubble'] [data-part='reaction']:focus-visible {
1395
+ [data-ui-message][data-part-bubble] [data-part-reaction]:focus-visible {
1416
1396
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color);
1417
1397
  outline-offset: var(--slotted-focus-ring-offset, 2px);
1418
1398
  }
@@ -1425,28 +1405,28 @@
1425
1405
  * reader chose.
1426
1406
  */
1427
1407
  @media (forced-colors: active) {
1428
- [data-ui='message'][data-part='bubble'] > [data-part='content'] {
1408
+ [data-ui-message][data-part-bubble] > [data-part-content] {
1429
1409
  border-color: CanvasText;
1430
1410
  }
1431
1411
 
1432
1412
  /* A background is the system's to repaint; the dot is ink, so it keeps the text's colour. */
1433
- [data-ui='message'][data-part='bubble'] [data-part='caret'] {
1413
+ [data-ui-message][data-part-bubble] [data-part-caret] {
1434
1414
  forced-color-adjust: none;
1435
1415
  background-color: CanvasText;
1436
1416
  }
1437
1417
 
1438
- [data-ui='message'][data-part='bubble'][data-variant='plain'] > [data-part='content'] {
1418
+ [data-ui-message][data-part-bubble][data-variant='plain'] > [data-part-content] {
1439
1419
  border-color: transparent;
1440
1420
  }
1441
1421
 
1442
- [data-ui='message'][data-part='bubble'] [data-part='reaction'][data-pressed] {
1422
+ [data-ui-message][data-part-bubble] [data-part-reaction][data-pressed] {
1443
1423
  border-color: Highlight;
1444
1424
  forced-color-adjust: none;
1445
1425
  background-color: Highlight;
1446
1426
  color: HighlightText;
1447
1427
  }
1448
1428
 
1449
- [data-ui='message'][data-part='bubble'] [data-part='quote'] {
1429
+ [data-ui-message][data-part-bubble] [data-part-quote] {
1450
1430
  border: var(--slotted-border-width-thin, 1px) solid CanvasText;
1451
1431
  }
1452
1432
  }