@slotted/styles 0.0.0-stage → 0.1.0-beta.1

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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/package.json +276 -3
  4. package/src/accordion/accordion.css +96 -0
  5. package/src/accordion/accordion.tokens.json +14 -0
  6. package/src/action-bar/action-bar.css +455 -0
  7. package/src/action-bar/action-bar.tokens.json +50 -0
  8. package/src/action-sheet/action-sheet.css +462 -0
  9. package/src/action-sheet/action-sheet.tokens.json +59 -0
  10. package/src/alert/alert.css +764 -0
  11. package/src/alert/alert.tokens.json +77 -0
  12. package/src/app-shell/app-shell.css +1899 -0
  13. package/src/app-shell/app-shell.tokens.json +88 -0
  14. package/src/aspect-ratio/aspect-ratio.css +131 -0
  15. package/src/aspect-ratio/aspect-ratio.tokens.json +1 -0
  16. package/src/attachment/attachment.css +906 -0
  17. package/src/attachment/attachment.tokens.json +85 -0
  18. package/src/avatar/avatar.css +598 -0
  19. package/src/avatar/avatar.tokens.json +64 -0
  20. package/src/avatar-group/avatar-group.css +268 -0
  21. package/src/avatar-group/avatar-group.tokens.json +16 -0
  22. package/src/badge/badge.css +462 -0
  23. package/src/badge/badge.tokens.json +58 -0
  24. package/src/breadcrumb/breadcrumb.css +441 -0
  25. package/src/breadcrumb/breadcrumb.tokens.json +50 -0
  26. package/src/button/button.css +754 -0
  27. package/src/button/button.tokens.json +72 -0
  28. package/src/button-group/button-group.css +455 -0
  29. package/src/button-group/button-group.tokens.json +11 -0
  30. package/src/calendar/calendar.css +846 -0
  31. package/src/calendar/calendar.tokens.json +67 -0
  32. package/src/card/card.css +602 -0
  33. package/src/card/card.tokens.json +68 -0
  34. package/src/carousel/carousel.css +860 -0
  35. package/src/carousel/carousel.tokens.json +62 -0
  36. package/src/cascader/cascader.css +1320 -0
  37. package/src/cascader/cascader.tokens.json +103 -0
  38. package/src/chart/chart.css +1473 -0
  39. package/src/chart/chart.tokens.json +107 -0
  40. package/src/checkbox/checkbox.css +1011 -0
  41. package/src/checkbox/checkbox.tokens.json +102 -0
  42. package/src/checkbox-group/checkbox-group.css +70 -0
  43. package/src/checkbox-group/checkbox-group.tokens.json +6 -0
  44. package/src/code-block/code-block.css +555 -0
  45. package/src/code-block/code-block.tokens.json +69 -0
  46. package/src/collapsible/collapsible.css +546 -0
  47. package/src/collapsible/collapsible.tokens.json +55 -0
  48. package/src/color-picker/color-picker.css +607 -0
  49. package/src/color-picker/color-picker.tokens.json +58 -0
  50. package/src/column-manager/column-manager.css +452 -0
  51. package/src/column-manager/column-manager.tokens.json +43 -0
  52. package/src/combobox/combobox.css +1048 -0
  53. package/src/combobox/combobox.tokens.json +112 -0
  54. package/src/command-palette/command-palette.css +1000 -0
  55. package/src/command-palette/command-palette.tokens.json +75 -0
  56. package/src/container/container.css +198 -0
  57. package/src/container/container.tokens.json +18 -0
  58. package/src/context-menu/context-menu.css +104 -0
  59. package/src/context-menu/context-menu.tokens.json +11 -0
  60. package/src/currency-field/currency-field.css +787 -0
  61. package/src/currency-field/currency-field.tokens.json +80 -0
  62. package/src/dashboard-grid/dashboard-grid.css +748 -0
  63. package/src/dashboard-grid/dashboard-grid.tokens.json +67 -0
  64. package/src/data-grid/data-grid.css +2484 -0
  65. package/src/data-grid/data-grid.tokens.json +100 -0
  66. package/src/data-list/data-list.css +455 -0
  67. package/src/data-list/data-list.tokens.json +35 -0
  68. package/src/date-field/date-field.css +560 -0
  69. package/src/date-field/date-field.tokens.json +80 -0
  70. package/src/date-picker/date-picker.css +420 -0
  71. package/src/date-picker/date-picker.tokens.json +49 -0
  72. package/src/date-range-picker/date-range-picker.css +983 -0
  73. package/src/date-range-picker/date-range-picker.tokens.json +109 -0
  74. package/src/datetime-field/datetime-field.css +850 -0
  75. package/src/datetime-field/datetime-field.tokens.json +91 -0
  76. package/src/datetime-picker/datetime-picker.css +843 -0
  77. package/src/datetime-picker/datetime-picker.tokens.json +78 -0
  78. package/src/datetime-range-picker/datetime-range-picker.css +1375 -0
  79. package/src/datetime-range-picker/datetime-range-picker.tokens.json +135 -0
  80. package/src/description-list/description-list.css +675 -0
  81. package/src/description-list/description-list.tokens.json +66 -0
  82. package/src/detail-panel/detail-panel.css +329 -0
  83. package/src/detail-panel/detail-panel.tokens.json +33 -0
  84. package/src/dialog/dialog.css +968 -0
  85. package/src/dialog/dialog.tokens.json +66 -0
  86. package/src/divider/divider.css +131 -0
  87. package/src/divider/divider.tokens.json +18 -0
  88. package/src/drawer/drawer.css +1303 -0
  89. package/src/drawer/drawer.tokens.json +75 -0
  90. package/src/entity-picker/entity-picker.css +1367 -0
  91. package/src/entity-picker/entity-picker.tokens.json +118 -0
  92. package/src/event-calendar/event-calendar.css +2148 -0
  93. package/src/event-calendar/event-calendar.tokens.json +87 -0
  94. package/src/field/field.css +707 -0
  95. package/src/field/field.tokens.json +58 -0
  96. package/src/field-group/field-group.css +226 -0
  97. package/src/field-group/field-group.tokens.json +33 -0
  98. package/src/filter-bar/filter-bar.css +1306 -0
  99. package/src/filter-bar/filter-bar.tokens.json +78 -0
  100. package/src/form/form.css +218 -0
  101. package/src/form/form.tokens.json +32 -0
  102. package/src/fullscreen/fullscreen.css +376 -0
  103. package/src/fullscreen/fullscreen.tokens.json +50 -0
  104. package/src/grid/grid.css +173 -0
  105. package/src/grid/grid.tokens.json +20 -0
  106. package/src/highlight/highlight.css +135 -0
  107. package/src/highlight/highlight.tokens.json +16 -0
  108. package/src/hover-card/hover-card.css +93 -0
  109. package/src/hover-card/hover-card.tokens.json +17 -0
  110. package/src/icon/icon.css +136 -0
  111. package/src/icon/icon.tokens.json +14 -0
  112. package/src/image/image.css +449 -0
  113. package/src/image/image.tokens.json +27 -0
  114. package/src/import-export-center/import-export-center.css +1175 -0
  115. package/src/import-export-center/import-export-center.tokens.json +84 -0
  116. package/src/inline/inline.css +149 -0
  117. package/src/inline/inline.tokens.json +14 -0
  118. package/src/inline-message/inline-message.css +396 -0
  119. package/src/inline-message/inline-message.tokens.json +19 -0
  120. package/src/kbd/kbd.css +490 -0
  121. package/src/kbd/kbd.tokens.json +40 -0
  122. package/src/link/link.css +237 -0
  123. package/src/link/link.tokens.json +25 -0
  124. package/src/list/list.css +240 -0
  125. package/src/list/list.tokens.json +42 -0
  126. package/src/list-item/list-item.css +937 -0
  127. package/src/list-item/list-item.tokens.json +114 -0
  128. package/src/listbox/listbox.css +674 -0
  129. package/src/listbox/listbox.tokens.json +72 -0
  130. package/src/loading-overlay/loading-overlay.css +730 -0
  131. package/src/loading-overlay/loading-overlay.tokens.json +48 -0
  132. package/src/markdown/markdown.css +168 -0
  133. package/src/markdown/markdown.tokens.json +18 -0
  134. package/src/menu/menu.css +817 -0
  135. package/src/menu/menu.tokens.json +78 -0
  136. package/src/menubar/menubar.css +170 -0
  137. package/src/menubar/menubar.tokens.json +32 -0
  138. package/src/message/message.css +1453 -0
  139. package/src/message/message.tokens.json +85 -0
  140. package/src/message-scroller/message-scroller.css +371 -0
  141. package/src/message-scroller/message-scroller.tokens.json +47 -0
  142. package/src/multi-select/multi-select.css +1427 -0
  143. package/src/multi-select/multi-select.tokens.json +114 -0
  144. package/src/navigation-menu/navigation-menu.css +1029 -0
  145. package/src/navigation-menu/navigation-menu.tokens.json +70 -0
  146. package/src/notification-center/notification-center.css +856 -0
  147. package/src/notification-center/notification-center.tokens.json +84 -0
  148. package/src/number-field/number-field.css +794 -0
  149. package/src/number-field/number-field.tokens.json +80 -0
  150. package/src/otp-input/otp-input.css +525 -0
  151. package/src/otp-input/otp-input.tokens.json +69 -0
  152. package/src/page/page.css +179 -0
  153. package/src/page/page.tokens.json +20 -0
  154. package/src/page-header/page-header.css +1181 -0
  155. package/src/page-header/page-header.tokens.json +71 -0
  156. package/src/pagination/pagination.css +500 -0
  157. package/src/pagination/pagination.tokens.json +56 -0
  158. package/src/popover/popover.css +526 -0
  159. package/src/popover/popover.tokens.json +60 -0
  160. package/src/progress-indicator/progress-indicator.css +1584 -0
  161. package/src/progress-indicator/progress-indicator.tokens.json +50 -0
  162. package/src/prompt-composer/prompt-composer.css +680 -0
  163. package/src/prompt-composer/prompt-composer.tokens.json +99 -0
  164. package/src/prose/prose.css +733 -0
  165. package/src/prose/prose.tokens.json +79 -0
  166. package/src/radio-group/radio-group.css +778 -0
  167. package/src/radio-group/radio-group.tokens.json +103 -0
  168. package/src/rating/rating.css +1071 -0
  169. package/src/rating/rating.tokens.json +88 -0
  170. package/src/result-state/result-state.css +980 -0
  171. package/src/result-state/result-state.tokens.json +63 -0
  172. package/src/runtime-properties.mjs +321 -0
  173. package/src/saved-views/saved-views.css +394 -0
  174. package/src/saved-views/saved-views.tokens.json +41 -0
  175. package/src/scroll-area/scroll-area.css +481 -0
  176. package/src/scroll-area/scroll-area.tokens.json +15 -0
  177. package/src/section/section.css +177 -0
  178. package/src/section/section.tokens.json +39 -0
  179. package/src/segmented-control/segmented-control.css +564 -0
  180. package/src/segmented-control/segmented-control.tokens.json +67 -0
  181. package/src/select/select.css +1593 -0
  182. package/src/select/select.tokens.json +110 -0
  183. package/src/side-navigation/side-navigation.css +1096 -0
  184. package/src/side-navigation/side-navigation.tokens.json +87 -0
  185. package/src/skeleton/skeleton.css +431 -0
  186. package/src/skeleton/skeleton.tokens.json +29 -0
  187. package/src/slider/slider.css +792 -0
  188. package/src/slider/slider.tokens.json +75 -0
  189. package/src/sparkline/sparkline.css +282 -0
  190. package/src/sparkline/sparkline.tokens.json +45 -0
  191. package/src/spinner/spinner.css +224 -0
  192. package/src/spinner/spinner.tokens.json +8 -0
  193. package/src/split-button/split-button.css +253 -0
  194. package/src/split-button/split-button.tokens.json +12 -0
  195. package/src/splitter/splitter.css +336 -0
  196. package/src/splitter/splitter.tokens.json +24 -0
  197. package/src/stack/stack.css +128 -0
  198. package/src/stack/stack.tokens.json +14 -0
  199. package/src/stat-card/stat-card.css +641 -0
  200. package/src/stat-card/stat-card.tokens.json +95 -0
  201. package/src/status-indicator/status-indicator.css +481 -0
  202. package/src/status-indicator/status-indicator.tokens.json +38 -0
  203. package/src/stepper/stepper.css +629 -0
  204. package/src/stepper/stepper.tokens.json +72 -0
  205. package/src/switch/switch.css +703 -0
  206. package/src/switch/switch.tokens.json +75 -0
  207. package/src/table/table.css +1482 -0
  208. package/src/table/table.tokens.json +69 -0
  209. package/src/table-of-contents/table-of-contents.css +533 -0
  210. package/src/table-of-contents/table-of-contents.tokens.json +53 -0
  211. package/src/tabs/tabs.css +998 -0
  212. package/src/tabs/tabs.tokens.json +82 -0
  213. package/src/tag/tag.css +768 -0
  214. package/src/tag/tag.tokens.json +85 -0
  215. package/src/tags-input/tags-input.css +757 -0
  216. package/src/tags-input/tags-input.tokens.json +84 -0
  217. package/src/text-field/text-field.css +900 -0
  218. package/src/text-field/text-field.tokens.json +87 -0
  219. package/src/textarea/textarea.css +365 -0
  220. package/src/textarea/textarea.tokens.json +59 -0
  221. package/src/time-field/time-field.css +719 -0
  222. package/src/time-field/time-field.tokens.json +86 -0
  223. package/src/time-picker/time-picker.css +665 -0
  224. package/src/time-picker/time-picker.tokens.json +66 -0
  225. package/src/time-range-picker/time-range-picker.css +1287 -0
  226. package/src/time-range-picker/time-range-picker.tokens.json +134 -0
  227. package/src/timeline/timeline.css +1596 -0
  228. package/src/timeline/timeline.tokens.json +96 -0
  229. package/src/toast/toast.css +943 -0
  230. package/src/toast/toast.tokens.json +90 -0
  231. package/src/toggle/toggle.css +290 -0
  232. package/src/toggle/toggle.tokens.json +54 -0
  233. package/src/toggle-group/toggle-group.css +463 -0
  234. package/src/toggle-group/toggle-group.tokens.json +54 -0
  235. package/src/toolbar/toolbar.css +434 -0
  236. package/src/toolbar/toolbar.tokens.json +49 -0
  237. package/src/tooltip/tooltip.css +368 -0
  238. package/src/tooltip/tooltip.tokens.json +39 -0
  239. package/src/top-navigation/top-navigation.css +1287 -0
  240. package/src/top-navigation/top-navigation.tokens.json +91 -0
  241. package/src/tour/tour.css +680 -0
  242. package/src/tour/tour.tokens.json +67 -0
  243. package/src/transfer/transfer.css +571 -0
  244. package/src/transfer/transfer.tokens.json +49 -0
  245. package/src/tree/tree.css +1000 -0
  246. package/src/tree/tree.tokens.json +80 -0
  247. package/src/typography/typography.css +211 -0
  248. package/src/typography/typography.tokens.json +31 -0
  249. package/src/upload/upload.css +1706 -0
  250. package/src/upload/upload.tokens.json +123 -0
  251. package/src/visually-hidden/visually-hidden.css +52 -0
  252. package/src/visually-hidden/visually-hidden.tokens.json +1 -0
  253. package/src/wizard/wizard.css +740 -0
  254. package/src/wizard/wizard.tokens.json +63 -0
