@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,69 @@
1
+ [
2
+ "--slotted-border-strong",
3
+ "--slotted-border-subtle",
4
+ "--slotted-border-width-thin",
5
+ "--slotted-control-font-family",
6
+ "--slotted-control-font-size-md",
7
+ "--slotted-control-gap-md",
8
+ "--slotted-control-height-md",
9
+ "--slotted-control-icon-size-md",
10
+ "--slotted-control-padding-inline-md",
11
+ "--slotted-control-transition-duration",
12
+ "--slotted-control-transition-easing",
13
+ "--slotted-disabled-foreground",
14
+ "--slotted-duration-short",
15
+ "--slotted-easing-standard",
16
+ "--slotted-focus-ring-color",
17
+ "--slotted-focus-ring-offset",
18
+ "--slotted-focus-ring-width",
19
+ "--slotted-font-size-xs",
20
+ "--slotted-font-weight-medium",
21
+ "--slotted-font-weight-regular",
22
+ "--slotted-font-weight-semibold",
23
+ "--slotted-ground",
24
+ "--slotted-line-height-md",
25
+ "--slotted-radius-md",
26
+ "--slotted-radius-sm",
27
+ "--slotted-shadow-xs",
28
+ "--slotted-space-2",
29
+ "--slotted-space-5",
30
+ "--slotted-space-9",
31
+ "--slotted-surface",
32
+ "--slotted-table-border-color",
33
+ "--slotted-table-border-color-strong",
34
+ "--slotted-table-border-width",
35
+ "--slotted-table-cell-padding-block",
36
+ "--slotted-table-cell-padding-inline",
37
+ "--slotted-table-color",
38
+ "--slotted-table-color-muted",
39
+ "--slotted-table-column-actions-size",
40
+ "--slotted-table-control-radius",
41
+ "--slotted-table-font-family",
42
+ "--slotted-table-font-size",
43
+ "--slotted-table-gap",
44
+ "--slotted-table-header-surface",
45
+ "--slotted-table-header-surface-hover",
46
+ "--slotted-table-icon-size",
47
+ "--slotted-table-radius",
48
+ "--slotted-table-row-color-selected",
49
+ "--slotted-table-row-min-block-size",
50
+ "--slotted-table-row-surface-hover",
51
+ "--slotted-table-row-surface-selected",
52
+ "--slotted-table-row-surface-selected-hover",
53
+ "--slotted-table-row-surface-stripe",
54
+ "--slotted-table-selection-size",
55
+ "--slotted-table-shadow",
56
+ "--slotted-table-sticky-inset",
57
+ "--slotted-table-sticky-offset",
58
+ "--slotted-table-sticky-offset-end",
59
+ "--slotted-table-surface",
60
+ "--slotted-target-comfortable",
61
+ "--slotted-target-min",
62
+ "--slotted-text",
63
+ "--slotted-text-muted",
64
+ "--slotted-tone-accent-subtle-hover",
65
+ "--slotted-tone-accent-surface",
66
+ "--slotted-tone-accent-text",
67
+ "--slotted-tone-secondary-subtle-hover",
68
+ "--slotted-z-index-sticky"
69
+ ]
@@ -0,0 +1,533 @@
1
+ @layer slotted.components {
2
+ /**
3
+ * A list of links into the document the reader is in, with the link of the
4
+ * place in view marked. It is text and a rule: no fill on a row, no frame
5
+ * on the list. What it borrows from the control scale is the row's height,
6
+ * inset and type, so a column of links beside a page reads at the weight of
7
+ * the page's own controls.
8
+ *
9
+ * Three layouts, one anatomy. `vertical` is the column — the track on the
10
+ * list's start edge, the marker sliding along it. `horizontal` is the bar
11
+ * that sits in `page-header`'s tabs slot — the track under the bar, the
12
+ * marker sliding under the current link. `collapsed` is a trigger with the
13
+ * current label that opens the list in a layer under it.
14
+ *
15
+ * root ▸ label
16
+ * ▸ trigger ▸ label · current · indicator (collapsed)
17
+ * ▸ panel ▸ marker
18
+ * ▸ list ▸ item ▸ link
19
+ * ▸ group ▸ item ▸ link …
20
+ * ▸ skeleton (loading)
21
+ *
22
+ * Two inks carry the list. `--_text` is the muted step every link rests in
23
+ * and `--_current` is the accent text step the current link is set in;
24
+ * hover mixes the first toward the page's own text colour, which is the rule
25
+ * `link` and `breadcrumb` arrived at for a line of text.
26
+ */
27
+ [data-ui='table-of-contents'] {
28
+ --_text: var(--slotted-table-of-contents-color, var(--slotted-text-muted, GrayText));
29
+ --_strong: var(--slotted-text, CanvasText);
30
+ --_hover: var(
31
+ --slotted-table-of-contents-color-hover,
32
+ color-mix(in oklab, var(--_text) 30%, var(--_strong))
33
+ );
34
+ --_current: var(
35
+ --slotted-table-of-contents-color-current,
36
+ var(--slotted-tone-accent-text, LinkText)
37
+ );
38
+ --_track: var(--slotted-table-of-contents-track-color, var(--slotted-border-subtle, GrayText));
39
+ --_track-width: var(
40
+ --slotted-table-of-contents-track-width,
41
+ var(--slotted-border-width-medium, 2px)
42
+ );
43
+ --_marker: var(
44
+ --slotted-table-of-contents-marker-color,
45
+ var(--slotted-tone-accent-solid, Highlight)
46
+ );
47
+ --_indent: var(--slotted-table-of-contents-indent, var(--slotted-space-5, 0.75rem));
48
+ --_line-height: var(--slotted-line-height-sm, 1.45);
49
+ --_duration: var(--slotted-duration-medium);
50
+ --_easing: var(--slotted-easing-standard, ease);
51
+
52
+ color: var(--_text);
53
+ display: block;
54
+ font-family: var(--slotted-font-family-sans, inherit);
55
+ font-size: var(--_font-size);
56
+ line-height: var(--_line-height);
57
+ /* A column beside a page: the page's measure is the page's, and the column has none of its own. */
58
+ min-inline-size: 0;
59
+ }
60
+
61
+ /* ── Size ───────────────────────────────────────────────────────────────
62
+ *
63
+ * The row is the control's height at the family's step, and the type and
64
+ * the inset are the control's own, so a row at `sm` is the row `button`
65
+ * draws at `sm`. The row's height is met with padding rather than with a
66
+ * fixed height, because a label wraps.
67
+ */
68
+
69
+ [data-ui='table-of-contents'][data-size='sm'] {
70
+ --_row-height: var(--slotted-control-height-sm, 30px);
71
+ --_font-size: var(--slotted-control-font-size-sm, 12px);
72
+ --_inset: var(--slotted-control-padding-inline-sm, 10px);
73
+ --_icon-size: var(--slotted-control-icon-size-sm, 14px);
74
+ --_gap: var(--slotted-control-gap-sm, 6px);
75
+ }
76
+
77
+ [data-ui='table-of-contents'][data-size='md'] {
78
+ --_row-height: var(--slotted-control-height-md, 34px);
79
+ --_font-size: var(--slotted-control-font-size-md, 13px);
80
+ --_inset: var(--slotted-control-padding-inline-md, 13px);
81
+ --_icon-size: var(--slotted-control-icon-size-md, 16px);
82
+ --_gap: var(--slotted-control-gap-md, 8px);
83
+ }
84
+
85
+ [data-ui='table-of-contents'][data-size='lg'] {
86
+ --_row-height: var(--slotted-control-height-lg, 38px);
87
+ --_font-size: var(--slotted-control-font-size-lg, 14px);
88
+ --_inset: var(--slotted-control-padding-inline-lg, 16px);
89
+ --_icon-size: var(--slotted-control-icon-size-lg, 18px);
90
+ --_gap: var(--slotted-control-gap-lg, 8px);
91
+ }
92
+
93
+ /** A list with no entries draws nothing: a title over an empty column is a broken column. */
94
+ [data-ui='table-of-contents'][data-empty]:not([data-loading]) {
95
+ display: none;
96
+ }
97
+
98
+ /* ── The label ──────────────────────────────────────────────────────────
99
+ *
100
+ * The list's title, set in the page's own text colour and one step of
101
+ * weight above the links, so the column reads as a titled list and not as a
102
+ * link that happens to be bold. It stands on the same inset as the links.
103
+ */
104
+
105
+ [data-ui='table-of-contents'] > [data-part='label'] {
106
+ color: var(--_strong);
107
+ font-size: var(--slotted-font-size-sm, 0.8125rem);
108
+ font-weight: var(--slotted-font-weight-semibold, 600);
109
+ line-height: var(--slotted-line-height-sm, 1.45);
110
+ margin-block-end: var(--slotted-space-3, 0.375rem);
111
+ padding-inline: var(--_inset);
112
+ }
113
+
114
+ /* ── The list ─────────────────────────────────────────────────────────── */
115
+
116
+ [data-ui='table-of-contents'] [data-part='panel'] {
117
+ position: relative;
118
+ }
119
+
120
+ [data-ui='table-of-contents'] :is([data-part='list'], [data-part='group']) {
121
+ list-style: none;
122
+ margin: 0;
123
+ padding: 0;
124
+ }
125
+
126
+ /**
127
+ * The track: a rule the whole list stands beside, on the edge facing the
128
+ * text. It is drawn once, on the first level, so the groups inside indent
129
+ * under it rather than each carrying a rule of their own.
130
+ */
131
+ [data-ui='table-of-contents'][data-layout='vertical'] [data-part='panel'] > [data-part='list'] {
132
+ border-inline-start: var(--_track-width) solid var(--_track);
133
+ }
134
+
135
+ [data-ui='table-of-contents'] [data-part='group'] {
136
+ padding-inline-start: var(--_indent);
137
+ }
138
+
139
+ [data-ui='table-of-contents'] [data-part='item'] {
140
+ /* An item is a block in a list; the marker beside the list is the panel's, not the item's. */
141
+ display: block;
142
+ min-inline-size: 0;
143
+ }
144
+
145
+ /* ── The link ─────────────────────────────────────────────────────────── */
146
+
147
+ [data-ui='table-of-contents'] [data-part='link'] {
148
+ border-radius: var(--slotted-control-radius, 4px);
149
+ color: inherit;
150
+ display: block;
151
+ /**
152
+ * A label wraps rather than truncating: a heading translated into a longer
153
+ * language is read whole in a 220-pixel column, which is what Docusaurus
154
+ * and Starlight do and what `docs/build-briefing.md` asks of every
155
+ * truncation — nothing leaves the DOM. An unbroken token breaks inside
156
+ * itself rather than widening the column.
157
+ */
158
+ overflow-wrap: anywhere;
159
+ /* The row's height, met with padding so a second line adds to it rather than overflowing it. */
160
+ padding-block: calc((var(--_row-height) - var(--_font-size) * var(--_line-height)) / 2);
161
+ padding-inline: var(--_inset);
162
+ text-decoration: none;
163
+ transition:
164
+ color var(--slotted-duration-short) var(--_easing),
165
+ font-weight var(--slotted-duration-short) var(--_easing);
166
+ }
167
+
168
+ [data-ui='table-of-contents'] [data-part='link']:not([data-disabled]):not([data-current]):hover {
169
+ color: var(--_hover);
170
+ }
171
+
172
+ [data-ui='table-of-contents'] [data-part='link']:not([data-disabled]):not([data-current]):active {
173
+ color: var(--_strong);
174
+ }
175
+
176
+ /**
177
+ * The current link is said by its ink and its weight, and the marker beside
178
+ * the list says it a second time; neither says it alone, which is what
179
+ * `state-rail.test.mjs` asks of a band on an edge.
180
+ */
181
+ [data-ui='table-of-contents'] [data-part='link'][data-current] {
182
+ color: var(--_current);
183
+ font-weight: var(--slotted-font-weight-medium, 500);
184
+ }
185
+
186
+ /**
187
+ * The ring is drawn inside the row, as every row in a list of this library
188
+ * draws it: an outward ring on a row against the track would cross the
189
+ * track, and against the column's edge would be clipped by the panel that
190
+ * scrolls.
191
+ */
192
+ [data-ui='table-of-contents'] :is([data-part='link'], [data-part='trigger']):focus-visible {
193
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
194
+ outline-offset: calc(-1 * var(--slotted-focus-ring-offset, 2px));
195
+ }
196
+
197
+ /* ── The marker ───────────────────────────────────────────────────────────
198
+ *
199
+ * One segment that travels along the track to the current link, the way
200
+ * Ant's ink does: the binding measures the current link against the panel
201
+ * and writes where it starts and how long it is. It lives in the panel and
202
+ * not in the list, because an `ol` holds only `li`, and it is positioned
203
+ * against the panel's content so it scrolls with the links when the panel
204
+ * scrolls. Absent a current link it has no size, so the track stands alone.
205
+ *
206
+ * It is pulled over the track by the track's own width, so the two lines
207
+ * are one line — the arithmetic `tabs` uses for the same pair.
208
+ */
209
+ [data-ui='table-of-contents'] [data-part='marker'] {
210
+ background-color: var(--_marker);
211
+ border-radius: var(--slotted-radius-full, 9999px);
212
+ pointer-events: none;
213
+ position: absolute;
214
+ transition:
215
+ inset-block-start var(--_duration) var(--_easing),
216
+ inset-inline-start var(--_duration) var(--_easing),
217
+ block-size var(--_duration) var(--_easing),
218
+ inline-size var(--_duration) var(--_easing);
219
+ }
220
+
221
+ [data-ui='table-of-contents'][data-layout='vertical'] [data-part='marker'] {
222
+ block-size: var(--_marker-size, 0px);
223
+ inline-size: var(--_track-width);
224
+ inset-block-start: var(--_marker-start, 0px);
225
+ inset-inline-start: 0;
226
+ }
227
+
228
+ /* ── Numbered ───────────────────────────────────────────────────────────
229
+ *
230
+ * Counters per level — `1.`, `1.2`, `1.2.3` — for a contract, a policy or
231
+ * a procedure whose clauses are numbered. The number is text in tabular
232
+ * figures, muted like the link it precedes, and it takes the link's ink
233
+ * when the link is current.
234
+ */
235
+ [data-ui='table-of-contents'][data-numbered] :is([data-part='list'], [data-part='group']) {
236
+ counter-reset: slotted-table-of-contents;
237
+ }
238
+
239
+ [data-ui='table-of-contents'][data-numbered] [data-part='item'] {
240
+ counter-increment: slotted-table-of-contents;
241
+ }
242
+
243
+ [data-ui='table-of-contents'][data-numbered] [data-part='link']::before {
244
+ content: counters(slotted-table-of-contents, '.') '.';
245
+ display: inline-block;
246
+ font-variant-numeric: tabular-nums;
247
+ margin-inline-end: var(--_gap);
248
+ }
249
+
250
+ /* ── Sticky ───────────────────────────────────────────────────────────────
251
+ *
252
+ * The column pins under the page's chrome and takes the rest of the
253
+ * viewport; the panel scrolls, the label stays. `100dvh` because a phone's
254
+ * toolbar comes and goes; the panel's own scrollbar is hidden, because a
255
+ * column of a dozen links with a scrollbar beside it reads as a control.
256
+ */
257
+ [data-ui='table-of-contents'][data-sticky] {
258
+ display: flex;
259
+ flex-direction: column;
260
+ inset-block-start: var(--slotted-page-sticky-top, 0px);
261
+ max-block-size: calc(100dvh - var(--slotted-page-sticky-top, 0px));
262
+ position: sticky;
263
+ }
264
+
265
+ [data-ui='table-of-contents'][data-sticky] > [data-part='panel'] {
266
+ min-block-size: 0;
267
+ overflow-y: auto;
268
+ overscroll-behavior: contain;
269
+ scrollbar-width: none;
270
+ }
271
+
272
+ /* ── Horizontal ───────────────────────────────────────────────────────────
273
+ *
274
+ * The bar under a page's title. One line that scrolls inline rather than
275
+ * compressing its labels — `tabs`' rule for a row of words — with the track
276
+ * under it and the marker under the current link. Groups are not shown:
277
+ * Ant's horizontal Anchor takes no children, and a bar with two levels is
278
+ * two bars.
279
+ */
280
+ [data-ui='table-of-contents'][data-layout='horizontal'] {
281
+ display: flex;
282
+ gap: var(--_gap);
283
+ }
284
+
285
+ [data-ui='table-of-contents'][data-layout='horizontal'] > [data-part='label'] {
286
+ align-self: center;
287
+ flex: none;
288
+ margin-block-end: 0;
289
+ padding-inline-end: 0;
290
+ white-space: nowrap;
291
+ }
292
+
293
+ /**
294
+ * The track is painted as the panel's own background, not as its border:
295
+ * the panel is a scroll container, and a scroll container clips on both
296
+ * axes, so a marker hung over a border would be cut off. The background
297
+ * stays put while the links scroll — a background's default attachment —
298
+ * and the panel keeps the track's height under its content so the marker,
299
+ * absolutely positioned at the panel's end edge, sits on the track and
300
+ * scrolls with the link it marks.
301
+ */
302
+ [data-ui='table-of-contents'][data-layout='horizontal'] > [data-part='panel'] {
303
+ --_fade: var(--slotted-space-9, 2rem);
304
+ --_fade-angle: 90deg;
305
+
306
+ background: linear-gradient(var(--_track), var(--_track)) 0 100% / 100% var(--_track-width)
307
+ no-repeat;
308
+ display: flex;
309
+ flex: 1 1 auto;
310
+ min-inline-size: 0;
311
+ overflow-x: auto;
312
+ overscroll-behavior-inline: contain;
313
+ padding-block-end: var(--_track-width);
314
+ scrollbar-width: none;
315
+ }
316
+
317
+ /**
318
+ * A bar with more links than room says so at the edge they continue past:
319
+ * the binding measures the panel and writes `data-overflow` as `start`,
320
+ * `end` or `both`, and the panel fades over one large step of space on that
321
+ * side. The track fades with the links, which is the hint — a rule that
322
+ * ends is a bar that ends. The gradient's angle is the one physical value
323
+ * here, mirrored by hand under `:dir(rtl)`, because a gradient angle takes
324
+ * no logical keyword.
325
+ */
326
+ [data-ui='table-of-contents'][data-layout='horizontal'] > [data-part='panel']:dir(rtl) {
327
+ --_fade-angle: 270deg;
328
+ }
329
+
330
+ [data-ui='table-of-contents'][data-layout='horizontal']
331
+ > [data-part='panel'][data-overflow='end'] {
332
+ mask-image: linear-gradient(var(--_fade-angle), #000 calc(100% - var(--_fade)), transparent);
333
+ }
334
+
335
+ [data-ui='table-of-contents'][data-layout='horizontal']
336
+ > [data-part='panel'][data-overflow='start'] {
337
+ mask-image: linear-gradient(var(--_fade-angle), transparent, #000 var(--_fade));
338
+ }
339
+
340
+ [data-ui='table-of-contents'][data-layout='horizontal']
341
+ > [data-part='panel'][data-overflow='both'] {
342
+ mask-image: linear-gradient(
343
+ var(--_fade-angle),
344
+ transparent,
345
+ #000 var(--_fade),
346
+ #000 calc(100% - var(--_fade)),
347
+ transparent
348
+ );
349
+ }
350
+
351
+ [data-ui='table-of-contents'][data-layout='horizontal'] [data-part='list'] {
352
+ display: flex;
353
+ }
354
+
355
+ [data-ui='table-of-contents'][data-layout='horizontal'] [data-part='item'] {
356
+ flex: none;
357
+ }
358
+
359
+ [data-ui='table-of-contents'][data-layout='horizontal'] [data-part='link'] {
360
+ white-space: nowrap;
361
+ }
362
+
363
+ [data-ui='table-of-contents'][data-layout='horizontal'] [data-part='group'] {
364
+ display: none;
365
+ }
366
+
367
+ [data-ui='table-of-contents'][data-layout='horizontal'] [data-part='marker'] {
368
+ block-size: var(--_track-width);
369
+ inline-size: var(--_marker-size, 0px);
370
+ inset-block-end: 0;
371
+ inset-inline-start: var(--_marker-start, 0px);
372
+ }
373
+
374
+ /* ── Collapsed ────────────────────────────────────────────────────────────
375
+ *
376
+ * A phone's bar: a button the width of its column showing the list's title
377
+ * and the current label, with the list in a layer under it. The layer is in
378
+ * flow — anchored under the trigger by position alone, with no portal and
379
+ * no positioner, because it opens exactly one place — and it is a
380
+ * dismissable layer for Escape and a press outside.
381
+ */
382
+ [data-ui='table-of-contents'][data-layout='collapsed'] {
383
+ position: relative;
384
+ }
385
+
386
+ [data-ui='table-of-contents'] [data-part='trigger'] {
387
+ align-items: center;
388
+ appearance: none;
389
+ background: none;
390
+ border: 0;
391
+ border-block-end: var(--_track-width) solid var(--_track);
392
+ border-radius: 0;
393
+ color: var(--_strong);
394
+ cursor: pointer;
395
+ display: flex;
396
+ font: inherit;
397
+ gap: var(--_gap);
398
+ inline-size: 100%;
399
+ margin: 0;
400
+ min-block-size: var(--_row-height);
401
+ padding-block: 0;
402
+ padding-inline: var(--_inset);
403
+ text-align: start;
404
+ }
405
+
406
+ [data-ui='table-of-contents'] [data-part='trigger'] > [data-part='label'] {
407
+ color: var(--_strong);
408
+ flex: none;
409
+ font-weight: var(--slotted-font-weight-semibold, 600);
410
+ }
411
+
412
+ /**
413
+ * The current label: the one line a reader on a phone has, so it takes the
414
+ * room the title leaves and is cut at the end when it is longer. The whole
415
+ * text stays in the DOM and in the list below.
416
+ */
417
+ [data-ui='table-of-contents'] [data-part='current'] {
418
+ color: var(--_text);
419
+ flex: 1 1 auto;
420
+ min-inline-size: 0;
421
+ overflow: hidden;
422
+ text-overflow: ellipsis;
423
+ white-space: nowrap;
424
+ }
425
+
426
+ [data-ui='table-of-contents'] [data-part='current']:empty {
427
+ display: none;
428
+ }
429
+
430
+ /**
431
+ * The chevron is the `chevron-down` Glyph element in an `icon` box, which the
432
+ * part sizes to the glyph scale and pushes to the end of the trigger. The box
433
+ * turns half a turn while the panel is open.
434
+ */
435
+ [data-ui='table-of-contents'] [data-part='indicator'] {
436
+ --slotted-icon-size: var(--_icon-size);
437
+
438
+ display: flex;
439
+ flex: none;
440
+ margin-inline-start: auto;
441
+ }
442
+
443
+ [data-ui='table-of-contents'] [data-part='indicator'] > [data-ui='icon'] {
444
+ transition: rotate var(--_duration) var(--_easing);
445
+ }
446
+
447
+ [data-ui='table-of-contents'][data-open] [data-part='indicator'] > [data-ui='icon'] {
448
+ rotate: 180deg;
449
+ }
450
+
451
+ [data-ui='table-of-contents'][data-layout='collapsed'] > [data-part='panel'] {
452
+ --_enter-distance: var(--slotted-space-2, 0.25rem);
453
+
454
+ background-color: var(--slotted-surface-raised, Canvas);
455
+ border: var(--slotted-border-width-thin, 1px) solid var(--slotted-border-subtle, GrayText);
456
+ border-radius: var(--slotted-radius-md, 6px);
457
+ box-shadow: var(--slotted-shadow-md, none);
458
+ display: none;
459
+ inset-block-start: 100%;
460
+ inset-inline: 0;
461
+ margin-block-start: var(--slotted-space-2, 0.25rem);
462
+ max-block-size: min(60dvh, 24rem);
463
+ overflow-y: auto;
464
+ overscroll-behavior: contain;
465
+ padding-block: var(--slotted-space-2, 0.25rem);
466
+ position: absolute;
467
+ z-index: var(--slotted-z-index-popover, 1100);
468
+ }
469
+
470
+ [data-ui='table-of-contents'][data-layout='collapsed'][data-open] > [data-part='panel'] {
471
+ animation: slotted-table-of-contents-enter var(--slotted-duration-short)
472
+ var(--slotted-easing-enter, ease-out);
473
+ display: block;
474
+ }
475
+
476
+ /* The layer under the trigger has no track: the layer's own edge frames the list. */
477
+ [data-ui='table-of-contents'][data-layout='collapsed'] [data-part='marker'] {
478
+ display: none;
479
+ }
480
+
481
+ /** The layer arrives along the axis it opens on, R7 of `overlay-motion.test.mjs`. */
482
+ @keyframes slotted-table-of-contents-enter {
483
+ from {
484
+ opacity: 0;
485
+ translate: 0 calc(-1 * var(--_enter-distance));
486
+ }
487
+ }
488
+
489
+ @media (prefers-reduced-motion: reduce) {
490
+ @keyframes slotted-table-of-contents-enter {
491
+ from {
492
+ opacity: 0;
493
+ }
494
+ }
495
+ }
496
+
497
+ /* ── Loading ────────────────────────────────────────────────────────────
498
+ *
499
+ * Rows with an item's geometry whose text is `skeleton`'s bar, so a column
500
+ * whose body is still arriving keeps its width and its rhythm.
501
+ */
502
+ [data-ui='table-of-contents'] [data-part='skeleton'] {
503
+ display: flex;
504
+ min-block-size: var(--_row-height);
505
+ padding-block: calc((var(--_row-height) - var(--_font-size) * var(--_line-height)) / 2);
506
+ padding-inline: var(--_inset);
507
+ }
508
+
509
+ [data-ui='table-of-contents'] [data-part='skeleton'] > [data-ui='skeleton'] {
510
+ --slotted-skeleton-block-size: var(--_font-size);
511
+ }
512
+
513
+ [data-ui='table-of-contents'][data-layout='horizontal'] [data-part='skeleton'] {
514
+ flex: none;
515
+ inline-size: 6rem;
516
+ }
517
+
518
+ /* ── Forced colours ───────────────────────────────────────────────────── */
519
+
520
+ @media (forced-colors: active) {
521
+ /* A painted background is the one thing the mode throws away: the marker is redrawn in the system's highlight. */
522
+ [data-ui='table-of-contents'] [data-part='marker'] {
523
+ background-color: Highlight;
524
+ forced-color-adjust: none;
525
+ }
526
+
527
+ [data-ui='table-of-contents'] [data-part='link'][data-current] {
528
+ background-color: Highlight;
529
+ color: HighlightText;
530
+ forced-color-adjust: none;
531
+ }
532
+ }
533
+ }
@@ -0,0 +1,53 @@
1
+ [
2
+ "--slotted-border-subtle",
3
+ "--slotted-border-width-medium",
4
+ "--slotted-border-width-thin",
5
+ "--slotted-control-font-size-lg",
6
+ "--slotted-control-font-size-md",
7
+ "--slotted-control-font-size-sm",
8
+ "--slotted-control-gap-lg",
9
+ "--slotted-control-gap-md",
10
+ "--slotted-control-gap-sm",
11
+ "--slotted-control-height-lg",
12
+ "--slotted-control-height-md",
13
+ "--slotted-control-height-sm",
14
+ "--slotted-control-icon-size-lg",
15
+ "--slotted-control-icon-size-md",
16
+ "--slotted-control-icon-size-sm",
17
+ "--slotted-control-padding-inline-lg",
18
+ "--slotted-control-padding-inline-md",
19
+ "--slotted-control-padding-inline-sm",
20
+ "--slotted-control-radius",
21
+ "--slotted-duration-medium",
22
+ "--slotted-duration-short",
23
+ "--slotted-easing-enter",
24
+ "--slotted-easing-standard",
25
+ "--slotted-focus-ring-color",
26
+ "--slotted-focus-ring-offset",
27
+ "--slotted-focus-ring-width",
28
+ "--slotted-font-family-sans",
29
+ "--slotted-font-size-sm",
30
+ "--slotted-font-weight-medium",
31
+ "--slotted-font-weight-semibold",
32
+ "--slotted-line-height-sm",
33
+ "--slotted-radius-full",
34
+ "--slotted-radius-md",
35
+ "--slotted-shadow-md",
36
+ "--slotted-space-2",
37
+ "--slotted-space-3",
38
+ "--slotted-space-5",
39
+ "--slotted-space-9",
40
+ "--slotted-surface-raised",
41
+ "--slotted-table-of-contents-color",
42
+ "--slotted-table-of-contents-color-current",
43
+ "--slotted-table-of-contents-color-hover",
44
+ "--slotted-table-of-contents-indent",
45
+ "--slotted-table-of-contents-marker-color",
46
+ "--slotted-table-of-contents-track-color",
47
+ "--slotted-table-of-contents-track-width",
48
+ "--slotted-text",
49
+ "--slotted-text-muted",
50
+ "--slotted-tone-accent-solid",
51
+ "--slotted-tone-accent-text",
52
+ "--slotted-z-index-popover"
53
+ ]