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

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 (180) hide show
  1. package/package.json +1 -1
  2. package/src/accordion/accordion.css +10 -10
  3. package/src/action-bar/action-bar.css +35 -42
  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 +149 -68
  17. package/src/button/button.tokens.json +10 -0
  18. package/src/button-group/button-group.css +79 -74
  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 +103 -90
  36. package/src/command-palette/command-palette.tokens.json +1 -0
  37. package/src/container/container.css +24 -24
  38. package/src/context-menu/context-menu.css +8 -8
  39. package/src/currency-field/currency-field.css +210 -88
  40. package/src/currency-field/currency-field.tokens.json +13 -0
  41. package/src/dashboard-grid/dashboard-grid.css +148 -116
  42. package/src/data-grid/data-grid.css +535 -470
  43. package/src/data-grid/data-grid.tokens.json +4 -0
  44. package/src/data-list/data-list.css +81 -70
  45. package/src/data-list/data-list.tokens.json +2 -1
  46. package/src/date-field/date-field.css +55 -52
  47. package/src/date-field/date-field.tokens.json +1 -0
  48. package/src/date-picker/date-picker.css +40 -42
  49. package/src/date-range-picker/date-range-picker.css +114 -118
  50. package/src/datetime-field/datetime-field.css +78 -80
  51. package/src/datetime-field/datetime-field.tokens.json +1 -0
  52. package/src/datetime-picker/datetime-picker.css +61 -63
  53. package/src/datetime-range-picker/datetime-range-picker.css +149 -156
  54. package/src/description-list/description-list.css +61 -64
  55. package/src/detail-panel/detail-panel.css +86 -71
  56. package/src/detail-panel/detail-panel.tokens.json +2 -0
  57. package/src/dialog/dialog.css +372 -153
  58. package/src/dialog/dialog.tokens.json +6 -0
  59. package/src/divider/divider.css +18 -18
  60. package/src/drawer/drawer.css +205 -210
  61. package/src/drawer/drawer.tokens.json +1 -0
  62. package/src/entity-picker/entity-picker.css +238 -241
  63. package/src/entity-picker/entity-picker.tokens.json +1 -0
  64. package/src/event-calendar/event-calendar.css +343 -385
  65. package/src/field/field.css +74 -78
  66. package/src/field-group/field-group.css +22 -25
  67. package/src/filter-bar/filter-bar.css +193 -209
  68. package/src/form/form.css +34 -24
  69. package/src/form/form.tokens.json +1 -0
  70. package/src/fullscreen/fullscreen.css +24 -25
  71. package/src/grid/grid.css +28 -28
  72. package/src/highlight/highlight.css +6 -6
  73. package/src/hover-card/hover-card.css +6 -6
  74. package/src/icon/icon.css +19 -15
  75. package/src/icon/icon.tokens.json +1 -0
  76. package/src/image/image.css +39 -39
  77. package/src/import-export-center/import-export-center.css +135 -156
  78. package/src/inline/inline.css +27 -27
  79. package/src/inline-message/inline-message.css +52 -28
  80. package/src/inline-message/inline-message.tokens.json +4 -0
  81. package/src/kbd/kbd.css +30 -26
  82. package/src/link/link.css +15 -15
  83. package/src/list/list.css +44 -17
  84. package/src/list/list.tokens.json +4 -0
  85. package/src/list-item/list-item.css +80 -66
  86. package/src/list-item/list-item.tokens.json +7 -0
  87. package/src/listbox/listbox.css +56 -59
  88. package/src/loading-overlay/loading-overlay.css +75 -92
  89. package/src/markdown/markdown.css +17 -17
  90. package/src/menu/menu.css +83 -63
  91. package/src/menubar/menubar.css +13 -13
  92. package/src/message/message.css +182 -202
  93. package/src/message/message.tokens.json +5 -0
  94. package/src/message-scroller/message-scroller.css +41 -42
  95. package/src/multi-select/multi-select.css +152 -145
  96. package/src/multi-select/multi-select.tokens.json +1 -0
  97. package/src/navigation-menu/navigation-menu.css +167 -188
  98. package/src/notification-center/notification-center.css +140 -148
  99. package/src/notification-center/notification-center.tokens.json +3 -0
  100. package/src/number-field/number-field.css +84 -83
  101. package/src/number-field/number-field.tokens.json +1 -0
  102. package/src/otp-input/otp-input.css +67 -57
  103. package/src/otp-input/otp-input.tokens.json +1 -0
  104. package/src/page/page.css +39 -23
  105. package/src/page/page.tokens.json +1 -0
  106. package/src/page-header/page-header.css +323 -283
  107. package/src/page-header/page-header.tokens.json +5 -0
  108. package/src/pagination/pagination.css +68 -72
  109. package/src/popover/popover.css +40 -49
  110. package/src/progress-indicator/progress-indicator.css +177 -120
  111. package/src/progress-indicator/progress-indicator.tokens.json +1 -1
  112. package/src/prompt-composer/prompt-composer.css +221 -102
  113. package/src/prompt-composer/prompt-composer.tokens.json +15 -0
  114. package/src/prose/prose.css +71 -75
  115. package/src/radio-group/radio-group.css +98 -103
  116. package/src/rating/rating.css +136 -132
  117. package/src/rating/rating.tokens.json +1 -0
  118. package/src/result-state/result-state.css +74 -77
  119. package/src/runtime-properties.mjs +2 -0
  120. package/src/saved-views/saved-views.css +41 -47
  121. package/src/scroll-area/scroll-area.css +39 -32
  122. package/src/section/section.css +161 -41
  123. package/src/section/section.tokens.json +7 -2
  124. package/src/segmented-control/segmented-control.css +254 -97
  125. package/src/segmented-control/segmented-control.tokens.json +15 -11
  126. package/src/select/select.css +118 -117
  127. package/src/select/select.tokens.json +1 -0
  128. package/src/side-navigation/side-navigation.css +179 -182
  129. package/src/side-navigation/side-navigation.tokens.json +1 -0
  130. package/src/skeleton/skeleton.css +47 -48
  131. package/src/slider/slider.css +86 -88
  132. package/src/sparkline/sparkline.css +62 -40
  133. package/src/sparkline/sparkline.tokens.json +2 -0
  134. package/src/spinner/spinner.css +83 -180
  135. package/src/spinner/spinner.tokens.json +0 -1
  136. package/src/split-button/split-button.css +30 -31
  137. package/src/split-button/split-button.tokens.json +1 -0
  138. package/src/splitter/splitter.css +35 -35
  139. package/src/stack/stack.css +24 -24
  140. package/src/stat-card/stat-card.css +341 -224
  141. package/src/stat-card/stat-card.tokens.json +3 -0
  142. package/src/status-indicator/status-indicator.css +28 -28
  143. package/src/stepper/stepper.css +58 -62
  144. package/src/switch/switch.css +86 -92
  145. package/src/table/table.css +310 -165
  146. package/src/table/table.tokens.json +6 -0
  147. package/src/table-of-contents/table-of-contents.css +51 -54
  148. package/src/tabs/tabs.css +337 -302
  149. package/src/tabs/tabs.tokens.json +8 -5
  150. package/src/tag/tag.css +79 -71
  151. package/src/tag/tag.tokens.json +9 -0
  152. package/src/tags-input/tags-input.css +145 -82
  153. package/src/tags-input/tags-input.tokens.json +7 -1
  154. package/src/text-field/text-field.css +132 -136
  155. package/src/text-field/text-field.tokens.json +1 -0
  156. package/src/textarea/textarea.css +31 -28
  157. package/src/textarea/textarea.tokens.json +1 -0
  158. package/src/time-field/time-field.css +72 -69
  159. package/src/time-field/time-field.tokens.json +1 -0
  160. package/src/time-picker/time-picker.css +56 -58
  161. package/src/time-range-picker/time-range-picker.css +126 -133
  162. package/src/timeline/timeline.css +254 -266
  163. package/src/timeline/timeline.tokens.json +5 -0
  164. package/src/toast/toast.css +108 -90
  165. package/src/toast/toast.tokens.json +6 -0
  166. package/src/toggle/toggle.css +62 -25
  167. package/src/toggle/toggle.tokens.json +8 -0
  168. package/src/toggle-group/toggle-group.css +106 -60
  169. package/src/toggle-group/toggle-group.tokens.json +10 -0
  170. package/src/toolbar/toolbar.css +30 -35
  171. package/src/tooltip/tooltip.css +26 -26
  172. package/src/top-navigation/top-navigation.css +243 -259
  173. package/src/tour/tour.css +51 -60
  174. package/src/transfer/transfer.css +160 -164
  175. package/src/tree/tree.css +103 -111
  176. package/src/typography/typography.css +40 -36
  177. package/src/typography/typography.tokens.json +1 -0
  178. package/src/upload/upload.css +224 -224
  179. package/src/visually-hidden/visually-hidden.css +1 -1
  180. package/src/wizard/wizard.css +185 -197