@@ -0,0 +1,1287 @@
1
+ @layer slotted.components {
2
+ /**
3
+ * ── A one-line frame, and behind it one end at a time ──
4
+ *
5
+ * ┌─ root ──────────────────────────────────────────────────────────────┐
6
+ * │ ┌─ control ── the frame ─────────────────────────────────────────┐ │
7
+ * │ │ ┌ trigger ──────────────────────────────────────────────────┐ │ │
8
+ * │ │ │ summary: 14:00 – 16:30 ┌ clear ┐ clock │ │ │
9
+ * │ │ └───────────────────────────────────────────┴───────┴───────┘ │ │
10
+ * │ └────────────────────────────────────────────────────────────────┘ │
11
+ * └─────────────────────────────────────────────────────────────────────┘
12
+ * ┌─ positioner ─ the layer ───────────────────────────────────┐
13
+ * │ ┌─ content ─ the surface ─────────────────────────────┐ │
14
+ * │ │ head: tabs [ START · 14:00 ] [ END · — ] │ │
15
+ * │ │ field [time-field] now │ │
16
+ * │ │ hint Choose the end length · limit │ │
17
+ * │ │ presets: chip chip chip │ │
18
+ * │ │ panel (the current end): list │ │
19
+ * │ │ footer done │ │
20
+ * │ └─────────────────────────────────────────────────────┘ │
21
+ * └───────────────────────────────────────────────────────────┘
22
+ *
23
+ * The field inside keeps its own `data-ui`. Nothing here selects a
24
+ * segment: this stylesheet owns the frame, the layer, the band the field
25
+ * stands in, and the list.
26
+ *
27
+ * **The frame is one line at any width.** Two segmented fields stood in it
28
+ * first — the shape `date-range-picker` has — and were withdrawn at the
29
+ * visual gate: a segment cannot shrink, and two fields broke the frame into
30
+ * two lines in any form column narrower than they are, against the height
31
+ * every control shares. The frame keeps the value in words.
32
+ *
33
+ * **The band speaks to the field through its tokens and never through its
34
+ * parts** — the rule `date-range-picker` records.
35
+ *
36
+ * **One end at a time.** Two lists side by side, under two fields, were
37
+ * refused at the release gate as too much interface at once for a lay
38
+ * reader and for a phone. The tab says which end, the panel shows only
39
+ * that end, and choosing one end moves to the other — the end list
40
+ * appears already striking what the chosen start refuses.
41
+ */
42
+ [data-ui='time-range-picker'][data-part='root'] {
43
+ display: block;
44
+ /* The anchor the positioner measures is the control, and a block root
45
+ lets the frame take the width the form gave it. */
46
+ inline-size: 100%;
47
+ }
48
+
49
+ /* ── The frame ────────────────────────────────────────────────────────
50
+ *
51
+ * One line, at the height the scale gives every control. The frame
52
+ * `select` draws: the value in words, cut with an ellipsis where it does
53
+ * not fit, and the trigger filling the box. Two segmented fields stood here
54
+ * first and were withdrawn at the visual gate — a segment cannot shrink,
55
+ * and two of them broke the frame into two lines in any form column
56
+ * narrower than they are, against the height every control shares.
57
+ */
58
+ [data-ui='time-range-picker'] [data-part='control'] {
59
+ --_font-size: var(--slotted-control-font-size-md, 13px);
60
+ --_height: var(--slotted-control-height-md, 34px);
61
+ --_padding-inline: var(--slotted-control-padding-inline-md, 13px);
62
+ --_gap: var(--slotted-control-gap-md, 8px);
63
+ --_icon-size: var(--slotted-control-icon-size-md, 16px);
64
+ --_border-width: var(--slotted-control-border-width, 1px);
65
+
66
+ /* The same inner-control box every family in the library draws: the glyph,
67
+ and one step of air on each side, bounded by the frame's own height. */
68
+ --_action-size: var(
69
+ --slotted-time-range-picker-action-size,
70
+ min(
71
+ calc(var(--_icon-size) + 2 * var(--slotted-space-2, 0.25rem)),
72
+ calc(var(--_height) - var(--_border-width) * 2 - var(--slotted-space-2, 0.25rem))
73
+ )
74
+ );
75
+ --_action-inset: max(
76
+ 0px,
77
+ calc(var(--_padding-inline) - (var(--_action-size) - var(--_icon-size)) / 2)
78
+ );
79
+
80
+ background-color: var(
81
+ --slotted-time-range-picker-background,
82
+ var(--slotted-control-surface, Field)
83
+ );
84
+ block-size: var(--_height);
85
+ border: var(--_border-width) solid
86
+ var(
87
+ --slotted-time-range-picker-border-color,
88
+ var(--slotted-control-border-color, ButtonBorder)
89
+ );
90
+ border-radius: var(--slotted-time-range-picker-radius, var(--slotted-control-radius, 4px));
91
+ box-shadow: var(--slotted-time-range-picker-shadow, var(--slotted-control-shadow, none));
92
+ box-sizing: border-box;
93
+ color: var(--slotted-time-range-picker-color, var(--slotted-text, CanvasText));
94
+ display: flex;
95
+ font-family: var(--slotted-control-font-family, system-ui, sans-serif);
96
+ font-size: var(--_font-size);
97
+ inline-size: 100%;
98
+ min-inline-size: 0;
99
+ position: relative;
100
+ transition:
101
+ background-color var(--slotted-control-transition-duration)
102
+ var(--slotted-control-transition-easing),
103
+ border-color var(--slotted-control-transition-duration)
104
+ var(--slotted-control-transition-easing),
105
+ box-shadow var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
106
+ }
107
+
108
+ [data-ui='time-range-picker'][data-part='root'][data-size='sm'] [data-part='control'] {
109
+ --_font-size: var(--slotted-control-font-size-sm, 12px);
110
+ --_height: var(--slotted-control-height-sm, 30px);
111
+ --_padding-inline: var(--slotted-control-padding-inline-sm, 11px);
112
+ --_gap: var(--slotted-control-gap-sm, 6px);
113
+ --_icon-size: var(--slotted-control-icon-size-sm, 14px);
114
+ }
115
+
116
+ [data-ui='time-range-picker'][data-part='root'][data-size='lg'] [data-part='control'] {
117
+ --_font-size: var(--slotted-control-font-size-lg, 14px);
118
+ --_height: var(--slotted-control-height-lg, 38px);
119
+ --_padding-inline: var(--slotted-control-padding-inline-lg, 15px);
120
+ --_gap: var(--slotted-control-gap-lg, 10px);
121
+ --_icon-size: var(--slotted-control-icon-size-lg, 18px);
122
+ }
123
+
124
+ /* ── Variant ──────────────────────────────────────────────────────────
125
+ *
126
+ * The three steps `text-field` set, through the field's own variant tokens.
127
+ */
128
+ [data-ui='time-range-picker'][data-part='root'][data-variant='subtle'] [data-part='control'] {
129
+ background-color: var(
130
+ --slotted-time-range-picker-subtle-background,
131
+ var(--slotted-surface-sunken, Canvas)
132
+ );
133
+ border-color: var(
134
+ --slotted-time-range-picker-subtle-border-color,
135
+ var(--slotted-border-subtle, ButtonBorder)
136
+ );
137
+ }
138
+
139
+ [data-ui='time-range-picker'][data-part='root'][data-variant='plain'] [data-part='control'] {
140
+ background-color: transparent;
141
+ border-color: transparent;
142
+ border-radius: var(--slotted-radius-none, 0px);
143
+ box-shadow: none;
144
+ }
145
+
146
+ /* ── The trigger ──────────────────────────────────────────────────────
147
+ *
148
+ * A transparent button filling the frame, with the value as its content and
149
+ * the glyph at its reading end: the whole box opens the panel, which is the
150
+ * shape `select` has. It is always drawn — ChromeOS turns `Alt`+`ArrowDown`
151
+ * into `PageDown` before the browser sees it, so a chord cannot be the only
152
+ * way in.
153
+ */
154
+ [data-ui='time-range-picker'] [data-part='trigger'] {
155
+ align-items: center;
156
+ appearance: none;
157
+ background-color: transparent;
158
+ border: 0;
159
+ border-radius: inherit;
160
+ color: inherit;
161
+ cursor: pointer;
162
+ display: flex;
163
+ flex: 1 1 auto;
164
+ font: inherit;
165
+ gap: var(--_gap);
166
+ min-inline-size: 0;
167
+ padding-block: 0;
168
+ padding-inline-start: var(--_padding-inline);
169
+ /* Room for the glyph, and for the clear beside it when there is one. */
170
+ padding-inline-end: calc(
171
+ var(--_action-inset) + var(--_action-size) * var(--_actions, 1) +
172
+ var(--slotted-space-1, 0.125rem) * (var(--_actions, 1) - 1) +
173
+ var(--slotted-space-2, 0.25rem)
174
+ );
175
+ text-align: start;
176
+ touch-action: manipulation;
177
+ -webkit-tap-highlight-color: transparent;
178
+ }
179
+
180
+ [data-ui='time-range-picker'] [data-part='control']:has(> [data-part='clear']) {
181
+ --_actions: 2;
182
+ }
183
+
184
+ /* The value in words, one line, cut where it does not fit: the trigger's
185
+ name carries it whole, so the ellipsis removes nothing a reader cannot
186
+ hear. Tabular figures, so two ranges in a form line up. */
187
+ [data-ui='time-range-picker'] [data-part='summary'] {
188
+ flex: 1 1 auto;
189
+ font-variant-numeric: tabular-nums;
190
+ min-inline-size: 0;
191
+ overflow: hidden;
192
+ text-overflow: ellipsis;
193
+ unicode-bidi: plaintext;
194
+ white-space: nowrap;
195
+ }
196
+
197
+ [data-ui='time-range-picker'] [data-part='summary'][data-placeholder] {
198
+ color: var(--slotted-time-range-picker-placeholder-color, var(--slotted-text-muted, GrayText));
199
+ }
200
+
201
+ /* The clock `time-picker` puts on its trigger, saying what kind of value the
202
+ frame holds; it does not turn while the surface is open. A `Glyph` the
203
+ binding draws after the summary, placed at the inner-control inset, so it
204
+ sits where `date-range-picker` sits its calendar. */
205
+ /* The frame draws the ring for the trigger; the browser's own ring on the
206
+ trigger would be a second one, inside the frame and over its edge. */
207
+ [data-ui='time-range-picker'] [data-part='trigger']:focus-visible {
208
+ outline: none;
209
+ }
210
+
211
+ [data-ui='time-range-picker'] [data-part='trigger'] > [data-ui='icon'] {
212
+ --slotted-icon-size: var(--_icon-size);
213
+
214
+ /* No system-colour fallback on a decoration: unthemed, it takes the
215
+ trigger's ink rather than shouts. */
216
+ color: var(--slotted-time-range-picker-action-color, var(--slotted-text-muted));
217
+ inset-block-start: 50%;
218
+ inset-inline-end: calc(var(--_action-inset) + (var(--_action-size) - var(--_icon-size)) / 2);
219
+ position: absolute;
220
+ translate: 0 -50%;
221
+ }
222
+
223
+ [data-ui='time-range-picker'] [data-part='trigger']:disabled {
224
+ cursor: not-allowed;
225
+ }
226
+
227
+ /* ── The clear ────────────────────────────────────────────────────────
228
+ *
229
+ * The inner-control box, before the glyph, as every clear in the library
230
+ * stands. Its own ring: tabbing from the trigger to it has to move
231
+ * something visible, and the frame's ring would sit still.
232
+ */
233
+ [data-ui='time-range-picker'] [data-part='clear'] {
234
+ --slotted-icon-size: var(--_icon-size);
235
+
236
+ align-items: center;
237
+ appearance: none;
238
+ background-color: transparent;
239
+ block-size: var(--_action-size);
240
+ border: 0;
241
+ border-radius: var(--slotted-time-range-picker-radius, var(--slotted-control-radius, 4px));
242
+ color: var(--slotted-time-range-picker-action-color, var(--slotted-text-muted, GrayText));
243
+ cursor: pointer;
244
+ display: inline-flex;
245
+ flex: 0 0 auto;
246
+ inline-size: var(--_action-size);
247
+ inset-block-start: calc((var(--_height) - var(--_border-width) * 2 - var(--_action-size)) / 2);
248
+ inset-inline-end: calc(
249
+ var(--_action-inset) + var(--_action-size) + var(--slotted-space-1, 0.125rem)
250
+ );
251
+ justify-content: center;
252
+ padding: 0;
253
+ position: absolute;
254
+ touch-action: manipulation;
255
+ transition:
256
+ background-color var(--slotted-control-transition-duration)
257
+ var(--slotted-control-transition-easing),
258
+ color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
259
+ -webkit-tap-highlight-color: transparent;
260
+ }
261
+
262
+ /* The hit area, recovered outside the paint, as every inner control does. */
263
+ [data-ui='time-range-picker'] [data-part='clear']::after {
264
+ content: '';
265
+ inset: min(0px, calc((100% - var(--slotted-target-min, 24px)) / 2));
266
+ position: absolute;
267
+ }
268
+
269
+ /* On a finger the target is the comfortable size in both axes and the box
270
+ is the one a mouse sees: the ground and the focus ring stay square, and
271
+ the hit area above grows to 44 pixels around them. It does not reach into
272
+ the clock's lane after it, which is the trigger's to answer. */
273
+ @media (pointer: coarse) {
274
+ [data-ui='time-range-picker'] [data-part='clear']::after {
275
+ inset: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
276
+ inset-inline-end: 0;
277
+ }
278
+ }
279
+
280
+ [data-ui='time-range-picker'] [data-part='clear']:hover:not(:disabled):not([data-disabled]) {
281
+ background-color: var(
282
+ --slotted-time-range-picker-action-hover-background,
283
+ var(--slotted-tone-secondary-subtle-hover)
284
+ );
285
+ }
286
+
287
+ [data-ui='time-range-picker'] [data-part='clear']:active:not(:disabled):not([data-disabled]) {
288
+ background-color: var(
289
+ --slotted-time-range-picker-action-active-background,
290
+ var(--slotted-tone-secondary-subtle-active)
291
+ );
292
+ }
293
+
294
+ [data-ui='time-range-picker'] [data-part='clear']:focus-visible {
295
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
296
+ outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
297
+ }
298
+
299
+ [data-ui='time-range-picker'] [data-part='clear']:disabled {
300
+ color: var(--slotted-disabled-foreground);
301
+ cursor: not-allowed;
302
+ }
303
+
304
+ /* ── States on the frame ──────────────────────────────────────────────
305
+ *
306
+ * Written strongest last, and each weaker one guarded against every stronger
307
+ * one it can meet, which is the order `STATE_PRECEDENCE` sets.
308
+ */
309
+
310
+ [data-ui='time-range-picker'][data-part='root']:not([data-disabled]):not([data-readonly]):not(
311
+ [data-invalid]
312
+ )
313
+ [data-part='control']:hover {
314
+ border-color: var(
315
+ --slotted-time-range-picker-hover-border-color,
316
+ var(--slotted-tone-accent-border)
317
+ );
318
+ }
319
+
320
+ [data-ui='time-range-picker'][data-part='root'][data-variant='subtle']:not([data-disabled]):not(
321
+ [data-readonly]
322
+ ):not([data-invalid])
323
+ [data-part='control']:hover {
324
+ background-color: var(
325
+ --slotted-time-range-picker-subtle-hover-background,
326
+ var(--slotted-tone-secondary-subtle-hover)
327
+ );
328
+ }
329
+
330
+ [data-ui='time-range-picker'][data-part='root'][data-variant='plain']:not([data-disabled]):not(
331
+ [data-readonly]
332
+ ):not([data-invalid])
333
+ [data-part='control']:hover {
334
+ background-color: var(
335
+ --slotted-time-range-picker-plain-hover-background,
336
+ var(--slotted-tone-secondary-subtle-hover)
337
+ );
338
+ border-color: transparent;
339
+ }
340
+
341
+ /* The trigger is the only thing in the frame that takes focus, apart from
342
+ the clear, which draws its own ring; the frame's ring is drawn for it. */
343
+ [data-ui='time-range-picker'] [data-part='control']:has(> [data-part='trigger']:focus-visible) {
344
+ box-shadow: var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
345
+ var(--slotted-focus-ring-color, Highlight);
346
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
347
+ outline-offset: var(--slotted-focus-ring-offset, 2px);
348
+ }
349
+
350
+ /* The ring of a control whose box is not its own is drawn inside that box,
351
+ and there is no lift — the `plain` rule of `plain-variant.test.mjs`. */
352
+ [data-ui='time-range-picker'][data-part='root'][data-variant='plain']
353
+ [data-part='control']:has(> [data-part='trigger']:focus-visible) {
354
+ box-shadow: none;
355
+ outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
356
+ }
357
+
358
+ /* Invalid outranks hover and is written after it. The ring is retargeted
359
+ rather than repainted, so every ring in the frame moves at once. */
360
+ [data-ui='time-range-picker'][data-part='root'][data-invalid] [data-part='control'] {
361
+ --slotted-focus-ring-color: var(
362
+ --slotted-time-range-picker-invalid-focus-ring-color,
363
+ var(--slotted-focus-ring-color-invalid, Highlight)
364
+ );
365
+ --_invalid-edge-width: var(
366
+ --slotted-time-range-picker-invalid-edge-width,
367
+ var(--slotted-control-invalid-edge-width, 1px)
368
+ );
369
+ --_invalid-edge-color: var(
370
+ --slotted-time-range-picker-invalid-border-color,
371
+ var(--slotted-tone-danger-border)
372
+ );
373
+ --_invalid-edge: inset 0 0 0 var(--_invalid-edge-width) var(--_invalid-edge-color);
374
+
375
+ border-color: var(
376
+ --slotted-time-range-picker-invalid-border-color,
377
+ var(--slotted-tone-danger-border)
378
+ );
379
+ /*
380
+ * Width as well as colour (WCAG 1.4.1), the edge `text-field` draws: in
381
+ * `high-contrast` the danger border is the resting edge's black. The line
382
+ * is a shadow inside the border, so neither box nor text moves, and it
383
+ * takes the resting lift's place.
384
+ */
385
+ box-shadow: var(--_invalid-edge);
386
+ }
387
+
388
+ [data-ui='time-range-picker'][data-invalid]
389
+ [data-part='control']:has(> [data-part='trigger']:focus-visible) {
390
+ box-shadow:
391
+ var(--_invalid-edge),
392
+ var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
393
+ var(--slotted-focus-ring-color, Highlight);
394
+ }
395
+
396
+ [data-ui='time-range-picker'][data-part='root'][data-variant='plain'][data-invalid]
397
+ [data-part='control']:has(> [data-part='trigger']:focus-visible) {
398
+ /* The ring lies inside the box here, over the border and an edge as wide as
399
+ it; the edge reaches past the ring. */
400
+ box-shadow: inset 0 0 0
401
+ calc(
402
+ var(--slotted-focus-ring-offset, 2px) - var(--_border-width) + var(--_invalid-edge-width)
403
+ )
404
+ var(--_invalid-edge-color);
405
+ }
406
+
407
+ /*
408
+ * Forced colours remove every box shadow, and the edge with them. The
409
+ * width comes back as an outline inside the border, and a focused invalid
410
+ * control draws its ring double, which a valid ring is not.
411
+ */
412
+ @media (forced-colors: active) {
413
+ [data-ui='time-range-picker'][data-part='root'][data-invalid] [data-part='control'] {
414
+ outline: var(--_invalid-edge-width) solid CanvasText;
415
+ outline-offset: calc(-1 * (var(--_border-width) + var(--_invalid-edge-width)));
416
+ }
417
+
418
+ [data-ui='time-range-picker'][data-invalid]
419
+ [data-part='control']:has(> [data-part='trigger']:focus-visible) {
420
+ outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
421
+ var(--slotted-focus-ring-color, Highlight);
422
+ outline-offset: var(--slotted-focus-ring-offset, 2px);
423
+ }
424
+
425
+ [data-ui='time-range-picker'][data-part='root'][data-variant='plain'][data-invalid]
426
+ [data-part='control']:has(> [data-part='trigger']:focus-visible) {
427
+ outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
428
+ var(--slotted-focus-ring-color, Highlight);
429
+ outline-offset: calc(
430
+ -1 * (var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width))
431
+ );
432
+ }
433
+ }
434
+
435
+ /* Read-only stays focusable, readable and copyable, and must not be
436
+ mistakable for disabled: the ground says "not yours to change". */
437
+ [data-ui='time-range-picker'][data-part='root'][data-readonly] [data-part='control'] {
438
+ background-color: var(
439
+ --slotted-time-range-picker-readonly-background,
440
+ var(--slotted-tone-secondary-subtle-hover)
441
+ );
442
+ cursor: default;
443
+ }
444
+
445
+ /* Muted to the colour the theme measures rather than faded by opacity. */
446
+ [data-ui='time-range-picker'][data-part='root'][data-disabled] [data-part='control'] {
447
+ background-color: var(
448
+ --slotted-time-range-picker-disabled-background,
449
+ var(--slotted-disabled-background)
450
+ );
451
+ border-color: var(
452
+ --slotted-time-range-picker-disabled-border-color,
453
+ var(--slotted-disabled-border)
454
+ );
455
+ box-shadow: none;
456
+ color: var(--slotted-time-range-picker-disabled-color, var(--slotted-disabled-foreground));
457
+ cursor: not-allowed;
458
+ }
459
+
460
+ [data-ui='time-range-picker'][data-part='root'][data-disabled]
461
+ [data-part='trigger']
462
+ > [data-ui='icon'] {
463
+ color: var(--slotted-disabled-foreground);
464
+ }
465
+
466
+ /* ── The layer ────────────────────────────────────────────────────────
467
+ *
468
+ * What `packages/core/src/positioner` writes `position`, `left` and `top`
469
+ * onto. The painted surface is one element in, as every overlay is built.
470
+ */
471
+ [data-ui='time-range-picker'][data-part='positioner'] {
472
+ /* Only the block inset: the positioner writes `left` and never `right`,
473
+ and `inset-inline-start` would resolve to `right` in a right-to-left
474
+ document and win over the measured value. */
475
+ position: absolute;
476
+ inset-block-start: 0;
477
+
478
+ box-sizing: border-box;
479
+ isolation: isolate;
480
+ pointer-events: none;
481
+ z-index: calc(var(--slotted-z-index-popover, 1100) + var(--slotted-layer-depth, 0));
482
+
483
+ /* The layer arrives along the axis it opens on and never along the inline
484
+ one, which is the rule `select` records. */
485
+ --_enter-distance: var(--slotted-space-2, 0.25rem);
486
+ opacity: 0;
487
+ translate: 0 calc(-1 * var(--_enter-distance));
488
+ transition:
489
+ opacity var(--slotted-duration-short) var(--slotted-easing-exit),
490
+ translate var(--slotted-duration-short) var(--slotted-easing-exit);
491
+ }
492
+
493
+ [data-ui='time-range-picker'][data-part='positioner'][data-side='top'] {
494
+ translate: 0 var(--_enter-distance);
495
+ }
496
+
497
+ [data-ui='time-range-picker'][data-part='positioner']:is(
498
+ [data-side='left'],
499
+ [data-side='right']
500
+ ) {
501
+ translate: 0 0;
502
+ }
503
+
504
+ [data-ui='time-range-picker'][data-part='positioner'][data-open] {
505
+ opacity: 1;
506
+ translate: 0 0;
507
+ transition: none;
508
+ }
509
+
510
+ /* The entrance is a keyframe animation and not a transition, for the reason
511
+ `select` records: only a layer the positioner placed arrives. */
512
+ [data-ui='time-range-picker'][data-part='positioner'][data-open][data-positioned] {
513
+ animation: slotted-time-range-picker-enter-down var(--slotted-duration-medium)
514
+ var(--slotted-easing-enter);
515
+ }
516
+
517
+ [data-ui='time-range-picker'][data-part='positioner'][data-open][data-positioned][data-side='top'] {
518
+ animation-name: slotted-time-range-picker-enter-up;
519
+ }
520
+
521
+ [data-ui='time-range-picker'][data-part='positioner'][data-open][data-positioned]:is(
522
+ [data-side='left'],
523
+ [data-side='right']
524
+ ) {
525
+ animation-name: slotted-time-range-picker-fade;
526
+ }
527
+
528
+ @keyframes slotted-time-range-picker-enter-down {
529
+ from {
530
+ opacity: 0;
531
+ translate: 0 calc(-1 * var(--_enter-distance));
532
+ }
533
+ }
534
+
535
+ @keyframes slotted-time-range-picker-enter-up {
536
+ from {
537
+ opacity: 0;
538
+ translate: 0 var(--_enter-distance);
539
+ }
540
+ }
541
+
542
+ @keyframes slotted-time-range-picker-fade {
543
+ from {
544
+ opacity: 0;
545
+ }
546
+ }
547
+
548
+ /* Stillness keeps the fade and drops the movement. */
549
+ @media (prefers-reduced-motion: reduce) {
550
+ [data-ui='time-range-picker'][data-part='positioner'],
551
+ [data-ui='time-range-picker'][data-part='positioner'][data-side='top'],
552
+ [data-ui='time-range-picker'][data-part='positioner'][data-side='left'],
553
+ [data-ui='time-range-picker'][data-part='positioner'][data-side='right'] {
554
+ translate: 0 0;
555
+ transition: opacity var(--slotted-duration-short) var(--slotted-easing-exit);
556
+ }
557
+
558
+ [data-ui='time-range-picker'][data-part='positioner'][data-open][data-positioned],
559
+ [data-ui='time-range-picker'][data-part='positioner'][data-open][data-positioned][data-side='top'],
560
+ [data-ui='time-range-picker'][data-part='positioner'][data-open][data-positioned][data-side='left'],
561
+ [data-ui='time-range-picker'][data-part='positioner'][data-open][data-positioned][data-side='right'] {
562
+ animation-name: slotted-time-range-picker-fade;
563
+ }
564
+ }
565
+
566
+ /* The anchor scrolled out of its own clipper. */
567
+ [data-ui='time-range-picker'][data-part='positioner'][data-detached] {
568
+ visibility: hidden;
569
+ }
570
+
571
+ /**
572
+ * The surface. One list has no intrinsic width, so the surface takes the
573
+ * anchor's, floored so a column is never too tight to read a time and its
574
+ * duration in, and capped so a wide form does not stretch one column
575
+ * across a page — the rule `time-picker` states, with a wider floor for
576
+ * the duration beside each time.
577
+ *
578
+ * The fallback is the floor rather than `auto`: the anchor width is written
579
+ * by the positioner and absent wherever the surface is drawn without one,
580
+ * and `min(auto, …)` is not a value.
581
+ */
582
+ [data-ui='time-range-picker'] [data-part='content'] {
583
+ background-color: var(
584
+ --slotted-time-range-picker-surface,
585
+ var(--slotted-surface-raised, Canvas)
586
+ );
587
+ border: var(--slotted-border-width-thin, 1px) solid
588
+ var(
589
+ --slotted-time-range-picker-content-border-color,
590
+ var(--slotted-border-subtle, ButtonBorder)
591
+ );
592
+ border-radius: var(--slotted-time-range-picker-content-radius, var(--slotted-radius-lg, 8px));
593
+ box-shadow: var(--slotted-time-range-picker-content-shadow, var(--slotted-shadow-md));
594
+ box-sizing: border-box;
595
+ color: var(--slotted-time-range-picker-content-color, var(--slotted-text, CanvasText));
596
+ /* The type of the surface follows density with the control scale, as the
597
+ calendar's does: a list at the page's size beside a grid at the
598
+ control's read as two sizes in dense. */
599
+ font-family: var(--slotted-control-font-family, system-ui, sans-serif);
600
+ font-size: var(--slotted-control-font-size-md, 13px);
601
+ /**
602
+ * One row's height, stated once, because the list's cap is counted in
603
+ * rows — eight and a half of them at every density, the arithmetic
604
+ * `time-picker` records. The pitch is the row plus the air under it.
605
+ */
606
+ --_row: max(var(--slotted-target-min, 24px), var(--slotted-control-height-sm, 30px));
607
+ --_row-pitch: calc(var(--_row) + var(--slotted-space-1, 0.125rem));
608
+
609
+ display: grid;
610
+ /* The bands breathe by the step the dialogs of the date chain use: a
611
+ surface holding a field and a list is a dialog, not a menu. */
612
+ gap: var(--slotted-space-5, 0.75rem);
613
+ grid-template-areas: 'head' 'presets' 'panel' 'footer';
614
+ grid-template-columns: minmax(0, 1fr);
615
+ inline-size: max(
616
+ var(--slotted-time-range-picker-content-min-inline-size, 16rem),
617
+ min(var(--slotted-positioner-anchor-width, 16rem), 22rem)
618
+ );
619
+ max-inline-size: var(--slotted-positioner-available-width, 100vw);
620
+ padding: var(--slotted-time-range-picker-content-padding, var(--slotted-space-5, 0.75rem));
621
+ /* The layer above gave up the pointer; the surface takes it back. */
622
+ pointer-events: auto;
623
+ }
624
+
625
+ /* ── The band ─────────────────────────────────────────────────────────
626
+ *
627
+ * Three rows: which end is being chosen, where the reader types it, and
628
+ * what to do next. It renders at the panel's width and contributes nothing
629
+ * to it, by the pair `datetime-picker` records.
630
+ */
631
+ [data-ui='time-range-picker'] [data-part='head'] {
632
+ box-sizing: border-box;
633
+ inline-size: 0;
634
+ min-inline-size: 100%;
635
+
636
+ /* A grid, so the field and now, and the hint and the length, share a
637
+ row without a wrapper the anatomy would have to name. */
638
+ column-gap: var(--slotted-space-2, 0.25rem);
639
+ display: grid;
640
+ grid-area: head;
641
+ grid-template-areas: 'tabs tabs' 'field now' 'hint length' 'limit limit';
642
+ grid-template-columns: minmax(0, 1fr) auto;
643
+ row-gap: var(--slotted-space-2, 0.25rem);
644
+ }
645
+
646
+ [data-ui='time-range-picker'] [data-part='tabs'] {
647
+ grid-area: tabs;
648
+ }
649
+
650
+ [data-ui='time-range-picker'] [data-part='field'] {
651
+ grid-area: field;
652
+ }
653
+
654
+ [data-ui='time-range-picker'] [data-part='head'] > [data-part='now'] {
655
+ align-self: center;
656
+ grid-area: now;
657
+ }
658
+
659
+ [data-ui='time-range-picker'] [data-part='hint'] {
660
+ align-self: center;
661
+ grid-area: hint;
662
+ }
663
+
664
+ [data-ui='time-range-picker'] [data-part='length'] {
665
+ align-self: center;
666
+ grid-area: length;
667
+ }
668
+
669
+ [data-ui='time-range-picker'] [data-part='limit'] {
670
+ grid-area: limit;
671
+ }
672
+
673
+ /* ── The two ends, as tabs ────────────────────────────────────────────
674
+ *
675
+ * One end at a time. Two equal halves, the label over the value; the
676
+ * current one carries the underline `date-range-picker` draws under its
677
+ * current field, in the accent, and the other reads as the step to come.
678
+ * The row is the whole width so the two are the same size whatever their
679
+ * values, and a thumb finds them without aiming.
680
+ */
681
+ [data-ui='time-range-picker'] [data-part='tabs'] {
682
+ border-block-end: var(--slotted-border-width-thin, 1px) solid
683
+ var(
684
+ --slotted-time-range-picker-content-border-color,
685
+ var(--slotted-border-subtle, ButtonBorder)
686
+ );
687
+ display: grid;
688
+ gap: var(--slotted-space-2, 0.25rem);
689
+ grid-template-columns: repeat(2, minmax(0, 1fr));
690
+ }
691
+
692
+ [data-ui='time-range-picker'] [data-part='tab'] {
693
+ appearance: none;
694
+ background-color: transparent;
695
+ border: 0;
696
+ border-start-end-radius: var(
697
+ --slotted-time-range-picker-option-radius,
698
+ var(--slotted-radius-sm, 4px)
699
+ );
700
+ border-start-start-radius: var(
701
+ --slotted-time-range-picker-option-radius,
702
+ var(--slotted-radius-sm, 4px)
703
+ );
704
+ color: var(--slotted-time-range-picker-content-color, var(--slotted-text, CanvasText));
705
+ cursor: pointer;
706
+ display: flex;
707
+ flex-direction: column;
708
+ font: inherit;
709
+ gap: var(--slotted-space-1, 0.125rem);
710
+ min-block-size: var(--slotted-time-range-picker-tab-block-size, calc(var(--_row) * 1.5));
711
+ min-inline-size: 0;
712
+ padding-block: var(--slotted-space-2, 0.25rem) var(--slotted-space-3, 0.375rem);
713
+ padding-inline: var(--slotted-space-3, 0.375rem);
714
+ position: relative;
715
+ text-align: start;
716
+ touch-action: manipulation;
717
+ transition: background-color var(--slotted-control-transition-duration)
718
+ var(--slotted-control-transition-easing);
719
+ -webkit-tap-highlight-color: transparent;
720
+ }
721
+
722
+ [data-ui='time-range-picker'] [data-part='tab']::after {
723
+ background-color: var(
724
+ --slotted-time-range-picker-current-color,
725
+ var(--slotted-tone-accent-solid)
726
+ );
727
+ block-size: var(--slotted-time-range-picker-current-size, 2px);
728
+ border-start-end-radius: var(--slotted-radius-xs, 2px);
729
+ border-start-start-radius: var(--slotted-radius-xs, 2px);
730
+ content: '';
731
+ /* Over the row's own hairline, so the current tab's mark and the rule
732
+ are one line. */
733
+ inset-block-end: calc(-1 * var(--slotted-border-width-thin, 1px));
734
+ inset-inline: 0;
735
+ opacity: 0;
736
+ position: absolute;
737
+ transition: opacity var(--slotted-control-transition-duration)
738
+ var(--slotted-control-transition-easing);
739
+ }
740
+
741
+ [data-ui='time-range-picker'] [data-part='tab'][data-current]::after {
742
+ opacity: 1;
743
+ }
744
+
745
+ [data-ui='time-range-picker'] [data-part='tab']:hover:not(:disabled):not([data-current]) {
746
+ background-color: var(
747
+ --slotted-time-range-picker-option-hover-background,
748
+ var(--slotted-tone-secondary-subtle-hover)
749
+ );
750
+ }
751
+
752
+ [data-ui='time-range-picker'] [data-part='tab']:focus-visible {
753
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
754
+ outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
755
+ }
756
+
757
+ [data-ui='time-range-picker'] [data-part='tab']:disabled {
758
+ color: var(--slotted-disabled-foreground);
759
+ cursor: not-allowed;
760
+ }
761
+
762
+ /* The label, in the muted ink for both ends alike: which end is current
763
+ is said once, by the underline. */
764
+ [data-ui='time-range-picker'] [data-part='tab-label'] {
765
+ color: var(--slotted-time-range-picker-label-color, var(--slotted-text-muted, GrayText));
766
+ font-size: var(--slotted-font-size-xs, 11px);
767
+ font-weight: var(--slotted-font-weight-medium, 500);
768
+ letter-spacing: var(--slotted-letter-spacing-wide, 0.02em);
769
+ text-transform: uppercase;
770
+ white-space: nowrap;
771
+ }
772
+
773
+ [data-ui='time-range-picker'] [data-part='tab-value'] {
774
+ font-size: var(--slotted-font-size-sm, 13px);
775
+ font-variant-numeric: tabular-nums;
776
+ font-weight: var(--slotted-font-weight-medium, 500);
777
+ overflow: hidden;
778
+ text-overflow: ellipsis;
779
+ unicode-bidi: plaintext;
780
+ white-space: nowrap;
781
+ }
782
+
783
+ [data-ui='time-range-picker'] [data-part='tab'][data-placeholder] [data-part='tab-value'] {
784
+ color: var(--slotted-time-range-picker-label-color, var(--slotted-text-muted, GrayText));
785
+ font-weight: var(--slotted-font-weight-regular, 400);
786
+ }
787
+
788
+ /* ── The field row ────────────────────────────────────────────────────
789
+ *
790
+ * The current end's field in `plain`, spoken to in the only language this
791
+ * stylesheet is allowed: the tokens the field reads. Its border, inline
792
+ * padding, hover wash, invalid edge and lift are zeroed; its own focus ring
793
+ * stays, because in the band the field is the control the reader is in.
794
+ * `now` sits at the reading end of the same row. On a coarse pointer the
795
+ * row is `now` alone: a segment is a spinbutton and raises no keyboard.
796
+ */
797
+ [data-ui='time-range-picker'] [data-part='field'] {
798
+ --slotted-control-border-width: 0px;
799
+ --slotted-control-padding-inline-sm: var(--slotted-space-2, 0.25rem);
800
+ --slotted-control-padding-inline-md: var(--slotted-space-2, 0.25rem);
801
+ --slotted-control-padding-inline-lg: var(--slotted-space-2, 0.25rem);
802
+ --slotted-time-field-plain-hover-background: transparent;
803
+ --slotted-time-field-invalid-border-color: transparent;
804
+ --slotted-time-field-shadow: none;
805
+ --slotted-control-shadow-focus-geometry: 0 0 0 0;
806
+
807
+ display: flex;
808
+ flex: 0 1 auto;
809
+ min-inline-size: 0;
810
+ }
811
+
812
+ /* ── What to do next ──────────────────────────────────────────────────
813
+ *
814
+ * The hint at the start, the duration at the reading end; the limit on a
815
+ * line of its own under them. The hint is the difference between a panel
816
+ * that refuses and a panel that explains.
817
+ */
818
+ [data-ui='time-range-picker'] [data-part='hint'] {
819
+ color: var(--slotted-time-range-picker-hint-color, var(--slotted-text-muted, GrayText));
820
+ font-size: var(--slotted-font-size-sm, 13px);
821
+ min-inline-size: 0;
822
+ padding-inline-start: var(--slotted-space-2, 0.25rem);
823
+ text-wrap: balance;
824
+ unicode-bidi: plaintext;
825
+ }
826
+
827
+ [data-ui='time-range-picker'] [data-part='hint'][data-invalid] {
828
+ color: var(--slotted-time-range-picker-invalid-color, var(--slotted-tone-danger-text));
829
+ }
830
+
831
+ /* The duration, at the reading end, in the accent's text tone: it is the
832
+ number the band exists to say. Pending, it drops a step of weight. */
833
+ [data-ui='time-range-picker'] [data-part='length'] {
834
+ color: var(--slotted-time-range-picker-length-color, var(--slotted-tone-accent-text));
835
+ font-size: var(--slotted-font-size-sm, 13px);
836
+ font-variant-numeric: tabular-nums;
837
+ font-weight: var(--slotted-font-weight-semibold, 600);
838
+ padding-inline: var(--slotted-space-4, 0.5rem) var(--slotted-space-2, 0.25rem);
839
+ unicode-bidi: plaintext;
840
+ white-space: nowrap;
841
+ }
842
+
843
+ [data-ui='time-range-picker'] [data-part='length'][data-pending] {
844
+ font-weight: var(--slotted-font-weight-medium, 500);
845
+ }
846
+
847
+ /* An empty length still holds its line, so the band does not grow a row
848
+ when the first end is chosen. */
849
+ [data-ui='time-range-picker'] [data-part='length']:empty::before {
850
+ content: '\200B';
851
+ }
852
+
853
+ [data-ui='time-range-picker'] [data-part='limit'] {
854
+ color: var(--slotted-time-range-picker-limit-color, var(--slotted-text-muted, GrayText));
855
+ font-size: var(--slotted-font-size-xs, 11px);
856
+ padding-inline-start: var(--slotted-space-2, 0.25rem);
857
+ unicode-bidi: plaintext;
858
+ }
859
+
860
+ /* ── The panel ────────────────────────────────────────────────────────
861
+ *
862
+ * The current end, one at a time: its list. `data-position` says which.
863
+ */
864
+ [data-ui='time-range-picker'] [data-part='panel'] {
865
+ display: flex;
866
+ flex-direction: column;
867
+ gap: var(--slotted-space-2, 0.25rem);
868
+ grid-area: panel;
869
+ min-inline-size: 0;
870
+ }
871
+
872
+ [data-ui='time-range-picker'] [data-part='now'] {
873
+ appearance: none;
874
+ background-color: transparent;
875
+ border: 0;
876
+ border-radius: var(--slotted-time-range-picker-option-radius, var(--slotted-radius-sm, 4px));
877
+ color: var(--slotted-time-range-picker-now-color, var(--slotted-tone-accent-text));
878
+ cursor: pointer;
879
+ flex: 0 0 auto;
880
+ font: inherit;
881
+ font-size: var(--slotted-font-size-sm, 13px);
882
+ min-block-size: var(--_row);
883
+ padding-block: var(--slotted-space-1, 0.125rem);
884
+ padding-inline: var(--slotted-space-3, 0.375rem);
885
+ touch-action: manipulation;
886
+ transition: background-color var(--slotted-control-transition-duration)
887
+ var(--slotted-control-transition-easing);
888
+ }
889
+
890
+ [data-ui='time-range-picker'] [data-part='now']:hover:not(:disabled):not([data-disabled]) {
891
+ background-color: var(
892
+ --slotted-time-range-picker-option-hover-background,
893
+ var(--slotted-tone-secondary-subtle-hover)
894
+ );
895
+ }
896
+
897
+ [data-ui='time-range-picker'] [data-part='now']:focus-visible {
898
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
899
+ outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
900
+ }
901
+
902
+ [data-ui='time-range-picker'] [data-part='now']:disabled {
903
+ color: var(--slotted-disabled-foreground);
904
+ cursor: not-allowed;
905
+ }
906
+
907
+ /* ── The shortcuts ────────────────────────────────────────────────────
908
+ *
909
+ * This family ships no list of them: "the morning shift" is a business
910
+ * clock. It ships the row they stand in and the chip each one is, between
911
+ * the band and the panel, wrapping when they do not fit.
912
+ */
913
+ [data-ui='time-range-picker'] [data-part='presets'] {
914
+ display: flex;
915
+ flex-wrap: wrap;
916
+ gap: var(--slotted-space-2, 0.25rem);
917
+ grid-area: presets;
918
+ min-inline-size: 0;
919
+ }
920
+
921
+ [data-ui='time-range-picker'] [data-part='preset'] {
922
+ appearance: none;
923
+ background-color: var(
924
+ --slotted-time-range-picker-preset-background,
925
+ var(--slotted-tone-secondary-subtle)
926
+ );
927
+ border: 0;
928
+ border-radius: var(
929
+ --slotted-time-range-picker-preset-radius,
930
+ var(--slotted-radius-pill, 999px)
931
+ );
932
+ color: var(--slotted-time-range-picker-content-color, var(--slotted-text, CanvasText));
933
+ cursor: pointer;
934
+ font-family: var(--slotted-control-font-family, system-ui, sans-serif);
935
+ font-size: var(--slotted-font-size-sm, 13px);
936
+ line-height: var(--slotted-line-height-sm, 1.4);
937
+ min-block-size: var(--_row);
938
+ padding-block: var(--slotted-space-1, 0.125rem);
939
+ padding-inline: var(--slotted-space-4, 0.5rem);
940
+ text-align: start;
941
+ touch-action: manipulation;
942
+ transition:
943
+ background-color var(--slotted-control-transition-duration)
944
+ var(--slotted-control-transition-easing),
945
+ color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
946
+ white-space: nowrap;
947
+ -webkit-tap-highlight-color: transparent;
948
+ }
949
+
950
+ [data-ui='time-range-picker'] [data-part='preset']:hover:not(:disabled):not([data-selected]) {
951
+ background-color: var(
952
+ --slotted-time-range-picker-preset-hover-background,
953
+ var(--slotted-tone-secondary-subtle-hover)
954
+ );
955
+ }
956
+
957
+ [data-ui='time-range-picker'] [data-part='preset']:active:not(:disabled):not([data-selected]) {
958
+ background-color: var(
959
+ --slotted-time-range-picker-preset-active-background,
960
+ var(--slotted-tone-secondary-subtle-active)
961
+ );
962
+ }
963
+
964
+ [data-ui='time-range-picker'] [data-part='preset'][data-selected] {
965
+ background-color: var(
966
+ --slotted-time-range-picker-preset-selected-background,
967
+ var(--slotted-tone-accent-subtle-hover)
968
+ );
969
+ color: var(--slotted-time-range-picker-preset-selected-color, var(--slotted-tone-accent-text));
970
+ font-weight: var(--slotted-font-weight-medium, 500);
971
+ }
972
+
973
+ [data-ui='time-range-picker'] [data-part='preset']:focus-visible {
974
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
975
+ outline-offset: var(--slotted-focus-ring-offset, 2px);
976
+ }
977
+
978
+ [data-ui='time-range-picker'] [data-part='preset']:disabled {
979
+ color: var(--slotted-disabled-foreground);
980
+ cursor: not-allowed;
981
+ }
982
+
983
+ /* ── The list ─────────────────────────────────────────────────────────
984
+ *
985
+ * One column of times, the current end's, capped in control heights so the
986
+ * cap holds at every density, and scrolled rather than truncated —
987
+ * `time-picker`'s list.
988
+ */
989
+ [data-ui='time-range-picker'] [data-part='list'] {
990
+ display: flex;
991
+ flex-direction: column;
992
+ /* One step of air between rows, so the chosen row's painted ground and
993
+ the focused row's inset ring never share an edge. */
994
+ gap: var(--slotted-space-1, 0.125rem);
995
+ /* Eight rows and half of the ninth: a list cut on a row boundary looks
996
+ like the whole list. */
997
+ max-block-size: var(--slotted-time-range-picker-list-block-size, calc(var(--_row-pitch) * 8.5));
998
+ min-inline-size: 0;
999
+ overflow-y: auto;
1000
+ /* A highlight moved by a key lands whole rather than half under the edge. */
1001
+ scroll-padding-block: var(--slotted-space-2, 0.25rem);
1002
+ }
1003
+
1004
+ [data-ui='time-range-picker'] [data-part='option'] {
1005
+ /* The time and its duration share a baseline, and the line box is the
1006
+ row: baseline alignment alone would seat both at the top of a row
1007
+ taller than one line, and a length line-height centres them in it. */
1008
+ align-items: baseline;
1009
+ background-color: transparent;
1010
+ border-radius: var(--slotted-time-range-picker-option-radius, var(--slotted-radius-sm, 4px));
1011
+ color: inherit;
1012
+ cursor: pointer;
1013
+ display: flex;
1014
+ flex: 0 0 auto;
1015
+ font-variant-numeric: tabular-nums;
1016
+ gap: var(--slotted-space-3, 0.375rem);
1017
+ justify-content: space-between;
1018
+ line-height: var(--_row);
1019
+ /* The row *is* `--_row`: no block padding on top of it, so eight rows are
1020
+ eight rows and the cap that counts them is arithmetic. */
1021
+ min-block-size: var(--_row);
1022
+ padding-inline: var(--slotted-space-3, 0.375rem);
1023
+ transition:
1024
+ background-color var(--slotted-control-transition-duration)
1025
+ var(--slotted-control-transition-easing),
1026
+ color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
1027
+ user-select: none;
1028
+ -webkit-tap-highlight-color: transparent;
1029
+ }
1030
+
1031
+ /**
1032
+ * The duration this option would make, beside it: "15:00 · 1 hr", the way
1033
+ * a calendar application lists the end times of an event. It is the answer
1034
+ * to the question the reader is actually asking while choosing an end, read
1035
+ * row by row rather than one option at a time from the band. In the list of
1036
+ * the other end it is the duration to the end already chosen. Muted, so the
1037
+ * time stays what the row is; on the chosen row it takes the row's own ink.
1038
+ */
1039
+ [data-ui='time-range-picker'] [data-part='option-duration'] {
1040
+ color: var(--slotted-time-range-picker-label-color, var(--slotted-text-muted, GrayText));
1041
+ flex: 0 1 auto;
1042
+ font-size: var(--slotted-font-size-xs, 11px);
1043
+ min-inline-size: 0;
1044
+ overflow: hidden;
1045
+ text-overflow: ellipsis;
1046
+ unicode-bidi: plaintext;
1047
+ white-space: nowrap;
1048
+ }
1049
+
1050
+ [data-ui='time-range-picker'] [data-part='option'][data-selected] [data-part='option-duration'],
1051
+ [data-ui='time-range-picker'] [data-part='option'][data-disabled] [data-part='option-duration'] {
1052
+ color: inherit;
1053
+ }
1054
+
1055
+ /* ── Option states ────────────────────────────────────────────────────
1056
+ *
1057
+ * Written strongest last, and each weaker one guarded against every stronger
1058
+ * one it can meet: the chosen time outranks the highlight, and the highlight
1059
+ * outranks the pointer. Specificity is what makes this a rule rather than an
1060
+ * ordering — the defect `time-picker` records from its visual gate.
1061
+ */
1062
+ [data-ui='time-range-picker']
1063
+ [data-part='option']:hover:not([data-disabled]):not([data-selected]):not([data-current]) {
1064
+ background-color: var(
1065
+ --slotted-time-range-picker-option-hover-background,
1066
+ var(--slotted-tone-secondary-subtle-hover)
1067
+ );
1068
+ }
1069
+
1070
+ [data-ui='time-range-picker'] [data-part='option'][data-current]:not([data-selected]) {
1071
+ background-color: var(
1072
+ --slotted-time-range-picker-option-current-background,
1073
+ var(--slotted-tone-secondary-subtle-active)
1074
+ );
1075
+ }
1076
+
1077
+ [data-ui='time-range-picker'] [data-part='option']:focus-visible {
1078
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
1079
+ outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
1080
+ }
1081
+
1082
+ [data-ui='time-range-picker'] [data-part='option'][data-selected] {
1083
+ background-color: var(
1084
+ --slotted-time-range-picker-option-selected-background,
1085
+ var(--slotted-tone-accent-solid)
1086
+ );
1087
+ color: var(
1088
+ --slotted-time-range-picker-option-selected-color,
1089
+ var(--slotted-tone-accent-on-solid)
1090
+ );
1091
+ }
1092
+
1093
+ /* The chosen row still answers the pointer, one step along its own tone. */
1094
+ [data-ui='time-range-picker'] [data-part='option'][data-selected]:hover:not([data-disabled]) {
1095
+ background-color: var(
1096
+ --slotted-time-range-picker-option-selected-hover-background,
1097
+ var(--slotted-tone-accent-solid-hover)
1098
+ );
1099
+ }
1100
+
1101
+ /**
1102
+ * A time a bound, the predicate or the other end refuses. It stays in the
1103
+ * list by default, because a list that silently drops rows is a list whose
1104
+ * step the reader cannot infer — and it is muted to the colour the theme
1105
+ * measures rather than faded by opacity, so it stays readable.
1106
+ */
1107
+ [data-ui='time-range-picker'] [data-part='option'][data-disabled] {
1108
+ background-color: transparent;
1109
+ color: var(--slotted-disabled-foreground);
1110
+ cursor: not-allowed;
1111
+ }
1112
+
1113
+ /* Nothing available for this end at all. A sentence rather than an empty
1114
+ box, the reason `time-picker` records. */
1115
+ [data-ui='time-range-picker'] [data-part='empty'] {
1116
+ align-items: center;
1117
+ color: var(--slotted-time-range-picker-label-color, var(--slotted-text-muted, GrayText));
1118
+ display: flex;
1119
+ font-size: var(--slotted-font-size-sm, 13px);
1120
+ justify-content: center;
1121
+ min-block-size: calc(var(--_row) * 2);
1122
+ padding: var(--slotted-space-4, 0.5rem);
1123
+ text-align: center;
1124
+ text-wrap: balance;
1125
+ /* A sentence laid out by its own first strong character, so a full stop
1126
+ does not lead it in a right-to-left document. */
1127
+ unicode-bidi: plaintext;
1128
+ }
1129
+
1130
+ /* The consumer's own actions and, at the reading end, `done`: the way out
1131
+ of a sheet that fills the screen and of an edit left half way. */
1132
+ [data-ui='time-range-picker'] [data-part='footer'] {
1133
+ box-sizing: border-box;
1134
+ inline-size: 0;
1135
+ min-inline-size: 100%;
1136
+
1137
+ align-items: center;
1138
+ border-block-start: var(--slotted-border-width-thin, 1px) solid
1139
+ var(
1140
+ --slotted-time-range-picker-content-border-color,
1141
+ var(--slotted-border-subtle, ButtonBorder)
1142
+ );
1143
+ display: flex;
1144
+ gap: var(--slotted-space-2, 0.25rem);
1145
+ grid-area: footer;
1146
+ justify-content: flex-end;
1147
+ padding-block-start: var(--slotted-space-3, 0.375rem);
1148
+ }
1149
+
1150
+ [data-ui='time-range-picker'] [data-part='done'] {
1151
+ appearance: none;
1152
+ background-color: var(
1153
+ --slotted-time-range-picker-done-background,
1154
+ var(--slotted-tone-accent-solid)
1155
+ );
1156
+ border: 0;
1157
+ border-radius: var(--slotted-time-range-picker-radius, var(--slotted-control-radius, 4px));
1158
+ color: var(--slotted-time-range-picker-done-color, var(--slotted-tone-accent-on-solid, Canvas));
1159
+ cursor: pointer;
1160
+ font-family: var(--slotted-control-font-family, system-ui, sans-serif);
1161
+ font-size: var(--slotted-font-size-sm, 13px);
1162
+ font-weight: var(--slotted-font-weight-medium, 500);
1163
+ line-height: var(--slotted-line-height-sm, 1.4);
1164
+ margin-inline-start: auto;
1165
+ min-block-size: var(--_row);
1166
+ padding-block: var(--slotted-space-1, 0.125rem);
1167
+ padding-inline: var(--slotted-space-5, 0.75rem);
1168
+ touch-action: manipulation;
1169
+ transition: background-color var(--slotted-control-transition-duration)
1170
+ var(--slotted-control-transition-easing);
1171
+ -webkit-tap-highlight-color: transparent;
1172
+ }
1173
+
1174
+ [data-ui='time-range-picker'] [data-part='done']:hover:not(:disabled) {
1175
+ background-color: var(
1176
+ --slotted-time-range-picker-done-hover-background,
1177
+ var(--slotted-tone-accent-solid-hover)
1178
+ );
1179
+ }
1180
+
1181
+ [data-ui='time-range-picker'] [data-part='done']:active:not(:disabled) {
1182
+ background-color: var(
1183
+ --slotted-time-range-picker-done-active-background,
1184
+ var(--slotted-tone-accent-solid-active)
1185
+ );
1186
+ }
1187
+
1188
+ [data-ui='time-range-picker'] [data-part='done']:focus-visible {
1189
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
1190
+ outline-offset: var(--slotted-focus-ring-offset, 2px);
1191
+ }
1192
+
1193
+ /* ── On a finger ──────────────────────────────────────────────────────
1194
+ *
1195
+ * The row is the touch target: the theme raises the control heights to
1196
+ * `--slotted-target-comfortable` under a coarse pointer, and the row is
1197
+ * counted in them. The field is not drawn — a segment is a spinbutton and
1198
+ * raises no keyboard — and the list is the way to a time.
1199
+ */
1200
+ @media (pointer: coarse) {
1201
+ [data-ui='time-range-picker'] [data-part='field'] {
1202
+ display: none;
1203
+ }
1204
+ }
1205
+
1206
+ /* ── Narrow, on a finger ──────────────────────────────────────────────
1207
+ *
1208
+ * §2.7 of `docs/component-features.md` asks for it by name: a popover on the
1209
+ * desktop and a sheet in a narrow viewport. The DOM does not change.
1210
+ */
1211
+ @media (max-width: 480px) and (pointer: coarse) {
1212
+ [data-ui='time-range-picker'][data-part='positioner'][data-presentation='sheet'] {
1213
+ inset: auto 0 0;
1214
+ position: fixed;
1215
+ translate: 0 var(--slotted-space-9, 2rem);
1216
+ }
1217
+
1218
+ [data-ui='time-range-picker'][data-part='positioner'][data-presentation='sheet'][data-open] {
1219
+ translate: 0 0;
1220
+ }
1221
+
1222
+ [data-ui='time-range-picker'][data-part='positioner'][data-presentation='sheet']
1223
+ [data-part='content'] {
1224
+ border-end-end-radius: 0;
1225
+ border-end-start-radius: 0;
1226
+ border-inline: 0;
1227
+ border-block-end: 0;
1228
+ inline-size: var(--slotted-time-range-picker-sheet-inline-size, 100%);
1229
+ max-inline-size: none;
1230
+ /* A sheet taller than the screen — a grid and a list on a short phone,
1231
+ a list on a phone held sideways — scrolls as one, so the tabs stay
1232
+ reachable rather than above the top edge. `dvh` follows the
1233
+ browser's own bars; `vh` is the fallback. */
1234
+ max-block-size: 100vh;
1235
+ max-block-size: 100dvh;
1236
+ overflow-y: auto;
1237
+ overscroll-behavior: contain;
1238
+ padding-block-end: max(
1239
+ var(--slotted-time-range-picker-content-padding, var(--slotted-space-5, 0.75rem)),
1240
+ env(safe-area-inset-bottom, 0px)
1241
+ );
1242
+ }
1243
+
1244
+ /* Six rows and a half on a phone, at the touch height: the sheet stays
1245
+ under two thirds of the screen and done stays reachable. */
1246
+ [data-ui='time-range-picker'][data-part='positioner'][data-presentation='sheet']
1247
+ [data-part='list'] {
1248
+ max-block-size: calc(var(--_row-pitch) * 6.5);
1249
+ }
1250
+
1251
+ [data-ui='time-range-picker'][data-part='positioner'][data-presentation='sheet']
1252
+ [data-part='tab'] {
1253
+ min-block-size: var(
1254
+ --slotted-time-range-picker-tab-block-size,
1255
+ var(--slotted-target-comfortable, 44px)
1256
+ );
1257
+ }
1258
+ }
1259
+
1260
+ @media (forced-colors: active) {
1261
+ [data-ui='time-range-picker'][data-part='root'][data-variant='plain'] [data-part='control'] {
1262
+ border-color: ButtonBorder;
1263
+ }
1264
+
1265
+ /* The tab's underline is painted with a background, and forced colours
1266
+ replace a background that is not one of the system's own. */
1267
+ [data-ui='time-range-picker'] [data-part='tab']::after {
1268
+ forced-color-adjust: none;
1269
+ }
1270
+
1271
+ [data-ui='time-range-picker'] [data-part='tab']::after {
1272
+ background-color: currentcolor;
1273
+ }
1274
+
1275
+ [data-ui='time-range-picker'] [data-part='preset'][data-selected],
1276
+ [data-ui='time-range-picker'] [data-part='option'][data-selected] {
1277
+ background-color: Highlight;
1278
+ color: HighlightText;
1279
+ forced-color-adjust: none;
1280
+ }
1281
+
1282
+ [data-ui='time-range-picker'] [data-part='option'][data-current]:not([data-selected]) {
1283
+ outline: var(--slotted-focus-ring-width, 2px) solid Highlight;
1284
+ outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
1285
+ }
1286
+ }
1287
+ }