@slotted/styles 0.1.0-beta.0 → 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
@@ -16,7 +16,7 @@
16
16
  * mirrors its state onto the frame rather than styling through, so a control
17
17
  * used outside a field looks the same as one inside it.
18
18
  */
19
- [data-ui='number-field'][data-part='root'] {
19
+ [data-ui-number-field][data-part-root] {
20
20
  /**
21
21
  * Type, height, inline padding, gap and glyph size all come from the
22
22
  * control scales — the only ones the theme restates per density — so an
@@ -127,7 +127,7 @@
127
127
  * moves under the reader's eye, and no other family has a stronger claim on
128
128
  * the setting.
129
129
  */
130
- [data-ui='number-field'] > [data-part='input'] {
130
+ [data-ui-number-field] > [data-part-input] {
131
131
  background-color: transparent;
132
132
  /* The frame's border box, not its content box: on a coarse pointer the frame
133
133
  is the touch target's height and the control it holds is too. Stretched
@@ -176,11 +176,11 @@
176
176
  * "the document's start edge, whatever the run inside is doing", so the
177
177
  * alignment is named once, under a guard that is itself the direction.
178
178
  */
179
- [data-ui='number-field']:dir(rtl) > [data-part='input'] {
179
+ [data-ui-number-field]:dir(rtl) > [data-part-input] {
180
180
  text-align: right;
181
181
  }
182
182
 
183
- [data-ui='number-field'] > [data-part='input']::placeholder {
183
+ [data-ui-number-field] > [data-part-input]::placeholder {
184
184
  color: var(--slotted-number-field-placeholder-color, var(--slotted-text-muted, GrayText));
185
185
  text-overflow: ellipsis;
186
186
  }
@@ -191,7 +191,7 @@
191
191
  * control beside it. One library, one scale.
192
192
  */
193
193
 
194
- [data-ui='number-field'][data-part='root'][data-size='sm'] {
194
+ [data-ui-number-field][data-part-root][data-size='sm'] {
195
195
  --_font-size: var(--slotted-control-font-size-sm, 12px);
196
196
  --_height: var(--slotted-control-height-sm, 30px);
197
197
  --_padding-inline: var(--slotted-control-padding-inline-sm, 10px);
@@ -200,7 +200,7 @@
200
200
  --_inner-size: var(--slotted-control-inner-size-sm, 22px);
201
201
  }
202
202
 
203
- [data-ui='number-field'][data-part='root'][data-size='md'] {
203
+ [data-ui-number-field][data-part-root][data-size='md'] {
204
204
  --_font-size: var(--slotted-control-font-size-md, 13px);
205
205
  --_height: var(--slotted-control-height-md, 34px);
206
206
  --_padding-inline: var(--slotted-control-padding-inline-md, 13px);
@@ -209,7 +209,7 @@
209
209
  --_inner-size: var(--slotted-control-inner-size-md, 24px);
210
210
  }
211
211
 
212
- [data-ui='number-field'][data-part='root'][data-size='lg'] {
212
+ [data-ui-number-field][data-part-root][data-size='lg'] {
213
213
  --_font-size: var(--slotted-control-font-size-lg, 14px);
214
214
  --_height: var(--slotted-control-height-lg, 38px);
215
215
  --_padding-inline: var(--slotted-control-padding-inline-lg, 16px);
@@ -225,7 +225,7 @@
225
225
  * which is what a dense table needs.
226
226
  */
227
227
 
228
- [data-ui='number-field'][data-part='root'][data-variant='subtle'] {
228
+ [data-ui-number-field][data-part-root][data-variant='subtle'] {
229
229
  background-color: var(
230
230
  --slotted-number-field-subtle-background,
231
231
  var(--slotted-surface-sunken, Canvas)
@@ -239,7 +239,7 @@
239
239
  /* No edge, no lift, no ground and no corner of its own: the cell it sits in
240
240
  is the box, the row is the ground, a cell has no corner, and the resting
241
241
  shadow would draw the cell where there is none. */
242
- [data-ui='number-field'][data-part='root'][data-variant='plain'] {
242
+ [data-ui-number-field][data-part-root][data-variant='plain'] {
243
243
  background-color: transparent;
244
244
  border-color: transparent;
245
245
  border-radius: var(--slotted-radius-none, 0px);
@@ -252,7 +252,7 @@
252
252
  * its only edge exactly where an edge matters most.
253
253
  */
254
254
  @media (forced-colors: active) {
255
- [data-ui='number-field'][data-part='root'][data-variant='plain'] {
255
+ [data-ui-number-field][data-part-root][data-variant='plain'] {
256
256
  border-color: ButtonBorder;
257
257
  }
258
258
  }
@@ -263,8 +263,8 @@
263
263
  * inside the value — a currency, a percent sign, a unit — is `format`'s job
264
264
  * and arrives through `Intl` as part of the string the control holds.
265
265
  */
266
- [data-ui='number-field'] > [data-part='start'],
267
- [data-ui='number-field'] > [data-part='end'] {
266
+ [data-ui-number-field] > [data-part-start],
267
+ [data-ui-number-field] > [data-part-end] {
268
268
  align-items: center;
269
269
  color: var(--slotted-number-field-adornment-color, var(--slotted-text-muted, GrayText));
270
270
  display: inline-flex;
@@ -282,8 +282,8 @@
282
282
  --slotted-icon-size: var(--_icon-size);
283
283
  }
284
284
 
285
- [data-ui='number-field'] > [data-part='start'] > svg,
286
- [data-ui='number-field'] > [data-part='end'] > svg {
285
+ [data-ui-number-field] > [data-part-start] > svg,
286
+ [data-ui-number-field] > [data-part-end] > svg {
287
287
  block-size: var(--_icon-size);
288
288
  inline-size: var(--_icon-size);
289
289
  }
@@ -294,8 +294,8 @@
294
294
  * advance width. An adornment that draws no glyph takes the margin the glyph
295
295
  * box already has, on both sides — the measurement `text-field` derived.
296
296
  */
297
- [data-ui='number-field'] > [data-part='start']:not(:has(svg, img, [data-ui='icon'])),
298
- [data-ui='number-field'] > [data-part='end']:not(:has(svg, img, [data-ui='icon'])) {
297
+ [data-ui-number-field] > [data-part-start]:not(:has(svg, img, [data-ui-icon])),
298
+ [data-ui-number-field] > [data-part-end]:not(:has(svg, img, [data-ui-icon])) {
299
299
  padding-inline: calc(var(--_icon-size) / 8);
300
300
  }
301
301
 
@@ -308,12 +308,11 @@
308
308
  * mark is not a button, it has no ground to change, and the cursor alone
309
309
  * said nothing a reader would look at.
310
310
  */
311
- [data-ui='number-field']
312
- > :is([data-part='start'], [data-part='end']):has(> [data-part='scrub']) {
311
+ [data-ui-number-field] > :is([data-part-start], [data-part-end]):has(> [data-part-scrub]) {
313
312
  align-self: stretch;
314
313
  }
315
314
 
316
- [data-ui='number-field'] [data-part='scrub'] {
315
+ [data-ui-number-field] [data-part-scrub] {
317
316
  align-items: center;
318
317
  align-self: stretch;
319
318
  cursor: ew-resize;
@@ -323,16 +322,19 @@
323
322
  touch-action: none;
324
323
  transition: color var(--slotted-control-transition-duration)
325
324
  var(--slotted-control-transition-easing);
325
+ /* Its own bidi run: as a flex container its text is a new block, and a
326
+ mark of more than one character read backwards in a right-to-left page. */
327
+ unicode-bidi: plaintext;
326
328
  user-select: none;
327
329
  -webkit-user-select: none;
328
330
  }
329
331
 
330
- [data-ui='number-field']:not([data-disabled]):not([data-readonly])
331
- [data-part='scrub']:is(:hover, [data-scrubbing]) {
332
+ [data-ui-number-field]:not([data-disabled]):not([data-readonly])
333
+ [data-part-scrub]:is(:hover, [data-scrubbing]) {
332
334
  color: var(--slotted-number-field-scrub-active-color, var(--slotted-text, CanvasText));
333
335
  }
334
336
 
335
- [data-ui='number-field']:is([data-disabled], [data-readonly]) [data-part='scrub'] {
337
+ [data-ui-number-field]:is([data-disabled], [data-readonly]) [data-part-scrub] {
336
338
  cursor: default;
337
339
  touch-action: auto;
338
340
  }
@@ -344,9 +346,9 @@
344
346
  * screen-reader cursor still reaches them. Their glyphs are the `Glyph`
345
347
  * element the binding renders: a character is never an icon.
346
348
  */
347
- [data-ui='number-field'] > [data-part='stepper'] > button,
348
- [data-ui='number-field'] > [data-part='decrement'],
349
- [data-ui='number-field'] > [data-part='increment'] {
349
+ [data-ui-number-field] > [data-part-stepper] > button,
350
+ [data-ui-number-field] > [data-part-decrement],
351
+ [data-ui-number-field] > [data-part-increment] {
350
352
  align-items: center;
351
353
  appearance: none;
352
354
  background-color: transparent;
@@ -370,8 +372,8 @@
370
372
 
371
373
  /* The `icon` box inside each button is drawn at the control's own icon
372
374
  step rather than at the icon family's default. */
373
- [data-ui='number-field'] [data-part='decrement'],
374
- [data-ui='number-field'] [data-part='increment'] {
375
+ [data-ui-number-field] [data-part-decrement],
376
+ [data-ui-number-field] [data-part-increment] {
375
377
  --slotted-icon-size: var(--_icon-size);
376
378
  }
377
379
 
@@ -386,7 +388,7 @@
386
388
  * would have to be mirrored in a right-to-left document; less and more do not
387
389
  * change with the reading direction.
388
390
  */
389
- [data-ui='number-field'][data-stepper='stacked'] [data-part='increment'] > [data-ui='icon'] {
391
+ [data-ui-number-field][data-stepper='stacked'] [data-part-increment] > [data-ui-icon] {
390
392
  rotate: 0.5turn;
391
393
  }
392
394
 
@@ -400,11 +402,11 @@
400
402
  * halves are one surface. The paint gives the inset back to the pointer:
401
403
  * each half's hit area reaches the frame below.
402
404
  */
403
- [data-ui='number-field'][data-part='root'][data-stepper='stacked'] {
405
+ [data-ui-number-field][data-part-root][data-stepper='stacked'] {
404
406
  padding-inline-end: 0;
405
407
  }
406
408
 
407
- [data-ui='number-field'] > [data-part='stepper'] {
409
+ [data-ui-number-field] > [data-part-stepper] {
408
410
  align-self: stretch;
409
411
  box-sizing: content-box;
410
412
  display: flex;
@@ -415,26 +417,26 @@
415
417
  padding-inline-end: var(--_column-inset);
416
418
  }
417
419
 
418
- [data-ui='number-field'] > [data-part='stepper'] > button {
420
+ [data-ui-number-field] > [data-part-stepper] > button {
419
421
  /* Two halves of the column, whatever the frame's height turns out to be. */
420
422
  block-size: 50%;
421
423
  border-radius: var(--_column-radius);
422
424
  inline-size: 100%;
423
425
  }
424
426
 
425
- [data-ui='number-field']
426
- > [data-part='stepper']
427
- > :is([data-part='increment'], [data-part='decrement'])::after {
427
+ [data-ui-number-field]
428
+ > [data-part-stepper]
429
+ > :is([data-part-increment], [data-part-decrement])::after {
428
430
  content: '';
429
431
  inset-inline: 0 calc(var(--_column-inset) * -1);
430
432
  position: absolute;
431
433
  }
432
434
 
433
- [data-ui='number-field'] > [data-part='stepper'] > [data-part='increment']::after {
435
+ [data-ui-number-field] > [data-part-stepper] > [data-part-increment]::after {
434
436
  inset-block: calc(var(--_column-inset) * -1) 0;
435
437
  }
436
438
 
437
- [data-ui='number-field'] > [data-part='stepper'] > [data-part='decrement']::after {
439
+ [data-ui-number-field] > [data-part-stepper] > [data-part-decrement]::after {
438
440
  inset-block: 0 calc(var(--_column-inset) * -1);
439
441
  }
440
442
 
@@ -453,7 +455,7 @@
453
455
  * percentage falls back to the `<svg>`'s own square, and two of them plus the
454
456
  * divider stood a pixel taller than the value and grew the frame.
455
457
  */
456
- [data-ui='number-field'] > [data-part='stepper'] > button > [data-ui='icon'] {
458
+ [data-ui-number-field] > [data-part-stepper] > button > [data-ui-icon] {
457
459
  block-size: min(var(--_icon-size), 100%);
458
460
  contain: size;
459
461
  }
@@ -466,28 +468,28 @@
466
468
  * the two buttons, which is where a quantity belongs. No rule divides a
467
469
  * button from the value: the ground it paints is its edge.
468
470
  */
469
- [data-ui='number-field'][data-part='root'][data-stepper='split'] {
471
+ [data-ui-number-field][data-part-root][data-stepper='split'] {
470
472
  gap: 0;
471
473
  padding-inline: var(--_inset);
472
474
  }
473
475
 
474
- [data-ui='number-field'][data-stepper='split'] > [data-part='decrement'],
475
- [data-ui='number-field'][data-stepper='split'] > [data-part='increment'] {
476
+ [data-ui-number-field][data-stepper='split'] > [data-part-decrement],
477
+ [data-ui-number-field][data-stepper='split'] > [data-part-increment] {
476
478
  block-size: var(--_action-size);
477
479
  border-radius: var(--_action-radius);
478
480
  inline-size: var(--_action-size);
479
481
  }
480
482
 
481
- [data-ui='number-field'][data-stepper='split'] > [data-part='input'] {
483
+ [data-ui-number-field][data-stepper='split'] > [data-part-input] {
482
484
  padding-inline: var(--_gap);
483
485
  text-align: center;
484
486
  }
485
487
 
486
- [data-ui='number-field'][data-stepper='split'] > [data-part='start'] {
488
+ [data-ui-number-field][data-stepper='split'] > [data-part-start] {
487
489
  padding-inline-start: var(--_gap);
488
490
  }
489
491
 
490
- [data-ui='number-field'][data-stepper='split'] > [data-part='end'] {
492
+ [data-ui-number-field][data-stepper='split'] > [data-part-end] {
491
493
  padding-inline-end: var(--_gap);
492
494
  }
493
495
 
@@ -503,8 +505,8 @@
503
505
  * small target. That shortfall is the arrangement's own, and `split` is the
504
506
  * answer to it.
505
507
  */
506
- [data-ui='number-field'][data-stepper='split'] > [data-part='decrement']::after,
507
- [data-ui='number-field'][data-stepper='split'] > [data-part='increment']::after {
508
+ [data-ui-number-field][data-stepper='split'] > [data-part-decrement]::after,
509
+ [data-ui-number-field][data-stepper='split'] > [data-part-increment]::after {
508
510
  content: '';
509
511
  inset: min(0px, calc((100% - var(--slotted-target-min, 24px)) / 2));
510
512
  position: absolute;
@@ -522,14 +524,14 @@
522
524
  * inline axis, over the value's edge and past the frame's.
523
525
  */
524
526
  @media (pointer: coarse) {
525
- [data-ui='number-field'][data-stepper='split']
526
- > :is([data-part='decrement'], [data-part='increment'])::after {
527
+ [data-ui-number-field][data-stepper='split']
528
+ > :is([data-part-decrement], [data-part-increment])::after {
527
529
  inset: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
528
530
  }
529
531
 
530
- [data-ui='number-field']
531
- > [data-part='stepper']
532
- > :is([data-part='increment'], [data-part='decrement'])::after {
532
+ [data-ui-number-field]
533
+ > [data-part-stepper]
534
+ > :is([data-part-increment], [data-part-decrement])::after {
533
535
  inset-inline: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
534
536
  }
535
537
  }
@@ -540,16 +542,16 @@
540
542
  * ones it can meet, which is the order `STATE_PRECEDENCE` sets.
541
543
  */
542
544
 
543
- [data-ui='number-field'] [data-part='decrement']:hover:not(:disabled),
544
- [data-ui='number-field'] [data-part='increment']:hover:not(:disabled) {
545
+ [data-ui-number-field] [data-part-decrement]:hover:not(:disabled),
546
+ [data-ui-number-field] [data-part-increment]:hover:not(:disabled) {
545
547
  background-color: var(
546
548
  --slotted-number-field-stepper-hover-background,
547
549
  var(--slotted-tone-secondary-subtle-hover)
548
550
  );
549
551
  }
550
552
 
551
- [data-ui='number-field'] [data-part='decrement']:active:not(:disabled),
552
- [data-ui='number-field'] [data-part='increment']:active:not(:disabled) {
553
+ [data-ui-number-field] [data-part-decrement]:active:not(:disabled),
554
+ [data-ui-number-field] [data-part-increment]:active:not(:disabled) {
553
555
  background-color: var(
554
556
  --slotted-number-field-stepper-active-background,
555
557
  var(--slotted-tone-secondary-subtle-active)
@@ -563,8 +565,8 @@
563
565
  * drawing them, because a number field without its stepper is a different
564
566
  * component and a disabled form still has to say what it holds.
565
567
  */
566
- [data-ui='number-field'] [data-part='decrement']:disabled,
567
- [data-ui='number-field'] [data-part='increment']:disabled {
568
+ [data-ui-number-field] [data-part-decrement]:disabled,
569
+ [data-ui-number-field] [data-part-increment]:disabled {
568
570
  /**
569
571
  * The ground as well as the ink. The disabled foreground and the resting
570
572
  * stepper colour are two steps of one neutral and differ by about a shade,
@@ -586,21 +588,21 @@
586
588
  * path on touch and a screen-reader cursor activating one directly. It sits
587
589
  * inside the frame's own edge, so the ring never doubles the border.
588
590
  */
589
- [data-ui='number-field'] [data-part='decrement']:focus-visible,
590
- [data-ui='number-field'] [data-part='increment']:focus-visible {
591
+ [data-ui-number-field] [data-part-decrement]:focus-visible,
592
+ [data-ui-number-field] [data-part-increment]:focus-visible {
591
593
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
592
594
  outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
593
595
  }
594
596
 
595
597
  /* ── Frame states ─────────────────────────────────────────────────────── */
596
598
 
597
- [data-ui='number-field'][data-part='root']:hover:not([data-disabled]):not([data-readonly]):not(
599
+ [data-ui-number-field][data-part-root]:hover:not([data-disabled]):not([data-readonly]):not(
598
600
  [data-invalid]
599
601
  ) {
600
602
  border-color: var(--slotted-number-field-hover-border-color, var(--slotted-tone-accent-border));
601
603
  }
602
604
 
603
- [data-ui='number-field'][data-part='root'][data-variant='subtle']:hover:not([data-disabled]):not(
605
+ [data-ui-number-field][data-part-root][data-variant='subtle']:hover:not([data-disabled]):not(
604
606
  [data-readonly]
605
607
  ):not([data-invalid]) {
606
608
  background-color: var(
@@ -609,7 +611,7 @@
609
611
  );
610
612
  }
611
613
 
612
- [data-ui='number-field'][data-part='root'][data-variant='plain']:hover:not([data-disabled]):not(
614
+ [data-ui-number-field][data-part-root][data-variant='plain']:hover:not([data-disabled]):not(
613
615
  [data-readonly]
614
616
  ):not([data-invalid]) {
615
617
  background-color: var(
@@ -625,13 +627,13 @@
625
627
  * matches `:focus-visible` on a text input for a pointer press as well as for
626
628
  * a Tab, which is right for a control whose caret is the thing that moved.
627
629
  */
628
- [data-ui='number-field'][data-part='root']:has(> [data-part='input']:focus-visible) {
630
+ [data-ui-number-field][data-part-root]:has(> [data-part-input]:focus-visible) {
629
631
  /* The resting shadow, recoloured: the lift under the control and the ring
630
632
  around it are one colour, and the state decides which colour that is. */
631
633
  box-shadow: var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
632
634
  var(--slotted-focus-ring-color, Highlight);
633
635
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
634
- outline-offset: var(--slotted-focus-ring-offset, 2px);
636
+ outline-offset: var(--slotted-control-focus-ring-offset, var(--slotted-focus-ring-offset, 2px));
635
637
  }
636
638
 
637
639
  /**
@@ -641,8 +643,8 @@
641
643
  * shadow that appears only under focus is a cell that changes size when it
642
644
  * is used.
643
645
  */
644
- [data-ui='number-field'][data-part='root'][data-variant='plain']:has(
645
- > [data-part='input']:focus-visible
646
+ [data-ui-number-field][data-part-root][data-variant='plain']:has(
647
+ > [data-part-input]:focus-visible
646
648
  ) {
647
649
  box-shadow: none;
648
650
  outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
@@ -655,7 +657,7 @@
655
657
  * colour on the element moves the outline, the shadow and both steppers'
656
658
  * rings at once.
657
659
  */
658
- [data-ui='number-field'][data-part='root'][data-invalid] {
660
+ [data-ui-number-field][data-part-root][data-invalid] {
659
661
  --slotted-focus-ring-color: var(
660
662
  --slotted-number-field-invalid-focus-ring-color,
661
663
  var(--slotted-focus-ring-color-invalid, Highlight)
@@ -683,17 +685,15 @@
683
685
  box-shadow: var(--_invalid-edge);
684
686
  }
685
687
 
686
- [data-ui='number-field'][data-part='root'][data-invalid]:has(
687
- > [data-part='input']:focus-visible
688
- ) {
688
+ [data-ui-number-field][data-part-root][data-invalid]:has(> [data-part-input]:focus-visible) {
689
689
  box-shadow:
690
690
  var(--_invalid-edge),
691
691
  var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
692
692
  var(--slotted-focus-ring-color, Highlight);
693
693
  }
694
694
 
695
- [data-ui='number-field'][data-part='root'][data-variant='plain'][data-invalid]:has(
696
- > [data-part='input']:focus-visible
695
+ [data-ui-number-field][data-part-root][data-variant='plain'][data-invalid]:has(
696
+ > [data-part-input]:focus-visible
697
697
  ) {
698
698
  /* The ring lies inside the box here, over the border and an edge as wide as
699
699
  it; the edge reaches past the ring. */
@@ -711,23 +711,24 @@
711
711
  * control draws its ring double, which a valid ring is not.
712
712
  */
713
713
  @media (forced-colors: active) {
714
- [data-ui='number-field'][data-part='root'][data-invalid] {
714
+ [data-ui-number-field][data-part-root][data-invalid] {
715
715
  outline: var(--_invalid-edge-width) solid CanvasText;
716
716
  outline-offset: calc(
717
717
  -1 * (var(--slotted-control-border-width, 1px) + var(--_invalid-edge-width))
718
718
  );
719
719
  }
720
720
 
721
- [data-ui='number-field'][data-part='root'][data-invalid]:has(
722
- > [data-part='input']:focus-visible
723
- ) {
721
+ [data-ui-number-field][data-part-root][data-invalid]:has(> [data-part-input]:focus-visible) {
724
722
  outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
725
723
  var(--slotted-focus-ring-color, Highlight);
726
- outline-offset: var(--slotted-focus-ring-offset, 2px);
724
+ outline-offset: var(
725
+ --slotted-control-focus-ring-offset,
726
+ var(--slotted-focus-ring-offset, 2px)
727
+ );
727
728
  }
728
729
 
729
- [data-ui='number-field'][data-part='root'][data-variant='plain'][data-invalid]:has(
730
- > [data-part='input']:focus-visible
730
+ [data-ui-number-field][data-part-root][data-variant='plain'][data-invalid]:has(
731
+ > [data-part-input]:focus-visible
731
732
  ) {
732
733
  outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
733
734
  var(--slotted-focus-ring-color, Highlight);
@@ -742,7 +743,7 @@
742
743
  * mistakable for disabled: the value is still real and still submitted. The
743
744
  * ground says "not yours to change" and the ink says nothing at all.
744
745
  */
745
- [data-ui='number-field'][data-part='root'][data-readonly] {
746
+ [data-ui-number-field][data-part-root][data-readonly] {
746
747
  background-color: var(
747
748
  --slotted-number-field-readonly-background,
748
749
  var(--slotted-tone-secondary-subtle-hover)
@@ -770,8 +771,8 @@
770
771
  * disabled `fieldset` disables every control inside it, and the control has
771
772
  * no way to know.
772
773
  */
773
- [data-ui='number-field'][data-part='root'][data-disabled],
774
- [data-ui='number-field'][data-part='root']:has(> [data-part='input']:disabled) {
774
+ [data-ui-number-field][data-part-root][data-disabled],
775
+ [data-ui-number-field][data-part-root]:has(> [data-part-input]:disabled) {
775
776
  background-color: var(
776
777
  --slotted-number-field-disabled-background,
777
778
  var(--slotted-disabled-background)
@@ -787,8 +788,8 @@
787
788
  * Muted to the colour the theme measures rather than faded by opacity: a
788
789
  * value nobody can read is a field nobody can check.
789
790
  */
790
- [data-ui='number-field'][data-part='root'][data-disabled] > [data-part='start'],
791
- [data-ui='number-field'][data-part='root'][data-disabled] > [data-part='end'] {
791
+ [data-ui-number-field][data-part-root][data-disabled] > [data-part-start],
792
+ [data-ui-number-field][data-part-root][data-disabled] > [data-part-end] {
792
793
  color: var(--slotted-disabled-foreground);
793
794
  }
794
795
  }
@@ -2,6 +2,7 @@
2
2
  "--slotted-border-subtle",
3
3
  "--slotted-control-border-color",
4
4
  "--slotted-control-border-width",
5
+ "--slotted-control-focus-ring-offset",
5
6
  "--slotted-control-font-family",
6
7
  "--slotted-control-font-size-lg",
7
8
  "--slotted-control-font-size-md",