@@ -44,7 +44,7 @@
44
44
  * the two-line label clamp are `select`'s decisions, taken in an earlier
45
45
  * session. They are repeated here rather than shared because the three
46
46
  * families have three public identifiers, and a stylesheet that painted
47
- * `[data-ui='select']` from a multi-select would make one family's selector
47
+ * `[data-ui-select]` from a multi-select would make one family's selector
48
48
  * match another's DOM. The duplication is the price of that boundary.
49
49
  *
50
50
  * ── What this sheet decides on its own ───────────────────────────────
@@ -71,7 +71,7 @@
71
71
 
72
72
  /* ── The frame ────────────────────────────────────────────────────────── */
73
73
 
74
- [data-ui='multi-select'][data-part='root'] {
74
+ [data-ui-multi-select][data-part-root] {
75
75
  --_font-size: var(--slotted-control-font-size-md, 13px);
76
76
  --_height: var(--slotted-control-height-md, 34px);
77
77
  --_padding-inline: var(--slotted-control-padding-inline-md, 13px);
@@ -145,7 +145,7 @@
145
145
  box-shadow var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
146
146
  }
147
147
 
148
- [data-ui='multi-select'][data-part='root']:not([data-full-width]) {
148
+ [data-ui-multi-select][data-part-root]:not([data-full-width]) {
149
149
  inline-size: auto;
150
150
  }
151
151
 
@@ -154,7 +154,7 @@
154
154
  * role is what the layout-grid pattern asks for, and the geometry belongs to
155
155
  * the row that wraps.
156
156
  */
157
- [data-ui='multi-select'] > [data-part='control'] {
157
+ [data-ui-multi-select] > [data-part-control] {
158
158
  display: flex;
159
159
  flex: 1 1 auto;
160
160
  min-inline-size: 0;
@@ -171,7 +171,7 @@
171
171
  * acts on it was narrower than the rhythm inside it. Whichever part comes
172
172
  * first after the row takes the row's own gap.
173
173
  */
174
- [data-ui='multi-select'] > [data-part='control'] + * {
174
+ [data-ui-multi-select] > [data-part-control] + * {
175
175
  margin-inline-start: var(--_row-gap);
176
176
  }
177
177
 
@@ -180,7 +180,7 @@
180
180
  * which is what keeps `ArrowDown` and `ArrowUp` free for the popup: there is
181
181
  * no cell above or below any cell, so the grid answers neither key.
182
182
  */
183
- [data-ui='multi-select'] [data-part='chips'] {
183
+ [data-ui-multi-select] [data-part-chips] {
184
184
  /**
185
185
  * `safe`, because this box scrolls. Centring a scroll container's content
186
186
  * pushes the first line above the scrollport when there is more than fits,
@@ -240,7 +240,7 @@
240
240
  scrollbar-width: none;
241
241
  }
242
242
 
243
- [data-ui='multi-select'] [data-part='chips']::-webkit-scrollbar {
243
+ [data-ui-multi-select] [data-part-chips]::-webkit-scrollbar {
244
244
  display: none;
245
245
  }
246
246
 
@@ -250,7 +250,7 @@
250
250
  * collapsed by `createCollapse` into the counting chip below, and the whole
251
251
  * set is still reachable in the popup's `chosen` band.
252
252
  */
253
- [data-ui='multi-select'][data-overflow='collapse'] [data-part='chips'] {
253
+ [data-ui-multi-select][data-overflow='collapse'] [data-part-chips] {
254
254
  flex-wrap: nowrap;
255
255
  max-block-size: none;
256
256
  overflow: hidden;
@@ -267,7 +267,7 @@
267
267
  * not to this family, so it has no `data-part` of its own to be selected by,
268
268
  * and the query's own input is told apart by the part it does have.
269
269
  */
270
- [data-ui='multi-select'] [data-part='chips'] input:not([data-part='input']) {
270
+ [data-ui-multi-select] [data-part-chips] input:not([data-part-input]) {
271
271
  background-color: transparent;
272
272
  border: 0;
273
273
  color: inherit;
@@ -284,7 +284,7 @@
284
284
  * or goes to the next one; the only chip that gives way is one wider than the
285
285
  * whole row, which is capped here and truncated by `tag.css`.
286
286
  */
287
- [data-ui='multi-select'] [data-part='chips'] > :not([data-part='field']) {
287
+ [data-ui-multi-select] [data-part-chips] > :not([data-part-field]) {
288
288
  flex: 0 0 auto;
289
289
  max-inline-size: 100%;
290
290
  /* The row's own height, so three chips plus their gaps divide the cap the
@@ -296,10 +296,10 @@
296
296
  /**
297
297
  * The chip takes the height the inside of this control has, through the
298
298
  * property `tag` reads for it. Set on the row, inherited by every chip, and
299
- * no rule of this sheet names `[data-ui='tag']`: the host stands beside the
299
+ * no rule of this sheet names `[data-ui-tag]`: the host stands beside the
300
300
  * tag sheet and never reaches into it.
301
301
  */
302
- [data-ui='multi-select'] [data-part='chips'] {
302
+ [data-ui-multi-select] [data-part-chips] {
303
303
  --slotted-control-inner-size: var(--_inner-size);
304
304
  }
305
305
 
@@ -313,7 +313,7 @@
313
313
  * of its own the moment two chips were in front of it, and a control 240
314
314
  * pixels wide holding two values then stood two rows tall with one row empty.
315
315
  */
316
- [data-ui='multi-select'] [data-part='field'] {
316
+ [data-ui-multi-select] [data-part-field] {
317
317
  align-items: center;
318
318
  display: flex;
319
319
  flex: 1 1 var(--slotted-multi-select-field-basis, 4rem);
@@ -326,7 +326,7 @@
326
326
  * everything that makes it a text control: the caret, the selection, IME
327
327
  * composition, autofill and every native attribute the consumer wrote.
328
328
  */
329
- [data-ui='multi-select'] [data-part='input'] {
329
+ [data-ui-multi-select] [data-part-input] {
330
330
  background-color: transparent;
331
331
  border: 0;
332
332
  color: inherit;
@@ -341,18 +341,28 @@
341
341
  text-overflow: ellipsis;
342
342
  }
343
343
 
344
- [data-ui='multi-select'] [data-part='input']::placeholder {
344
+ [data-ui-multi-select] [data-part-input]::placeholder {
345
345
  color: var(--slotted-multi-select-placeholder-color, var(--slotted-text-muted, GrayText));
346
346
  text-overflow: ellipsis;
347
347
  }
348
348
 
349
349
  /**
350
- * Autofill. Chrome paints its own ground over the control's, and a
351
- * hundred-pixel inset shadow is the only way to reach it. The signal is kept
352
- * rather than erased, in the accent surface the theme owns — the repair
353
- * `text-field` makes, for the same reason.
350
+ * Autofill. Chrome paints its own ground over the input, and a hundred-pixel
351
+ * inset shadow is the only way to reach it. The signal is kept rather than
352
+ * erased, in the accent surface the theme owns, and it is the whole
353
+ * control's: the frame takes the tint under its border and inside its
354
+ * corner, and the input repaints the browser's ground in the same colour.
355
+ * Painted on the input alone, the tint left the frame's padding, the slots
356
+ * and the buttons bare.
354
357
  */
355
- [data-ui='multi-select'] [data-part='input']:autofill {
358
+ [data-ui-multi-select][data-part-root]:has([data-part-input]:autofill) {
359
+ background-color: var(
360
+ --slotted-multi-select-autofill-background,
361
+ var(--slotted-tone-accent-surface)
362
+ );
363
+ }
364
+
365
+ [data-ui-multi-select] [data-part-input]:autofill {
356
366
  box-shadow: inset 0 0 0 100px
357
367
  var(--slotted-multi-select-autofill-background, var(--slotted-tone-accent-surface));
358
368
  -webkit-text-fill-color: var(--slotted-multi-select-color, var(--slotted-text, CanvasText));
@@ -376,7 +386,7 @@
376
386
  * its own inner ring two widths in to keep a sliver of ground outside it;
377
387
  * here that sliver would cost the text its leading.
378
388
  */
379
- [data-ui='multi-select'] [data-part='chips'] > :not([data-part='field']):focus-visible {
389
+ [data-ui-multi-select] [data-part-chips] > :not([data-part-field]):focus-visible {
380
390
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
381
391
  outline-offset: calc(-1 * var(--slotted-focus-ring-width, 2px));
382
392
  }
@@ -387,7 +397,7 @@
387
397
  * whose last one happens to be a count, and `createCollapse` measures it the
388
398
  * way it measures every other unit.
389
399
  */
390
- [data-ui='multi-select'] [data-part='chips'] > [data-count] {
400
+ [data-ui-multi-select] [data-part-chips] > [data-count] {
391
401
  flex: none;
392
402
  }
393
403
 
@@ -397,7 +407,7 @@
397
407
  * too narrow for a chip — because a counter with nothing to count against is
398
408
  * furniture.
399
409
  */
400
- [data-ui='multi-select'] > [data-part='counter'] {
410
+ [data-ui-multi-select] > [data-part-counter] {
401
411
  text-box: auto; /* refine the alignment */
402
412
  align-self: center;
403
413
  color: var(--slotted-multi-select-counter-color, var(--slotted-text-muted, GrayText));
@@ -426,25 +436,25 @@
426
436
  * uses for a chosen value. Not a warning tone: reaching the limit is the
427
437
  * reader arriving somewhere, not going wrong.
428
438
  */
429
- [data-ui='multi-select'][data-complete] > [data-part='counter'] {
439
+ [data-ui-multi-select][data-complete] > [data-part-counter] {
430
440
  color: var(--slotted-multi-select-counter-complete-color, var(--slotted-tone-accent-text));
431
441
  font-weight: var(--slotted-font-weight-medium, 500);
432
442
  }
433
443
 
434
444
  /* Too narrow for a chip: the count is the whole answer. */
435
- [data-ui='multi-select'][data-narrow] [data-part='chips'] > :not([data-part='field']) {
445
+ [data-ui-multi-select][data-narrow] [data-part-chips] > :not([data-part-field]) {
436
446
  display: none;
437
447
  }
438
448
 
439
449
  /* The row takes only the room the count and the buttons leave, so the count
440
450
  is what shortens when even that room runs out. */
441
- [data-ui='multi-select'][data-narrow] > [data-part='control'] {
451
+ [data-ui-multi-select][data-narrow] > [data-part-control] {
442
452
  flex-basis: 0;
443
453
  }
444
454
 
445
455
  /* ── The two buttons inside the frame ─────────────────────────────────── */
446
456
 
447
- [data-ui='multi-select'] > :is([data-part='clear'], [data-part='trigger']) {
457
+ [data-ui-multi-select] > :is([data-part-clear], [data-part-trigger]) {
448
458
  align-items: center;
449
459
  align-self: center;
450
460
  appearance: none;
@@ -476,7 +486,7 @@
476
486
  * control is 24 pixels tall — the WCAG 2.2 minimum — so nothing drawn inside
477
487
  * it can also be 24.
478
488
  */
479
- [data-ui='multi-select'] > :is([data-part='clear'], [data-part='trigger'])::after {
489
+ [data-ui-multi-select] > :is([data-part-clear], [data-part-trigger])::after {
480
490
  content: '';
481
491
  inset: min(0px, calc((100% - var(--slotted-target-min, 24px)) / 2));
482
492
  position: absolute;
@@ -487,23 +497,22 @@
487
497
  the hit area above grows to 44 pixels around them. Side by side, neither
488
498
  button reaches across the edge the two share. */
489
499
  @media (pointer: coarse) {
490
- [data-ui='multi-select'] > :is([data-part='clear'], [data-part='trigger'])::after {
500
+ [data-ui-multi-select] > :is([data-part-clear], [data-part-trigger])::after {
491
501
  inset: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
492
502
  }
493
503
 
494
- [data-ui='multi-select']
495
- > [data-part='clear']:has(+ [data-part='trigger']:not([hidden]))::after {
504
+ [data-ui-multi-select] > [data-part-clear]:has(+ [data-part-trigger]:not([hidden]))::after {
496
505
  inset-inline-end: 0;
497
506
  }
498
507
 
499
- [data-ui='multi-select'] > [data-part='clear']:not([hidden]) + [data-part='trigger']::after {
508
+ [data-ui-multi-select] > [data-part-clear]:not([hidden]) + [data-part-trigger]::after {
500
509
  inset-inline-start: 0;
501
510
  }
502
511
  }
503
512
 
504
513
  /* The cross and the chevron are `Glyph` elements the binding draws, sized
505
514
  here to the control's icon step. */
506
- [data-ui='multi-select'] > :is([data-part='clear'], [data-part='trigger']) {
515
+ [data-ui-multi-select] > :is([data-part-clear], [data-part-trigger]) {
507
516
  --slotted-icon-size: var(--_icon-size);
508
517
  }
509
518
 
@@ -512,7 +521,7 @@
512
521
  * button is what a reader presses and the arrow is what turns over. The
513
522
  * library's own `Glyph` in an `icon` box; a character is never an icon.
514
523
  */
515
- [data-ui='multi-select'] [data-part='arrow'] {
524
+ [data-ui-multi-select] [data-part-arrow] {
516
525
  align-items: center;
517
526
  block-size: var(--_icon-size);
518
527
  display: flex;
@@ -520,12 +529,12 @@
520
529
  justify-content: center;
521
530
  }
522
531
 
523
- [data-ui='multi-select'] [data-part='arrow'] > [data-ui='icon'] {
532
+ [data-ui-multi-select] [data-part-arrow] > [data-ui-icon] {
524
533
  transition: rotate var(--slotted-control-transition-duration)
525
534
  var(--slotted-control-transition-easing);
526
535
  }
527
536
 
528
- [data-ui='multi-select'][data-open] [data-part='arrow'] > [data-ui='icon'] {
537
+ [data-ui-multi-select][data-open] [data-part-arrow] > [data-ui-icon] {
529
538
  rotate: 180deg;
530
539
  }
531
540
 
@@ -536,7 +545,7 @@
536
545
  * onto anything yet — and the arc is the one `spinner/spinner.css` draws for
537
546
  * every family that waits.
538
547
  */
539
- [data-ui='multi-select'] [data-part='busy'] {
548
+ [data-ui-multi-select] [data-part-busy] {
540
549
  --slotted-spinner-size: var(--_icon-size);
541
550
 
542
551
  align-self: center;
@@ -546,7 +555,7 @@
546
555
 
547
556
  /* ── Size ─────────────────────────────────────────────────────────────── */
548
557
 
549
- [data-ui='multi-select'][data-part='root'][data-size='sm'] {
558
+ [data-ui-multi-select][data-part-root][data-size='sm'] {
550
559
  --_font-size: var(--slotted-control-font-size-sm, 12px);
551
560
  --_height: var(--slotted-control-height-sm, 30px);
552
561
  --_inner-size: var(--slotted-control-inner-size-sm, 22px);
@@ -555,7 +564,7 @@
555
564
  --_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-sm, 14px));
556
565
  }
557
566
 
558
- [data-ui='multi-select'][data-part='root'][data-size='md'] {
567
+ [data-ui-multi-select][data-part-root][data-size='md'] {
559
568
  --_font-size: var(--slotted-control-font-size-md, 13px);
560
569
  --_height: var(--slotted-control-height-md, 34px);
561
570
  --_padding-inline: var(--slotted-control-padding-inline-md, 13px);
@@ -564,7 +573,7 @@
564
573
  --_inner-size: var(--slotted-control-inner-size-md, 24px);
565
574
  }
566
575
 
567
- [data-ui='multi-select'][data-part='root'][data-size='lg'] {
576
+ [data-ui-multi-select][data-part-root][data-size='lg'] {
568
577
  --_font-size: var(--slotted-control-font-size-lg, 14px);
569
578
  --_height: var(--slotted-control-height-lg, 38px);
570
579
  --_inner-size: var(--slotted-control-inner-size-lg, 28px);
@@ -575,7 +584,7 @@
575
584
 
576
585
  /* ── Variant ──────────────────────────────────────────────────────────── */
577
586
 
578
- [data-ui='multi-select'][data-part='root'][data-variant='subtle'] {
587
+ [data-ui-multi-select][data-part-root][data-variant='subtle'] {
579
588
  background-color: var(
580
589
  --slotted-multi-select-subtle-background,
581
590
  var(--slotted-surface-sunken, Canvas)
@@ -589,7 +598,7 @@
589
598
  /* No edge, no lift, no ground and no corner of its own: the cell it sits in
590
599
  is the box, the row is the ground, a cell has no corner, and the resting
591
600
  shadow would draw the cell where there is none. */
592
- [data-ui='multi-select'][data-part='root'][data-variant='plain'] {
601
+ [data-ui-multi-select][data-part-root][data-variant='plain'] {
593
602
  background-color: transparent;
594
603
  border-color: transparent;
595
604
  border-radius: var(--slotted-radius-none, 0px);
@@ -597,31 +606,31 @@
597
606
  }
598
607
 
599
608
  @media (forced-colors: active) {
600
- [data-ui='multi-select'][data-part='root'][data-variant='plain'] {
609
+ [data-ui-multi-select][data-part-root][data-variant='plain'] {
601
610
  border-color: ButtonBorder;
602
611
  }
603
612
  }
604
613
 
605
614
  /* ── States on the control ────────────────────────────────────────────── */
606
615
 
607
- [data-ui='multi-select'][data-part='root']:hover:not([data-disabled]):not([data-readonly]):not(
616
+ [data-ui-multi-select][data-part-root]:hover:not([data-disabled]):not([data-readonly]):not(
608
617
  [data-invalid]
609
618
  ) {
610
619
  border-color: var(--slotted-multi-select-hover-border-color, var(--slotted-tone-accent-border));
611
620
  }
612
621
 
613
- [data-ui='multi-select'][data-part='root'][data-variant='subtle']:hover:not([data-disabled]):not(
622
+ [data-ui-multi-select][data-part-root][data-variant='subtle']:hover:not([data-disabled]):not(
614
623
  [data-readonly]
615
- ):not([data-invalid]) {
624
+ ):not([data-invalid]):not(:has([data-part-input]:autofill)) {
616
625
  background-color: var(
617
626
  --slotted-multi-select-subtle-hover-background,
618
627
  var(--slotted-tone-secondary-subtle-hover)
619
628
  );
620
629
  }
621
630
 
622
- [data-ui='multi-select'][data-part='root'][data-variant='plain']:hover:not([data-disabled]):not(
631
+ [data-ui-multi-select][data-part-root][data-variant='plain']:hover:not([data-disabled]):not(
623
632
  [data-readonly]
624
- ):not([data-invalid]) {
633
+ ):not([data-invalid]):not(:has([data-part-input]:autofill)) {
625
634
  background-color: var(
626
635
  --slotted-multi-select-plain-hover-background,
627
636
  var(--slotted-tone-secondary-subtle-hover)
@@ -637,14 +646,14 @@
637
646
  * script, after a key, and a browser does not always match `:focus-visible`
638
647
  * on an element script moved focus to.
639
648
  */
640
- [data-ui='multi-select'][data-part='root']:has([data-part='input']:focus-visible),
641
- [data-ui='multi-select'][data-part='root']:has(
642
- [data-part='chips'] > :not([data-part='field']):focus-visible
649
+ [data-ui-multi-select][data-part-root]:has([data-part-input]:focus-visible),
650
+ [data-ui-multi-select][data-part-root]:has(
651
+ [data-part-chips] > :not([data-part-field]):focus-visible
643
652
  ) {
644
653
  box-shadow: var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
645
654
  var(--slotted-focus-ring-color, Highlight);
646
655
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
647
- outline-offset: var(--slotted-focus-ring-offset, 2px);
656
+ outline-offset: var(--slotted-control-focus-ring-offset, var(--slotted-focus-ring-offset, 2px));
648
657
  }
649
658
 
650
659
  /**
@@ -654,11 +663,9 @@
654
663
  * shadow that appears only under focus is a cell that changes size when it
655
664
  * is used.
656
665
  */
657
- [data-ui='multi-select'][data-part='root'][data-variant='plain']:has(
658
- [data-part='input']:focus-visible
659
- ),
660
- [data-ui='multi-select'][data-part='root'][data-variant='plain']:has(
661
- [data-part='chips'] > :not([data-part='field']):focus-visible
666
+ [data-ui-multi-select][data-part-root][data-variant='plain']:has([data-part-input]:focus-visible),
667
+ [data-ui-multi-select][data-part-root][data-variant='plain']:has(
668
+ [data-part-chips] > :not([data-part-field]):focus-visible
662
669
  ) {
663
670
  box-shadow: none;
664
671
  outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
@@ -669,17 +676,17 @@
669
676
  * is two rings for one focus. The frame keeps its lift and gives up the
670
677
  * outline while the ring is inside it.
671
678
  */
672
- [data-ui='multi-select'][data-part='root']:has(
673
- [data-part='chips'] > :not([data-part='field']):focus-visible
679
+ [data-ui-multi-select][data-part-root]:has(
680
+ [data-part-chips] > :not([data-part-field]):focus-visible
674
681
  ) {
675
682
  outline: none;
676
683
  }
677
684
 
678
- [data-ui='multi-select'][data-part='root'][data-open]:not([data-disabled]) {
685
+ [data-ui-multi-select][data-part-root][data-open]:not([data-disabled]) {
679
686
  border-color: var(--slotted-multi-select-open-border-color, var(--slotted-tone-accent-border));
680
687
  }
681
688
 
682
- [data-ui='multi-select'][data-part='root'][data-invalid] {
689
+ [data-ui-multi-select][data-part-root][data-invalid] {
683
690
  --slotted-focus-ring-color: var(
684
691
  --slotted-multi-select-invalid-focus-ring-color,
685
692
  var(--slotted-focus-ring-color-invalid, Highlight)
@@ -707,9 +714,9 @@
707
714
  box-shadow: var(--_invalid-edge);
708
715
  }
709
716
 
710
- [data-ui='multi-select'][data-part='root'][data-invalid]:has([data-part='input']:focus-visible),
711
- [data-ui='multi-select'][data-part='root'][data-invalid]:has(
712
- [data-part='chips'] > :not([data-part='field']):focus-visible
717
+ [data-ui-multi-select][data-part-root][data-invalid]:has([data-part-input]:focus-visible),
718
+ [data-ui-multi-select][data-part-root][data-invalid]:has(
719
+ [data-part-chips] > :not([data-part-field]):focus-visible
713
720
  ) {
714
721
  box-shadow:
715
722
  var(--_invalid-edge),
@@ -717,11 +724,11 @@
717
724
  var(--slotted-focus-ring-color, Highlight);
718
725
  }
719
726
 
720
- [data-ui='multi-select'][data-part='root'][data-variant='plain'][data-invalid]:has(
721
- [data-part='input']:focus-visible
727
+ [data-ui-multi-select][data-part-root][data-variant='plain'][data-invalid]:has(
728
+ [data-part-input]:focus-visible
722
729
  ),
723
- [data-ui='multi-select'][data-part='root'][data-variant='plain'][data-invalid]:has(
724
- [data-part='chips'] > :not([data-part='field']):focus-visible
730
+ [data-ui-multi-select][data-part-root][data-variant='plain'][data-invalid]:has(
731
+ [data-part-chips] > :not([data-part-field]):focus-visible
725
732
  ) {
726
733
  /* The ring lies inside the box here, over the border and an edge as wide as
727
734
  it; the edge reaches past the ring. */
@@ -739,23 +746,24 @@
739
746
  * control draws its ring double, which a valid ring is not.
740
747
  */
741
748
  @media (forced-colors: active) {
742
- [data-ui='multi-select'][data-part='root'][data-invalid] {
749
+ [data-ui-multi-select][data-part-root][data-invalid] {
743
750
  outline: var(--_invalid-edge-width) solid CanvasText;
744
751
  outline-offset: calc(
745
752
  -1 * (var(--slotted-control-border-width, 1px) + var(--_invalid-edge-width))
746
753
  );
747
754
  }
748
755
 
749
- [data-ui='multi-select'][data-part='root'][data-invalid]:has(
750
- [data-part='input']:focus-visible
751
- ) {
756
+ [data-ui-multi-select][data-part-root][data-invalid]:has([data-part-input]:focus-visible) {
752
757
  outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
753
758
  var(--slotted-focus-ring-color, Highlight);
754
- outline-offset: var(--slotted-focus-ring-offset, 2px);
759
+ outline-offset: var(
760
+ --slotted-control-focus-ring-offset,
761
+ var(--slotted-focus-ring-offset, 2px)
762
+ );
755
763
  }
756
764
 
757
- [data-ui='multi-select'][data-part='root'][data-variant='plain'][data-invalid]:has(
758
- [data-part='input']:focus-visible
765
+ [data-ui-multi-select][data-part-root][data-variant='plain'][data-invalid]:has(
766
+ [data-part-input]:focus-visible
759
767
  ) {
760
768
  outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
761
769
  var(--slotted-focus-ring-color, Highlight);
@@ -764,11 +772,11 @@
764
772
  );
765
773
  }
766
774
 
767
- [data-ui='multi-select'][data-part='root'][data-invalid]:has(
768
- [data-part='chips'] > :not([data-part='field']):focus-visible
775
+ [data-ui-multi-select][data-part-root][data-invalid]:has(
776
+ [data-part-chips] > :not([data-part-field]):focus-visible
769
777
  ),
770
- [data-ui='multi-select'][data-part='root'][data-variant='plain'][data-invalid]:has(
771
- [data-part='chips'] > :not([data-part='field']):focus-visible
778
+ [data-ui-multi-select][data-part-root][data-variant='plain'][data-invalid]:has(
779
+ [data-part-chips] > :not([data-part-field]):focus-visible
772
780
  ) {
773
781
  outline: var(--_invalid-edge-width) solid CanvasText;
774
782
  outline-offset: calc(
@@ -783,14 +791,14 @@
783
791
  * the text half; the rest is the family's, because neither pattern has a
784
792
  * readonly for a combobox.
785
793
  */
786
- [data-ui='multi-select'][data-part='root'][data-readonly] {
794
+ [data-ui-multi-select][data-part-root][data-readonly] {
787
795
  background-color: var(
788
796
  --slotted-multi-select-readonly-background,
789
797
  var(--slotted-tone-secondary-subtle-hover)
790
798
  );
791
799
  }
792
800
 
793
- [data-ui='multi-select'][data-part='root'][data-readonly] [data-part='arrow'] {
801
+ [data-ui-multi-select][data-part-root][data-readonly] [data-part-arrow] {
794
802
  opacity: 0.5;
795
803
  }
796
804
 
@@ -799,8 +807,8 @@
799
807
  * because a disabled `fieldset` disables every control inside it and the
800
808
  * control has no way to say so.
801
809
  */
802
- [data-ui='multi-select'][data-part='root'][data-disabled],
803
- [data-ui='multi-select'][data-part='root']:has([data-part='input']:disabled) {
810
+ [data-ui-multi-select][data-part-root][data-disabled],
811
+ [data-ui-multi-select][data-part-root]:has([data-part-input]:disabled) {
804
812
  background-color: var(
805
813
  --slotted-multi-select-disabled-background,
806
814
  var(--slotted-disabled-background)
@@ -811,16 +819,16 @@
811
819
  cursor: not-allowed;
812
820
  }
813
821
 
814
- [data-ui='multi-select']
815
- > :is([data-part='clear'], [data-part='trigger']):hover:not(:disabled):not([data-disabled]) {
822
+ [data-ui-multi-select]
823
+ > :is([data-part-clear], [data-part-trigger]):hover:not(:disabled):not([data-disabled]) {
816
824
  background-color: var(
817
825
  --slotted-multi-select-action-hover-background,
818
826
  var(--slotted-tone-secondary-subtle-hover)
819
827
  );
820
828
  }
821
829
 
822
- [data-ui='multi-select']
823
- > :is([data-part='clear'], [data-part='trigger']):active:not(:disabled):not([data-disabled]) {
830
+ [data-ui-multi-select]
831
+ > :is([data-part-clear], [data-part-trigger]):active:not(:disabled):not([data-disabled]) {
824
832
  background-color: var(
825
833
  --slotted-multi-select-action-active-background,
826
834
  var(--slotted-tone-secondary-subtle-active)
@@ -833,14 +841,14 @@
833
841
  * and a ring around the whole frame would sit still while focus moved inside
834
842
  * it.
835
843
  */
836
- [data-ui='multi-select'] > :is([data-part='clear'], [data-part='trigger']):focus-visible {
844
+ [data-ui-multi-select] > :is([data-part-clear], [data-part-trigger]):focus-visible {
837
845
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
838
846
  outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
839
847
  }
840
848
 
841
849
  /* ── The layer ────────────────────────────────────────────────────────── */
842
850
 
843
- [data-ui='multi-select'][data-part='positioner'] {
851
+ [data-ui-multi-select][data-part-positioner] {
844
852
  --_surface: var(--slotted-multi-select-surface, var(--slotted-surface-raised, #ffffff));
845
853
  --_text: var(--slotted-multi-select-content-text, var(--slotted-text, #0f172a));
846
854
  --_muted: var(--slotted-multi-select-content-text-muted, var(--slotted-text-muted, #5b6b7f));
@@ -914,12 +922,12 @@
914
922
  translate var(--slotted-duration-short) var(--slotted-easing-exit);
915
923
  }
916
924
 
917
- [data-ui='multi-select'][data-part='positioner'][data-side='top'] {
925
+ [data-ui-multi-select][data-part-positioner][data-side='top'] {
918
926
  translate: 0 var(--_enter-distance);
919
927
  }
920
928
 
921
929
  /* A lateral side has no block direction to arrive from, so it only fades. */
922
- [data-ui='multi-select'][data-part='positioner']:is([data-side='left'], [data-side='right']) {
930
+ [data-ui-multi-select][data-part-positioner]:is([data-side='left'], [data-side='right']) {
923
931
  translate: 0 0;
924
932
  }
925
933
 
@@ -931,7 +939,7 @@
931
939
  * it had one. A keyframe states where it starts. The exit stays a transition:
932
940
  * it leaves from wherever the layer is, on the closed rule's durations.
933
941
  */
934
- [data-ui='multi-select'][data-part='positioner'][data-open] {
942
+ [data-ui-multi-select][data-part-positioner][data-open] {
935
943
  opacity: 1;
936
944
  translate: 0 0;
937
945
  transition: none;
@@ -942,16 +950,16 @@
942
950
  * with the side, and a layer written open in static markup — the harness, a
943
951
  * docs snippet — is simply there, and is photographed where it stands.
944
952
  */
945
- [data-ui='multi-select'][data-part='positioner'][data-open][data-positioned] {
953
+ [data-ui-multi-select][data-part-positioner][data-open][data-positioned] {
946
954
  animation: slotted-multi-select-enter-down var(--slotted-duration-medium)
947
955
  var(--slotted-easing-enter);
948
956
  }
949
957
 
950
- [data-ui='multi-select'][data-part='positioner'][data-open][data-positioned][data-side='top'] {
958
+ [data-ui-multi-select][data-part-positioner][data-open][data-positioned][data-side='top'] {
951
959
  animation-name: slotted-multi-select-enter-up;
952
960
  }
953
961
 
954
- [data-ui='multi-select'][data-part='positioner'][data-open][data-positioned]:is(
962
+ [data-ui-multi-select][data-part-positioner][data-open][data-positioned]:is(
955
963
  [data-side='left'],
956
964
  [data-side='right']
957
965
  ) {
@@ -980,37 +988,37 @@
980
988
 
981
989
  /* Stillness keeps the fade and drops the movement. */
982
990
  @media (prefers-reduced-motion: reduce) {
983
- [data-ui='multi-select'][data-part='positioner'],
984
- [data-ui='multi-select'][data-part='positioner'][data-side='top'],
985
- [data-ui='multi-select'][data-part='positioner'][data-side='left'],
986
- [data-ui='multi-select'][data-part='positioner'][data-side='right'] {
991
+ [data-ui-multi-select][data-part-positioner],
992
+ [data-ui-multi-select][data-part-positioner][data-side='top'],
993
+ [data-ui-multi-select][data-part-positioner][data-side='left'],
994
+ [data-ui-multi-select][data-part-positioner][data-side='right'] {
987
995
  translate: 0 0;
988
996
  transition: opacity var(--slotted-duration-short) var(--slotted-easing-exit);
989
997
  }
990
998
 
991
- [data-ui='multi-select'][data-part='positioner'][data-open][data-positioned],
992
- [data-ui='multi-select'][data-part='positioner'][data-open][data-positioned][data-side='top'],
993
- [data-ui='multi-select'][data-part='positioner'][data-open][data-positioned][data-side='left'],
994
- [data-ui='multi-select'][data-part='positioner'][data-open][data-positioned][data-side='right'] {
999
+ [data-ui-multi-select][data-part-positioner][data-open][data-positioned],
1000
+ [data-ui-multi-select][data-part-positioner][data-open][data-positioned][data-side='top'],
1001
+ [data-ui-multi-select][data-part-positioner][data-open][data-positioned][data-side='left'],
1002
+ [data-ui-multi-select][data-part-positioner][data-open][data-positioned][data-side='right'] {
995
1003
  animation-name: slotted-multi-select-fade;
996
1004
  }
997
1005
  }
998
1006
 
999
- [data-ui='multi-select'][data-part='positioner'][data-detached] {
1007
+ [data-ui-multi-select][data-part-positioner][data-detached] {
1000
1008
  visibility: hidden;
1001
1009
  }
1002
1010
 
1003
- [data-ui='multi-select'][data-part='positioner'][data-width='anchor'] {
1011
+ [data-ui-multi-select][data-part-positioner][data-width='anchor'] {
1004
1012
  inline-size: var(--slotted-positioner-anchor-width, auto);
1005
1013
  }
1006
1014
 
1007
- [data-ui='multi-select'][data-part='positioner'][data-width='content'] {
1015
+ [data-ui-multi-select][data-part-positioner][data-width='content'] {
1008
1016
  inline-size: max-content;
1009
1017
  max-inline-size: min(var(--_measure), var(--slotted-positioner-available-width, 100vw));
1010
1018
  min-inline-size: var(--slotted-positioner-anchor-width, auto);
1011
1019
  }
1012
1020
 
1013
- [data-ui='multi-select'][data-part='positioner'][data-size='sm'] {
1021
+ [data-ui-multi-select][data-part-positioner][data-size='sm'] {
1014
1022
  --_item-inset: var(--slotted-control-padding-inline-sm, 0.625rem);
1015
1023
  --_item-height: var(--slotted-control-height-sm, 30px);
1016
1024
  --_content-font-size: var(--slotted-control-font-size-sm, 12px);
@@ -1019,7 +1027,7 @@
1019
1027
  --_column-gap: var(--slotted-control-gap-sm, 0.375rem);
1020
1028
  }
1021
1029
 
1022
- [data-ui='multi-select'][data-part='positioner'][data-size='lg'] {
1030
+ [data-ui-multi-select][data-part-positioner][data-size='lg'] {
1023
1031
  --_item-inset: var(--slotted-control-padding-inline-lg, 1rem);
1024
1032
  --_item-height: var(--slotted-control-height-lg, 38px);
1025
1033
  --_content-font-size: var(--slotted-control-font-size-lg, 14px);
@@ -1030,7 +1038,7 @@
1030
1038
 
1031
1039
  /* ── The surface ──────────────────────────────────────────────────────── */
1032
1040
 
1033
- [data-ui='multi-select'] > [data-part='content'] {
1041
+ [data-ui-multi-select] > [data-part-content] {
1034
1042
  background: var(--_surface);
1035
1043
  border: var(--_border-width) solid var(--_border-color);
1036
1044
  border-radius: var(--_radius);
@@ -1057,7 +1065,7 @@
1057
1065
  * interaction — the highlight is `aria-activedescendant`, not focus — so a
1058
1066
  * ring here would draw a box around something nobody is operating.
1059
1067
  */
1060
- [data-ui='multi-select'] > [data-part='content']:focus-visible {
1068
+ [data-ui-multi-select] > [data-part-content]:focus-visible {
1061
1069
  outline: none;
1062
1070
  }
1063
1071
 
@@ -1073,7 +1081,7 @@
1073
1081
  * option's own row, which the list has open beside it, and the chips in the
1074
1082
  * control, which are focusable. `select` recorded the same decision.
1075
1083
  */
1076
- [data-ui='multi-select'] [data-part='chosen'] {
1084
+ [data-ui-multi-select] [data-part-chosen] {
1077
1085
  background: var(--_surface);
1078
1086
  border-block-end: var(--_border-width) solid var(--_border-color);
1079
1087
  box-sizing: border-box;
@@ -1102,7 +1110,7 @@
1102
1110
 
1103
1111
  /* ── Groups ───────────────────────────────────────────────────────────── */
1104
1112
 
1105
- [data-ui='multi-select'] [data-part='group'] {
1113
+ [data-ui-multi-select] [data-part-group] {
1106
1114
  display: grid;
1107
1115
  grid-column: 1 / -1;
1108
1116
  grid-template-columns: subgrid;
@@ -1116,12 +1124,12 @@
1116
1124
  * author rule wins over the user agent sheet. Without this the search
1117
1125
  * filtered nothing the reader could see.
1118
1126
  */
1119
- [data-ui='multi-select'] [data-part='item'][hidden],
1120
- [data-ui='multi-select'] [data-part='group'][hidden] {
1127
+ [data-ui-multi-select] [data-part-item][hidden],
1128
+ [data-ui-multi-select] [data-part-group][hidden] {
1121
1129
  display: none;
1122
1130
  }
1123
1131
 
1124
- [data-ui='multi-select'] [data-part='group-label'] {
1132
+ [data-ui-multi-select] [data-part-group-label] {
1125
1133
  color: var(--_muted);
1126
1134
  font-size: var(--_secondary-font-size);
1127
1135
  font-weight: var(--slotted-font-weight-semibold, 600);
@@ -1133,7 +1141,7 @@
1133
1141
 
1134
1142
  /* ── Options ──────────────────────────────────────────────────────────── */
1135
1143
 
1136
- [data-ui='multi-select'] [data-part='item'] {
1144
+ [data-ui-multi-select] [data-part-item] {
1137
1145
  align-content: center;
1138
1146
  border-radius: var(--_item-radius);
1139
1147
  box-sizing: border-box;
@@ -1157,7 +1165,7 @@
1157
1165
  var(--slotted-control-transition-easing, var(--slotted-easing-standard));
1158
1166
  }
1159
1167
 
1160
- [data-ui='multi-select'] [data-part='item'][data-current] {
1168
+ [data-ui-multi-select] [data-part-item][data-current] {
1161
1169
  background-color: var(--_highlight);
1162
1170
  /**
1163
1171
  * A ring as well as a ground. Nothing on this surface holds focus — DOM
@@ -1171,11 +1179,11 @@
1171
1179
  var(--slotted-multi-select-highlight-ring, var(--slotted-tone-accent-border));
1172
1180
  }
1173
1181
 
1174
- [data-ui='multi-select'] [data-part='item']:not([data-disabled]):active {
1182
+ [data-ui-multi-select] [data-part-item]:not([data-disabled]):active {
1175
1183
  background-color: var(--_highlight-active);
1176
1184
  }
1177
1185
 
1178
- [data-ui='multi-select'] [data-part='item'][data-selected] {
1186
+ [data-ui-multi-select] [data-part-item][data-selected] {
1179
1187
  color: var(--_selected-color);
1180
1188
  }
1181
1189
 
@@ -1188,22 +1196,21 @@
1188
1196
  * and ends. `select` and `combobox` answer the same way, and
1189
1197
  * `selection-block.test.mjs` holds all of them to it.
1190
1198
  */
1191
- [data-ui='multi-select'] [data-part='item'][data-selected] + [data-part='item'][data-selected] {
1199
+ [data-ui-multi-select] [data-part-item][data-selected] + [data-part-item][data-selected] {
1192
1200
  border-start-end-radius: 0;
1193
1201
  border-start-start-radius: 0;
1194
1202
  }
1195
1203
 
1196
- [data-ui='multi-select']
1197
- [data-part='item'][data-selected]:has(+ [data-part='item'][data-selected]) {
1204
+ [data-ui-multi-select] [data-part-item][data-selected]:has(+ [data-part-item][data-selected]) {
1198
1205
  border-end-end-radius: 0;
1199
1206
  border-end-start-radius: 0;
1200
1207
  }
1201
1208
 
1202
- [data-ui='multi-select'] [data-part='item'][data-selected] > [data-part='label'] {
1209
+ [data-ui-multi-select] [data-part-item][data-selected] > [data-part-label] {
1203
1210
  font-weight: var(--slotted-font-weight-medium, 500);
1204
1211
  }
1205
1212
 
1206
- [data-ui='multi-select'] [data-part='item'][data-disabled] {
1213
+ [data-ui-multi-select] [data-part-item][data-disabled] {
1207
1214
  color: var(--slotted-disabled-foreground, #64748b);
1208
1215
  cursor: not-allowed;
1209
1216
  }
@@ -1221,7 +1228,7 @@
1221
1228
  * the row cannot do is said by the ink and by the ring, which both step down
1222
1229
  * to the disabled pair.
1223
1230
  */
1224
- [data-ui='multi-select'] [data-part='item'][data-disabled][data-current] {
1231
+ [data-ui-multi-select] [data-part-item][data-disabled][data-current] {
1225
1232
  box-shadow: inset 0 0 0 var(--slotted-border-width-thin, 1px)
1226
1233
  var(--slotted-disabled-border, #cbd5e1);
1227
1234
  color: var(--slotted-disabled-foreground, #64748b);
@@ -1229,13 +1236,13 @@
1229
1236
 
1230
1237
  /* ── The cells ────────────────────────────────────────────────────────── */
1231
1238
 
1232
- [data-ui='multi-select'] [data-part='item'] > :is([data-part='indicator'], [data-part='icon']) {
1239
+ [data-ui-multi-select] [data-part-item] > :is([data-part-indicator], [data-part-icon]) {
1233
1240
  block-size: 1lh;
1234
1241
  }
1235
1242
 
1236
1243
  /* Column one holds content and paints none: a `Glyph` in an `Icon` box, or
1237
1244
  artwork of the consumer's own, centred and sized from the column. */
1238
- [data-ui='multi-select'] [data-part='item'] > [data-part='icon'] {
1245
+ [data-ui-multi-select] [data-part-item] > [data-part-icon] {
1239
1246
  --slotted-icon-size: var(--_content-icon-size);
1240
1247
 
1241
1248
  align-items: center;
@@ -1248,7 +1255,7 @@
1248
1255
  margin-inline-end: var(--_column-gap);
1249
1256
  }
1250
1257
 
1251
- [data-ui='multi-select'] [data-part='item'] > [data-part='label'] {
1258
+ [data-ui-multi-select] [data-part-item] > [data-part-label] {
1252
1259
  grid-column: 2;
1253
1260
  grid-row: 1;
1254
1261
  min-inline-size: 0;
@@ -1259,7 +1266,7 @@
1259
1266
  overflow-wrap: anywhere;
1260
1267
  }
1261
1268
 
1262
- [data-ui='multi-select'] [data-part='item'] > [data-part='description'] {
1269
+ [data-ui-multi-select] [data-part-item] > [data-part-description] {
1263
1270
  color: var(--_muted);
1264
1271
  font-size: var(--_secondary-font-size);
1265
1272
  grid-column: 2;
@@ -1269,12 +1276,12 @@
1269
1276
  overflow-wrap: anywhere;
1270
1277
  }
1271
1278
 
1272
- [data-ui='multi-select'] [data-part='item'][data-disabled] > [data-part='description'] {
1279
+ [data-ui-multi-select] [data-part-item][data-disabled] > [data-part-description] {
1273
1280
  color: inherit;
1274
1281
  }
1275
1282
 
1276
1283
  /* The tick is a `Glyph` the binding draws, at the content's icon step. */
1277
- [data-ui='multi-select'] [data-part='item'] > [data-part='indicator'] {
1284
+ [data-ui-multi-select] [data-part-item] > [data-part-indicator] {
1278
1285
  --slotted-icon-size: var(--_content-icon-size);
1279
1286
 
1280
1287
  align-items: center;
@@ -1289,7 +1296,7 @@
1289
1296
  transition: opacity var(--slotted-duration-short) var(--slotted-easing-standard);
1290
1297
  }
1291
1298
 
1292
- [data-ui='multi-select'] [data-part='item'][data-selected] > [data-part='indicator'] {
1299
+ [data-ui-multi-select] [data-part-item][data-selected] > [data-part-indicator] {
1293
1300
  opacity: 1;
1294
1301
  }
1295
1302
 
@@ -1299,7 +1306,7 @@
1299
1306
  * plus rather than the check: the check says "this is in the set" and nothing
1300
1307
  * is in the set yet. The binding draws the plus; the rule only shows it.
1301
1308
  */
1302
- [data-ui='multi-select'] [data-part='item'][data-create] > [data-part='indicator'] {
1309
+ [data-ui-multi-select] [data-part-item][data-create] > [data-part-indicator] {
1303
1310
  opacity: 1;
1304
1311
  }
1305
1312
 
@@ -1312,13 +1319,13 @@
1312
1319
  * Latin word between them. The repair `status`, `empty` and the counter all
1313
1320
  * make, for the same reason.
1314
1321
  */
1315
- [data-ui='multi-select'] [data-part='item'][data-create] > [data-part='label'] {
1322
+ [data-ui-multi-select] [data-part-item][data-create] > [data-part-label] {
1316
1323
  unicode-bidi: plaintext;
1317
1324
  }
1318
1325
 
1319
1326
  /* ── Separator, empty, status ─────────────────────────────────────────── */
1320
1327
 
1321
- [data-ui='multi-select'] [data-part='separator'] {
1328
+ [data-ui-multi-select] [data-part-separator] {
1322
1329
  background-color: var(--slotted-multi-select-separator-color, var(--_border-color));
1323
1330
  block-size: var(--_border-width);
1324
1331
  border: 0;
@@ -1332,7 +1339,7 @@
1332
1339
  * keep the surface's measure rather than collapsing, so nothing jumps when
1333
1340
  * the results land.
1334
1341
  */
1335
- [data-ui='multi-select'] :is([data-part='empty'], [data-part='status']) {
1342
+ [data-ui-multi-select] :is([data-part-empty], [data-part-status]) {
1336
1343
  color: var(--_muted);
1337
1344
  /* Its own bidi run, ordered by its own content: "3 results" is a European
1338
1345
  number, a neutral space and a Latin word, and in a right-to-left document
@@ -1368,7 +1375,7 @@
1368
1375
  * The status row is also the live region that announces the count, so it is
1369
1376
  * often present with nothing to draw. A row with no text takes no space.
1370
1377
  */
1371
- [data-ui='multi-select'] [data-part='status']:empty {
1378
+ [data-ui-multi-select] [data-part-status]:empty {
1372
1379
  display: none;
1373
1380
  }
1374
1381
 
@@ -1379,47 +1386,47 @@
1379
1386
  * bars are `skeleton/skeleton.css`'s, and they are hidden from assistive
1380
1387
  * technology because the `status` row beside them is the live region.
1381
1388
  */
1382
- [data-ui='multi-select'] [data-part='placeholder'] {
1389
+ [data-ui-multi-select] [data-part-placeholder] {
1383
1390
  display: grid;
1384
1391
  grid-column: 1 / -1;
1385
1392
  padding-block: var(--slotted-space-2, 0.25rem);
1386
1393
  padding-inline: var(--_item-inset);
1387
1394
  }
1388
1395
 
1389
- [data-ui='multi-select'] [data-part='placeholder'] > * {
1396
+ [data-ui-multi-select] [data-part-placeholder] > * {
1390
1397
  align-items: center;
1391
1398
  display: flex;
1392
1399
  min-block-size: var(--_item-height);
1393
1400
  }
1394
1401
 
1395
- [data-ui='multi-select'] [data-part='placeholder'] > [data-ui='skeleton'] {
1402
+ [data-ui-multi-select] [data-part-placeholder] > [data-ui-skeleton] {
1396
1403
  align-self: center;
1397
1404
  }
1398
1405
 
1399
1406
  /* Three ragged widths: three identical bars read as a table, and a list of
1400
1407
  labels is ragged. */
1401
- [data-ui='multi-select'] [data-part='placeholder'] > :nth-child(2) [data-ui='skeleton'] {
1408
+ [data-ui-multi-select] [data-part-placeholder] > :nth-child(2) [data-ui-skeleton] {
1402
1409
  inline-size: 78%;
1403
1410
  }
1404
1411
 
1405
- [data-ui='multi-select'] [data-part='placeholder'] > :nth-child(3) [data-ui='skeleton'] {
1412
+ [data-ui-multi-select] [data-part-placeholder] > :nth-child(3) [data-ui-skeleton] {
1406
1413
  inline-size: 56%;
1407
1414
  }
1408
1415
 
1409
- [data-ui='multi-select'] > [data-part='content'][data-loading] {
1416
+ [data-ui-multi-select] > [data-part-content][data-loading] {
1410
1417
  cursor: progress;
1411
1418
  }
1412
1419
 
1413
1420
  /* ── Forced colours ───────────────────────────────────────────────────── */
1414
1421
 
1415
1422
  @media (forced-colors: active) {
1416
- [data-ui='multi-select'] [data-part='item'][data-current] {
1423
+ [data-ui-multi-select] [data-part-item][data-current] {
1417
1424
  background-color: Highlight;
1418
1425
  color: HighlightText;
1419
1426
  forced-color-adjust: none;
1420
1427
  }
1421
1428
 
1422
- [data-ui='multi-select'] [data-part='item'][data-disabled][data-current] {
1429
+ [data-ui-multi-select] [data-part-item][data-disabled][data-current] {
1423
1430
  background-color: Highlight;
1424
1431
  color: GrayText;
1425
1432
  }