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

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,1029 @@
1
+ /**
2
+ * The measured geometry is registered as lengths so that it can be
3
+ * transitioned. The root moves these five numbers, and the surface, every
4
+ * panel, the clip that keeps a panel inside the surface and the arrow read
5
+ * them: one interpolation, so nothing a panel draws can be seen outside the
6
+ * surface while the surface moves from one section to the next.
7
+ * `--slotted-navigation-menu-available-inline-size` is not registered: it is
8
+ * a cap, never animated, and its unset fallback is what a static render reads.
9
+ */
10
+ @property --slotted-navigation-menu-viewport-inline-size {
11
+ syntax: '<length>';
12
+ inherits: true;
13
+ initial-value: 0px;
14
+ }
15
+
16
+ @property --slotted-navigation-menu-viewport-block-size {
17
+ syntax: '<length>';
18
+ inherits: true;
19
+ initial-value: 0px;
20
+ }
21
+
22
+ @property --slotted-navigation-menu-viewport-inline-start {
23
+ syntax: '<length>';
24
+ inherits: true;
25
+ initial-value: 0px;
26
+ }
27
+
28
+ @property --slotted-navigation-menu-viewport-block-start {
29
+ syntax: '<length>';
30
+ inherits: true;
31
+ initial-value: 0px;
32
+ }
33
+
34
+ @property --slotted-navigation-menu-arrow-offset {
35
+ syntax: '<length>';
36
+ inherits: true;
37
+ initial-value: 0px;
38
+ }
39
+
40
+ @layer slotted.components {
41
+ /**
42
+ * The sections of a site or an application in a row, each a button that
43
+ * shows a panel of destinations under the row, with direct links beside
44
+ * them. The panel is a disclosure and never a menu: its destinations are
45
+ * links.
46
+ *
47
+ * root ▸ list ▸ item ▸ trigger ▸ indicator
48
+ * · content ▸ links ▸ link ▸ icon · label · description
49
+ * · group ▸ group-label · links
50
+ * · footer
51
+ * ▸ item ▸ link
52
+ * · viewport ▸ arrow
53
+ *
54
+ * ── The panel stays in its item; only the surface is shared ─────────────
55
+ *
56
+ * Every content follows its trigger in the DOM, which is where the
57
+ * disclosure example puts it and what lets Tab reach it. The viewport is an
58
+ * empty element after the list that paints the one surface — ground, edge,
59
+ * shadow, radius — and moves between the sizes of the sections, while the
60
+ * contents are laid over its box with no ground of their own and cross over
61
+ * it. Nothing is ported, so there is no tab order to rebuild.
62
+ *
63
+ * The script writes the measured geometry on the root as runtime
64
+ * properties (`--slotted-navigation-menu-viewport-*`, `-arrow-offset`,
65
+ * `-available-inline-size`) and `data-positioned` on the viewport once it
66
+ * has placed it. Without script there is no viewport: the open content
67
+ * paints the surface itself, so a static render shows the whole panel.
68
+ *
69
+ * ── Geometry is the control's ───────────────────────────────────────────
70
+ *
71
+ * A trigger and a top-level link are controls: the control scale's height,
72
+ * inset and type, the height `top-navigation` and every field beside the
73
+ * row stand at. A link inside a panel starts its text in the column the
74
+ * trigger's label starts in: the viewport opens at the trigger's inline
75
+ * start, and the panel's border, its inset and the link's own inset add up
76
+ * to the control's inline padding.
77
+ */
78
+ [data-ui='navigation-menu'] {
79
+ --_control-height: var(--slotted-control-height-md, 34px);
80
+ --_control-padding: var(--slotted-control-padding-inline-md, 13px);
81
+ --_control-font-size: var(--slotted-control-font-size-md, 13px);
82
+ --_icon-size: var(--slotted-control-icon-size-md, 16px);
83
+ --_gap: var(--slotted-control-gap-sm, 6px);
84
+ /** Two pixels between two triggers, so two grounds never read as one control. */
85
+ --_list-gap: var(--slotted-space-1, 0.125rem);
86
+ --_radius: var(--slotted-navigation-menu-radius, var(--slotted-control-radius, 4px));
87
+
88
+ --_surface: var(--slotted-navigation-menu-surface, var(--slotted-surface-raised, Canvas));
89
+ --_border-color: var(
90
+ --slotted-navigation-menu-border-color,
91
+ var(--slotted-border-subtle, ButtonBorder)
92
+ );
93
+ --_border-width: var(--slotted-border-width-thin, 1px);
94
+ --_shadow: var(--slotted-navigation-menu-shadow, var(--slotted-shadow-md));
95
+ --_viewport-radius: var(
96
+ --slotted-navigation-menu-viewport-radius,
97
+ var(--slotted-radius-lg, 8px)
98
+ );
99
+ /** The distance between the row and the surface, bridged for the pointer. */
100
+ --_offset: var(--slotted-navigation-menu-offset, var(--slotted-space-2, 0.25rem));
101
+ /** The surface's own inset, `menu`'s, so a panel and a menu hold their rows alike. */
102
+ --_inset: var(--slotted-space-2, 0.25rem);
103
+ /**
104
+ * One column of rich links: a title and two lines of description beside a
105
+ * mark. 240 pixels hold "Keep your finances organized." on one line at 12
106
+ * pixels; ReUI's 248 is the same column less its own inset.
107
+ */
108
+ --_column-size: var(--slotted-navigation-menu-column-size, 15rem);
109
+ --_column-gap: var(--slotted-space-2, 0.25rem);
110
+ /** The narrowest a group column stands before the panel stacks its groups. */
111
+ --_group-min: 10rem;
112
+ /** The gutter the panel keeps from the window's edge when it is moved to fit. */
113
+ --_gutter: var(--slotted-space-4, 0.5rem);
114
+
115
+ --_font-size: var(--slotted-control-font-size-md, 13px);
116
+ --_secondary-font-size: var(--slotted-control-font-size-sm, 12px);
117
+ /**
118
+ * Line boxes on whole pixels, `menu`'s rule: 13 × 1.5 is 19.5 and
119
+ * 12 × 1.45 is 17.4, and a rich link summed them to a fractional height.
120
+ */
121
+ --_leading: round(up, calc(var(--_font-size) * var(--slotted-line-height-md, 1.5)), 1px);
122
+ --_secondary-leading: round(
123
+ up,
124
+ calc(var(--_secondary-font-size) * var(--slotted-line-height-sm, 1.45)),
125
+ 1px
126
+ );
127
+ /**
128
+ * The link's inline inset is the control's less the surface's border and
129
+ * inset, so the panel's first text starts in the column the trigger's
130
+ * label starts in: 13 − 1 − 4 = 8 at `md`.
131
+ */
132
+ --_link-inset-inline: calc(var(--_control-padding) - var(--_border-width) - var(--_inset));
133
+ --_link-inset-block: var(--slotted-space-4, 0.5rem);
134
+
135
+ --_color: var(--slotted-navigation-menu-color, var(--slotted-text, CanvasText));
136
+ --_muted-color: var(--slotted-navigation-menu-muted-color, var(--slotted-text-muted, GrayText));
137
+ --_hover-background: var(
138
+ --slotted-navigation-menu-hover-background,
139
+ var(--slotted-tone-secondary-subtle-hover)
140
+ );
141
+ --_active-background: var(
142
+ --slotted-navigation-menu-active-background,
143
+ var(--slotted-tone-secondary-subtle-active)
144
+ );
145
+ --_current-color: var(--slotted-navigation-menu-current-color, var(--slotted-tone-accent-text));
146
+ --_current-background: var(
147
+ --slotted-navigation-menu-current-background,
148
+ var(--slotted-tone-accent-surface)
149
+ );
150
+ --_current-edge: var(
151
+ --slotted-navigation-menu-current-edge,
152
+ var(--slotted-current-edge, transparent)
153
+ );
154
+ --_disabled-color: var(--slotted-disabled-foreground, GrayText);
155
+
156
+ --_duration: var(--slotted-control-transition-duration, var(--slotted-duration-short));
157
+ --_easing: var(--slotted-control-transition-easing, var(--slotted-easing-standard));
158
+ /** One step of the space scale, R7's distance for a layer that arrives. */
159
+ --_enter-distance: var(--slotted-space-2, 0.25rem);
160
+ /** How far a section slides when another one takes its place. */
161
+ --_slide-distance: var(--slotted-space-6, 1rem);
162
+ /** `translate` is physical; a right-to-left root turns the inline sign. */
163
+ --_inline-sign: 1;
164
+ /** The arrow is a square turned a quarter: its diagonal is twice its reach. */
165
+ --_arrow-size: var(--slotted-space-4, 0.5rem);
166
+
167
+ box-sizing: border-box;
168
+ color: var(--_color);
169
+ display: flex;
170
+ font-family: var(--slotted-control-font-family, inherit);
171
+ font-size: var(--_control-font-size);
172
+ position: relative;
173
+ }
174
+
175
+ [data-ui='navigation-menu']:dir(rtl) {
176
+ --_inline-sign: -1;
177
+ }
178
+
179
+ /**
180
+ * An open root rises to the popover layer and no further: a constant
181
+ * z-index on a nav would put the row above a dialog's scrim.
182
+ */
183
+ [data-ui='navigation-menu']:has(
184
+ > [data-part='list'] > [data-part='item'] > [data-part='content'][data-open]
185
+ ) {
186
+ z-index: var(--slotted-z-index-popover, 1100);
187
+ }
188
+
189
+ /**
190
+ * While the surface is open, a change of section moves the measured
191
+ * geometry on the standard curve, and everything placed by it moves with
192
+ * it. While it is closed nothing transitions: the script writes the next
193
+ * section's numbers before it opens, and they are simply there.
194
+ */
195
+ [data-ui='navigation-menu']:has(> [data-part='viewport'][data-open]) {
196
+ transition:
197
+ --slotted-navigation-menu-viewport-inline-size var(--slotted-duration-medium)
198
+ var(--slotted-easing-standard),
199
+ --slotted-navigation-menu-viewport-block-size var(--slotted-duration-medium)
200
+ var(--slotted-easing-standard),
201
+ --slotted-navigation-menu-viewport-inline-start var(--slotted-duration-medium)
202
+ var(--slotted-easing-standard),
203
+ --slotted-navigation-menu-viewport-block-start var(--slotted-duration-medium)
204
+ var(--slotted-easing-standard),
205
+ --slotted-navigation-menu-arrow-offset var(--slotted-duration-medium)
206
+ var(--slotted-easing-standard);
207
+ }
208
+
209
+ [data-ui='navigation-menu'][data-size='sm'] {
210
+ --_control-height: var(--slotted-control-height-sm, 30px);
211
+ --_control-padding: var(--slotted-control-padding-inline-sm, 10px);
212
+ --_control-font-size: var(--slotted-control-font-size-sm, 12px);
213
+ --_icon-size: var(--slotted-control-icon-size-sm, 14px);
214
+ --_gap: var(--slotted-control-gap-sm, 6px);
215
+ }
216
+
217
+ [data-ui='navigation-menu'][data-size='lg'] {
218
+ --_control-height: var(--slotted-control-height-lg, 38px);
219
+ --_control-padding: var(--slotted-control-padding-inline-lg, 16px);
220
+ --_control-font-size: var(--slotted-control-font-size-lg, 14px);
221
+ --_icon-size: var(--slotted-control-icon-size-lg, 18px);
222
+ --_gap: var(--slotted-control-gap-md, 8px);
223
+ }
224
+
225
+ [data-ui='navigation-menu'] > [data-part='list'] {
226
+ align-items: center;
227
+ display: flex;
228
+ gap: var(--_list-gap);
229
+ list-style: none;
230
+ margin: 0;
231
+ padding: 0;
232
+ }
233
+
234
+ [data-ui='navigation-menu'] > [data-part='list'] > [data-part='item'] {
235
+ display: flex;
236
+ }
237
+
238
+ /* ── Trigger and top-level link ──────────────────────────────────────── */
239
+
240
+ /**
241
+ * A section and a destination share one shape: the control's height and
242
+ * inset, the page's ink at rest and a ground under the pointer, as in
243
+ * `top-navigation`.
244
+ */
245
+ /* Held at the specificity of one attribute, so the current, open and
246
+ disabled rules below win over it without restating the path. */
247
+ :where([data-ui='navigation-menu'] > [data-part='list'] > [data-part='item'])
248
+ > :is([data-part='trigger'], [data-part='link']) {
249
+ align-items: center;
250
+ appearance: none;
251
+ background-color: transparent;
252
+ border: 0;
253
+ border-radius: var(--_radius);
254
+ box-sizing: border-box;
255
+ color: var(--_color);
256
+ cursor: pointer;
257
+ display: inline-flex;
258
+ font: inherit;
259
+ font-weight: var(--slotted-font-weight-medium, 500);
260
+ gap: var(--_gap);
261
+ line-height: var(--slotted-control-line-height, 1);
262
+ margin: 0;
263
+ min-block-size: var(--_control-height);
264
+ padding-block: 0;
265
+ padding-inline: var(--_control-padding);
266
+ text-decoration: none;
267
+ transition:
268
+ background-color var(--_duration) var(--_easing),
269
+ color var(--_duration) var(--_easing);
270
+ white-space: nowrap;
271
+ }
272
+
273
+ [data-ui='navigation-menu']
274
+ > [data-part='list']
275
+ > [data-part='item']:not([data-disabled])
276
+ > [data-part='trigger']:enabled:hover,
277
+ [data-ui='navigation-menu']
278
+ > [data-part='list']
279
+ > [data-part='item']:not([data-disabled])
280
+ > [data-part='link']:not([data-disabled], [data-current], [aria-current='page']):hover {
281
+ background-color: var(--_hover-background);
282
+ }
283
+
284
+ [data-ui='navigation-menu']
285
+ > [data-part='list']
286
+ > [data-part='item']:not([data-disabled])
287
+ > [data-part='trigger']:enabled:active,
288
+ [data-ui='navigation-menu']
289
+ > [data-part='list']
290
+ > [data-part='item']:not([data-disabled])
291
+ > [data-part='link']:not([data-disabled], [data-current], [aria-current='page']):active {
292
+ background-color: var(--_active-background);
293
+ transition-duration: var(--slotted-duration-instant);
294
+ }
295
+
296
+ /** An open section holds the ground the pointer gave it. */
297
+ [data-ui='navigation-menu']
298
+ > [data-part='list']
299
+ > [data-part='item']
300
+ > [data-part='trigger'][data-open]:enabled {
301
+ background-color: var(--_hover-background);
302
+ }
303
+
304
+ /**
305
+ * The section that holds the current page says so with every section
306
+ * closed: the accent ink on the resting ground. The ground stays the
307
+ * pointer's, so an open current section reads open first.
308
+ */
309
+ [data-ui='navigation-menu']
310
+ > [data-part='list']
311
+ > [data-part='item']
312
+ > [data-part='trigger'][data-current]:enabled {
313
+ color: var(--_current-color);
314
+ }
315
+
316
+ [data-ui='navigation-menu'] [data-part='link']:is([data-current], [aria-current='page']) {
317
+ background-color: var(--_current-background);
318
+ box-shadow: inset 0 0 0 var(--_border-width) var(--_current-edge);
319
+ color: var(--_current-color);
320
+ }
321
+
322
+ [data-ui='navigation-menu']
323
+ > [data-part='list']
324
+ > [data-part='item']
325
+ > [data-part='link']:is([data-current], [aria-current='page']) {
326
+ font-weight: var(--slotted-font-weight-semibold, 600);
327
+ }
328
+
329
+ [data-ui='navigation-menu'] [data-part='trigger']:disabled,
330
+ [data-ui='navigation-menu'] [data-part='link'][data-disabled],
331
+ [data-ui='navigation-menu'] [data-part='content'] [data-part='link'][data-disabled] {
332
+ color: var(--_disabled-color);
333
+ cursor: not-allowed;
334
+ }
335
+
336
+ [data-ui='navigation-menu'] :is([data-part='trigger'], [data-part='link']):focus-visible {
337
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
338
+ outline-offset: var(--slotted-focus-ring-offset, 2px);
339
+ }
340
+
341
+ /**
342
+ * The chevron says the section opens below the row and turns half a turn
343
+ * while it is open. Down is down in both directions, so its box is not
344
+ * `directional`; a vertical root draws `chevron-right` in a directional box
345
+ * and does not turn it, because the section opens where it already points.
346
+ */
347
+ [data-ui='navigation-menu'] [data-part='indicator'] {
348
+ --slotted-icon-size: var(--_icon-size);
349
+
350
+ display: flex;
351
+ flex: 0 0 auto;
352
+ margin-inline-end: calc(-1 * var(--slotted-space-2, 0.25rem));
353
+ }
354
+
355
+ [data-ui='navigation-menu'] [data-part='indicator'] > [data-ui='icon'] {
356
+ transition: rotate var(--slotted-duration-medium) var(--slotted-easing-standard);
357
+ }
358
+
359
+ [data-ui='navigation-menu']:not([data-orientation='vertical'])
360
+ > [data-part='list']
361
+ > [data-part='item']
362
+ > [data-part='trigger'][data-open]
363
+ > [data-part='indicator']
364
+ > [data-ui='icon'] {
365
+ rotate: 0.5turn;
366
+ }
367
+
368
+ /* ── The surface ─────────────────────────────────────────────────────── */
369
+
370
+ /**
371
+ * Sized and placed from the measured content. While it is closed a change
372
+ * of size snaps, because nothing is seen; while it is open a change of
373
+ * section moves its size and its place on the standard curve, so the
374
+ * surface the reader is looking at grows into the next section rather than
375
+ * being replaced by it.
376
+ *
377
+ * R7: the surface arrives one space step above its place and leaves on the
378
+ * exit curve, never longer than it arrived. The arrival is a keyframe, the
379
+ * reason `menu` gives: only a surface the script has placed arrives.
380
+ */
381
+ [data-ui='navigation-menu'] > [data-part='viewport'] {
382
+ background-color: var(--_surface);
383
+ border: var(--_border-width) solid var(--_border-color);
384
+ border-radius: var(--_viewport-radius);
385
+ box-shadow: var(--_shadow);
386
+ box-sizing: border-box;
387
+ display: none;
388
+ block-size: var(--slotted-navigation-menu-viewport-block-size, 0px);
389
+ inline-size: var(--slotted-navigation-menu-viewport-inline-size, 0px);
390
+ inset-block-start: calc(100% + var(--_offset));
391
+ inset-inline-start: var(--slotted-navigation-menu-viewport-inline-start, 0px);
392
+ opacity: 0;
393
+ pointer-events: none;
394
+ position: absolute;
395
+ translate: 0 calc(-1 * var(--_enter-distance));
396
+ transition:
397
+ opacity var(--slotted-duration-short) var(--slotted-easing-exit),
398
+ translate var(--slotted-duration-short) var(--slotted-easing-exit);
399
+ }
400
+
401
+ [data-ui='navigation-menu'] > [data-part='viewport'][data-positioned] {
402
+ display: block;
403
+ }
404
+
405
+ [data-ui='navigation-menu'] > [data-part='viewport'][data-open] {
406
+ opacity: 1;
407
+ pointer-events: auto;
408
+ translate: 0 0;
409
+ transition: none;
410
+ }
411
+
412
+ [data-ui='navigation-menu'] > [data-part='viewport'][data-open][data-positioned] {
413
+ animation: slotted-navigation-menu-enter-down var(--slotted-duration-medium)
414
+ var(--slotted-easing-enter);
415
+ }
416
+
417
+ /**
418
+ * The gap between the row and the surface is the surface's, not the
419
+ * page's: a transparent bridge covers it, so a pointer moving down from a
420
+ * trigger never leaves the region that keeps the panel open. It paints
421
+ * nothing.
422
+ */
423
+ [data-ui='navigation-menu'] > [data-part='viewport']::before {
424
+ content: '';
425
+ inset-block-end: 100%;
426
+ inset-inline: 0;
427
+ block-size: calc(var(--_offset) + var(--_border-width));
428
+ position: absolute;
429
+ }
430
+
431
+ @keyframes slotted-navigation-menu-enter-down {
432
+ from {
433
+ opacity: 0;
434
+ translate: 0 calc(-1 * var(--_enter-distance));
435
+ }
436
+ }
437
+
438
+ @keyframes slotted-navigation-menu-enter-from-start {
439
+ from {
440
+ opacity: 0;
441
+ translate: calc(-1 * var(--_inline-sign) * var(--_enter-distance)) 0;
442
+ }
443
+ }
444
+
445
+ @keyframes slotted-navigation-menu-fade {
446
+ from {
447
+ opacity: 0;
448
+ }
449
+ }
450
+
451
+ /**
452
+ * The mark on the surface's edge that points at the open trigger: a square
453
+ * turned a quarter, painted with the surface and edged on the two sides that
454
+ * face the row, so it reads as the surface reaching for its trigger. It
455
+ * slides from trigger to trigger with the surface.
456
+ */
457
+ [data-ui='navigation-menu'] > [data-part='viewport'] > [data-part='arrow'] {
458
+ background-color: var(--_surface);
459
+ border-block-start: var(--_border-width) solid var(--_border-color);
460
+ border-inline-start: var(--_border-width) solid var(--_border-color);
461
+ border-start-start-radius: var(--slotted-radius-xs, 2px);
462
+ box-sizing: border-box;
463
+ block-size: var(--_arrow-size);
464
+ inline-size: var(--_arrow-size);
465
+ inset-block-start: calc(var(--_arrow-size) / -2 - var(--_border-width) / 2);
466
+ inset-inline-start: calc(
467
+ var(--slotted-navigation-menu-arrow-offset, 50%) - var(--_arrow-size) / 2
468
+ );
469
+ position: absolute;
470
+ rotate: calc(var(--_inline-sign) * 45deg);
471
+ }
472
+
473
+ /* ── The panel ───────────────────────────────────────────────────────── */
474
+
475
+ /**
476
+ * Laid over the surface's box with no ground of its own. Its inline size is
477
+ * stated — so many columns of so much, plus the gaps and the surface's
478
+ * frame — which is what lets it be a query container: a `max-content`
479
+ * width under inline-size containment measures nothing. The space the
480
+ * script measured caps it.
481
+ */
482
+ [data-ui='navigation-menu'] > [data-part='list'] > [data-part='item'] > [data-part='content'] {
483
+ --_columns: 1;
484
+ --_content-size: calc(
485
+ var(--_columns) * var(--_column-size) + (var(--_columns) - 1) * var(--_column-gap) + 2 *
486
+ (var(--_inset) + var(--_border-width))
487
+ );
488
+
489
+ border: var(--_border-width) solid transparent;
490
+ border-radius: var(--_viewport-radius);
491
+ box-sizing: border-box;
492
+ color: var(--_color);
493
+ column-gap: var(--_column-gap);
494
+ container-name: slotted-navigation-menu-content;
495
+ container-type: inline-size;
496
+ display: grid;
497
+ font-size: var(--_font-size);
498
+ /**
499
+ * The panel's own tracks hold its groups, and a query container cannot
500
+ * query itself: the groups fit as many columns of at least ten rem as the
501
+ * panel holds, up to its column count, and a narrow panel stacks them.
502
+ */
503
+ grid-template-columns: repeat(
504
+ auto-fit,
505
+ minmax(
506
+ max(
507
+ var(--_group-min),
508
+ calc((100% - (var(--_columns) - 1) * var(--_column-gap)) / var(--_columns))
509
+ ),
510
+ 1fr
511
+ )
512
+ );
513
+ inline-size: min(
514
+ var(--_content-size),
515
+ var(--slotted-navigation-menu-available-inline-size, calc(100vw - 2 * var(--_gutter)))
516
+ );
517
+ inset-block-start: calc(100% + var(--_offset));
518
+ inset-inline-start: var(--slotted-navigation-menu-viewport-inline-start, 0px);
519
+ line-height: var(--_leading);
520
+ opacity: 0;
521
+ padding: var(--_inset);
522
+ position: absolute;
523
+ row-gap: var(--_inset);
524
+ /**
525
+ * A panel is drawn only inside the surface: while the surface grows or
526
+ * shrinks into the next section, the part of a panel past the surface's
527
+ * end and bottom is clipped, the way a panel inside a viewport would be.
528
+ * At rest the two boxes are the same and nothing is clipped.
529
+ */
530
+ clip-path: inset(
531
+ 0 max(0px, calc(100% - var(--slotted-navigation-menu-viewport-inline-size)))
532
+ max(0px, calc(100% - var(--slotted-navigation-menu-viewport-block-size))) 0 round
533
+ var(--_viewport-radius)
534
+ );
535
+ transition: opacity var(--slotted-duration-short) var(--slotted-easing-exit);
536
+ z-index: 1;
537
+ }
538
+
539
+ [data-ui='navigation-menu']:dir(rtl)
540
+ > [data-part='list']
541
+ > [data-part='item']
542
+ > [data-part='content'] {
543
+ clip-path: inset(
544
+ 0 0 max(0px, calc(100% - var(--slotted-navigation-menu-viewport-block-size)))
545
+ max(0px, calc(100% - var(--slotted-navigation-menu-viewport-inline-size))) round
546
+ var(--_viewport-radius)
547
+ );
548
+ }
549
+
550
+ [data-ui='navigation-menu']
551
+ > [data-part='list']
552
+ > [data-part='item']
553
+ > [data-part='content'][data-columns='2'] {
554
+ --_columns: 2;
555
+ }
556
+
557
+ [data-ui='navigation-menu']
558
+ > [data-part='list']
559
+ > [data-part='item']
560
+ > [data-part='content'][data-columns='3'] {
561
+ --_columns: 3;
562
+ }
563
+
564
+ [data-ui='navigation-menu']
565
+ > [data-part='list']
566
+ > [data-part='item']
567
+ > [data-part='content'][hidden] {
568
+ display: none;
569
+ }
570
+
571
+ [data-ui='navigation-menu']
572
+ > [data-part='list']
573
+ > [data-part='item']
574
+ > [data-part='content'][data-open] {
575
+ opacity: 1;
576
+ transition: none;
577
+ }
578
+
579
+ /**
580
+ * Without script there is no surface to lay the panel over, so the open
581
+ * panel paints one itself: a static render, a snippet and a server render
582
+ * show the whole panel where it stands.
583
+ */
584
+ [data-ui='navigation-menu']:not([data-nested]):not(
585
+ :has(> [data-part='viewport'][data-positioned])
586
+ )
587
+ > [data-part='list']
588
+ > [data-part='item']
589
+ > [data-part='content'] {
590
+ background-color: var(--_surface);
591
+ border-color: var(--_border-color);
592
+ box-shadow: var(--_shadow);
593
+ clip-path: none;
594
+ }
595
+
596
+ /**
597
+ * One section crossing another. The one that leaves slides one step
598
+ * toward the side the reader moved away from and fades on the exit curve;
599
+ * the one that arrives comes from the other side on the enter curve, a
600
+ * duration step longer. The directions are logical: `from-end` is the
601
+ * section after this one in reading order.
602
+ */
603
+ [data-ui='navigation-menu'] [data-part='content'][data-motion='from-end'] {
604
+ animation: slotted-navigation-menu-from-end var(--slotted-duration-medium)
605
+ var(--slotted-easing-enter) both;
606
+ }
607
+
608
+ [data-ui='navigation-menu'] [data-part='content'][data-motion='from-start'] {
609
+ animation: slotted-navigation-menu-from-start var(--slotted-duration-medium)
610
+ var(--slotted-easing-enter) both;
611
+ }
612
+
613
+ [data-ui='navigation-menu'] [data-part='content'][data-motion='to-end'] {
614
+ animation: slotted-navigation-menu-to-end var(--slotted-duration-short)
615
+ var(--slotted-easing-exit) both;
616
+ }
617
+
618
+ [data-ui='navigation-menu'] [data-part='content'][data-motion='to-start'] {
619
+ animation: slotted-navigation-menu-to-start var(--slotted-duration-short)
620
+ var(--slotted-easing-exit) both;
621
+ }
622
+
623
+ @keyframes slotted-navigation-menu-from-end {
624
+ from {
625
+ opacity: 0;
626
+ translate: calc(var(--_inline-sign) * var(--_slide-distance)) 0;
627
+ }
628
+ }
629
+
630
+ @keyframes slotted-navigation-menu-from-start {
631
+ from {
632
+ opacity: 0;
633
+ translate: calc(-1 * var(--_inline-sign) * var(--_slide-distance)) 0;
634
+ }
635
+ }
636
+
637
+ @keyframes slotted-navigation-menu-to-end {
638
+ to {
639
+ opacity: 0;
640
+ translate: calc(var(--_inline-sign) * var(--_slide-distance)) 0;
641
+ }
642
+ }
643
+
644
+ @keyframes slotted-navigation-menu-to-start {
645
+ to {
646
+ opacity: 0;
647
+ translate: calc(-1 * var(--_inline-sign) * var(--_slide-distance)) 0;
648
+ }
649
+ }
650
+
651
+ /** A list or a footer straight in the panel spans every column. */
652
+ [data-ui='navigation-menu']
653
+ [data-part='content']
654
+ > :is([data-part='links'], [data-part='footer']) {
655
+ grid-column: 1 / -1;
656
+ }
657
+
658
+ [data-ui='navigation-menu'] [data-part='links'] {
659
+ display: grid;
660
+ gap: var(--_column-gap);
661
+ grid-template-columns: repeat(var(--_columns, 1), minmax(0, 1fr));
662
+ list-style: none;
663
+ margin: 0;
664
+ padding: 0;
665
+ }
666
+
667
+ /** A group is one column; its list is one column inside it. */
668
+ [data-ui='navigation-menu'] [data-part='group'] > [data-part='links'] {
669
+ grid-template-columns: minmax(0, 1fr);
670
+ }
671
+
672
+ /**
673
+ * Below 480 pixels of panel — a phone, or a window the panel was moved to
674
+ * fit — two columns of 200 are two columns of clipped descriptions, and
675
+ * the panel falls to one.
676
+ */
677
+ @container slotted-navigation-menu-content (inline-size < 480px) {
678
+ [data-ui='navigation-menu'] [data-part='links'] {
679
+ grid-template-columns: minmax(0, 1fr);
680
+ }
681
+ }
682
+
683
+ [data-ui='navigation-menu'] [data-part='group'] {
684
+ display: flex;
685
+ flex-direction: column;
686
+ gap: var(--slotted-space-1, 0.125rem);
687
+ min-inline-size: 0;
688
+ }
689
+
690
+ [data-ui='navigation-menu'] [data-part='group-label'] {
691
+ color: var(--_muted-color);
692
+ font-size: var(--_secondary-font-size);
693
+ font-weight: var(--slotted-font-weight-semibold, 600);
694
+ line-height: var(--_secondary-leading);
695
+ padding-block: var(--slotted-space-3, 0.375rem) var(--slotted-space-2, 0.25rem);
696
+ padding-inline: var(--_link-inset-inline);
697
+ }
698
+
699
+ /* ── A link inside the panel ─────────────────────────────────────────── */
700
+
701
+ /**
702
+ * A row of the panel: the mark in its own column, the title and the
703
+ * description stacked beside it. The mark column carries no gap of its
704
+ * own — a column gap is drawn even when the mark is absent — so the mark
705
+ * holds its margin and a link with no mark starts its title at the inset.
706
+ */
707
+ [data-ui='navigation-menu'] [data-part='content'] [data-part='link'] {
708
+ border-radius: var(--_radius);
709
+ box-sizing: border-box;
710
+ color: var(--_color);
711
+ display: grid;
712
+ font-weight: var(--slotted-font-weight-regular, 400);
713
+ grid-template-areas:
714
+ 'icon label'
715
+ 'icon description';
716
+ grid-template-columns: auto minmax(0, 1fr);
717
+ grid-template-rows: auto auto;
718
+ line-height: var(--_leading);
719
+ min-block-size: var(--_control-height);
720
+ outline-offset: 0;
721
+ padding-block: var(--_link-inset-block);
722
+ padding-inline: var(--_link-inset-inline);
723
+ row-gap: var(--slotted-space-1, 0.125rem);
724
+ text-decoration: none;
725
+ transition:
726
+ background-color var(--_duration) var(--_easing),
727
+ color var(--_duration) var(--_easing);
728
+ }
729
+
730
+ /** A link of plain words is a row at the control's height, its text centred in it. */
731
+ [data-ui='navigation-menu']
732
+ [data-part='content']
733
+ [data-part='link']:not(:has([data-part='label'])) {
734
+ align-content: center;
735
+ display: grid;
736
+ grid-template-areas: none;
737
+ grid-template-columns: minmax(0, 1fr);
738
+ padding-block: 0;
739
+ }
740
+
741
+ [data-ui='navigation-menu']
742
+ [data-part='content']
743
+ [data-part='link']:not([data-disabled], [data-current], [aria-current='page']):hover {
744
+ background-color: var(--_hover-background);
745
+ }
746
+
747
+ [data-ui='navigation-menu']
748
+ [data-part='content']
749
+ [data-part='link']:not([data-disabled], [data-current], [aria-current='page']):active {
750
+ background-color: var(--_active-background);
751
+ transition-duration: var(--slotted-duration-instant);
752
+ }
753
+
754
+ /* The panel's row rule above is as specific as the shared current rule and later; restated here. */
755
+ [data-ui='navigation-menu']
756
+ [data-part='content']
757
+ [data-part='link']:is([data-current], [aria-current='page']) {
758
+ color: var(--_current-color);
759
+ }
760
+
761
+ [data-ui='navigation-menu']
762
+ [data-part='content']
763
+ [data-part='link']:is([data-current], [aria-current='page'])
764
+ > [data-part='description'] {
765
+ color: inherit;
766
+ }
767
+
768
+ [data-ui='navigation-menu'] [data-part='content'] [data-part='link']:focus-visible {
769
+ outline-offset: 0;
770
+ }
771
+
772
+ /**
773
+ * The mark is one line of the title tall, and its artwork stands on the
774
+ * title's baseline at the midpoint of the capitals' and the lowercase
775
+ * letters' centres — the briefing's rule for a mark beside a line of text.
776
+ */
777
+ [data-ui='navigation-menu'] [data-part='link'] > [data-part='icon'] {
778
+ --slotted-icon-size: var(--_icon-size);
779
+
780
+ color: var(--_muted-color);
781
+ grid-area: icon;
782
+ line-height: var(--_leading);
783
+ margin-inline-end: var(--slotted-control-gap-md, 8px);
784
+ transition: color var(--_duration) var(--_easing);
785
+ }
786
+
787
+ [data-ui='navigation-menu'] [data-part='link'] > [data-part='icon'] > [data-ui='icon'] {
788
+ display: inline-block;
789
+ vertical-align: calc((1cap + 1ex) / 4 - var(--_icon-size) / 2);
790
+ }
791
+
792
+ [data-ui='navigation-menu']
793
+ [data-part='link']:not([data-disabled], [data-current], [aria-current='page']):hover
794
+ > [data-part='icon'] {
795
+ color: var(--_color);
796
+ }
797
+
798
+ [data-ui='navigation-menu']
799
+ [data-part='link']:is([data-current], [aria-current='page'], [data-disabled])
800
+ > [data-part='icon'] {
801
+ color: inherit;
802
+ }
803
+
804
+ [data-ui='navigation-menu'] [data-part='link'] > [data-part='label'] {
805
+ font-weight: var(--slotted-font-weight-medium, 500);
806
+ grid-area: label;
807
+ min-inline-size: 0;
808
+ }
809
+
810
+ [data-ui='navigation-menu'] [data-part='link'] > [data-part='description'] {
811
+ -webkit-box-orient: vertical;
812
+ -webkit-line-clamp: 2;
813
+ color: var(--_muted-color);
814
+ display: -webkit-box;
815
+ font-size: var(--_secondary-font-size);
816
+ grid-area: description;
817
+ line-clamp: 2;
818
+ line-height: var(--_secondary-leading);
819
+ min-inline-size: 0;
820
+ overflow: hidden;
821
+ }
822
+
823
+ [data-ui='navigation-menu'] [data-part='link'][data-disabled] > [data-part='description'] {
824
+ color: inherit;
825
+ }
826
+
827
+ /** The panel's last row, under a rule that runs the panel's inner width. */
828
+ [data-ui='navigation-menu'] [data-part='footer'] {
829
+ align-items: center;
830
+ border-block-start: var(--_border-width) solid var(--_border-color);
831
+ display: flex;
832
+ gap: var(--slotted-control-gap-md, 8px);
833
+ justify-content: space-between;
834
+ margin-inline: calc(-1 * var(--_inset));
835
+ padding-block: var(--_inset) 0;
836
+ /* The words start in the links' column and the action ends on their edge. */
837
+ padding-inline: calc(var(--_inset) + var(--_link-inset-inline)) var(--_inset);
838
+ }
839
+
840
+ /* ── Vertical ────────────────────────────────────────────────────────── */
841
+
842
+ /**
843
+ * A column of sections whose panels open at its inline end, aligned with
844
+ * the open trigger's top. The surface arrives along the inline axis it
845
+ * opens on, the lateral case R7 names for a submenu.
846
+ */
847
+ [data-ui='navigation-menu'][data-orientation='vertical'] > [data-part='list'] {
848
+ align-items: stretch;
849
+ flex-direction: column;
850
+ inline-size: 100%;
851
+ }
852
+
853
+ [data-ui='navigation-menu'][data-orientation='vertical']
854
+ > [data-part='list']
855
+ > [data-part='item']
856
+ > :is([data-part='trigger'], [data-part='link']) {
857
+ flex: 1 1 auto;
858
+ justify-content: space-between;
859
+ }
860
+
861
+ [data-ui='navigation-menu'][data-orientation='vertical'] > [data-part='viewport'],
862
+ [data-ui='navigation-menu'][data-orientation='vertical']
863
+ > [data-part='list']
864
+ > [data-part='item']
865
+ > [data-part='content'] {
866
+ inset-block-start: var(--slotted-navigation-menu-viewport-block-start, 0px);
867
+ inset-inline-start: calc(
868
+ var(--slotted-navigation-menu-viewport-inline-start, 100%) + var(--_offset)
869
+ );
870
+ }
871
+
872
+ /* Without script a vertical panel stands beside the column. */
873
+ [data-ui='navigation-menu'][data-orientation='vertical']:not([data-nested]):not(
874
+ :has(> [data-part='viewport'][data-positioned])
875
+ )
876
+ > [data-part='list']
877
+ > [data-part='item']
878
+ > [data-part='content'] {
879
+ inset-inline-start: calc(100% + var(--_offset));
880
+ }
881
+
882
+ /**
883
+ * A column with no room at its end — a phone, a narrow sidebar — drops the
884
+ * panel under the open trigger instead of clipping it at the window's
885
+ * edge; the script decides it and writes `data-placement`. Under the
886
+ * trigger the surface arrives, points and bridges as it does under a row.
887
+ */
888
+ [data-ui='navigation-menu'][data-orientation='vertical'][data-placement='below']:not(
889
+ [data-nested]
890
+ )
891
+ > [data-part='viewport'],
892
+ [data-ui='navigation-menu'][data-orientation='vertical'][data-placement='below']:not(
893
+ [data-nested]
894
+ )
895
+ > [data-part='list']
896
+ > [data-part='item']
897
+ > [data-part='content'] {
898
+ inset-block-start: calc(
899
+ var(--slotted-navigation-menu-viewport-block-start, 100%) + var(--_offset)
900
+ );
901
+ inset-inline-start: var(--slotted-navigation-menu-viewport-inline-start, 0px);
902
+ }
903
+
904
+ [data-ui='navigation-menu'][data-orientation='vertical']:not([data-placement='below'])
905
+ > [data-part='viewport'] {
906
+ translate: calc(-1 * var(--_inline-sign) * var(--_enter-distance)) 0;
907
+ }
908
+
909
+ [data-ui='navigation-menu'][data-orientation='vertical']:not([data-placement='below'])
910
+ > [data-part='viewport'][data-open] {
911
+ translate: 0 0;
912
+ }
913
+
914
+ [data-ui='navigation-menu'][data-orientation='vertical']:not([data-placement='below'])
915
+ > [data-part='viewport'][data-open][data-positioned] {
916
+ animation-name: slotted-navigation-menu-enter-from-start;
917
+ }
918
+
919
+ [data-ui='navigation-menu'][data-orientation='vertical']:not([data-placement='below'])
920
+ > [data-part='viewport']::before {
921
+ block-size: auto;
922
+ inline-size: calc(var(--_offset) + var(--_border-width));
923
+ inset-block: 0;
924
+ inset-inline: auto 100%;
925
+ }
926
+
927
+ [data-ui='navigation-menu'][data-orientation='vertical']:not([data-placement='below'])
928
+ > [data-part='viewport']
929
+ > [data-part='arrow'] {
930
+ inset-block-start: calc(
931
+ var(--slotted-navigation-menu-arrow-offset, 50%) - var(--_arrow-size) / 2
932
+ );
933
+ inset-inline-start: calc(var(--_arrow-size) / -2 - var(--_border-width) / 2);
934
+ rotate: calc(var(--_inline-sign) * -45deg);
935
+ }
936
+
937
+ /* Under the trigger, the chevron turns to point where the panel went. */
938
+ [data-ui='navigation-menu'][data-orientation='vertical'][data-placement='below']:not(
939
+ [data-nested]
940
+ )
941
+ > [data-part='list']
942
+ > [data-part='item']
943
+ > [data-part='trigger'][data-open]
944
+ > [data-part='indicator']
945
+ > [data-ui='icon'] {
946
+ rotate: calc(var(--_inline-sign) * 0.25turn);
947
+ }
948
+
949
+ /* ── Nested ──────────────────────────────────────────────────────────── */
950
+
951
+ /**
952
+ * A root inside another root's panel is a second level that switches in
953
+ * the same panel: its list is a column at the start, and its open section
954
+ * stands beside it with no surface of its own, because it is already on
955
+ * one. It draws no viewport; its height is the taller of its list and its
956
+ * open section, which the script measures into the same property.
957
+ */
958
+ [data-ui='navigation-menu'][data-nested] {
959
+ --_nested-list-size: var(--slotted-navigation-menu-nested-list-size, 11rem);
960
+
961
+ grid-column: 1 / -1;
962
+ min-block-size: var(--slotted-navigation-menu-viewport-block-size, auto);
963
+ }
964
+
965
+ /**
966
+ * The rule between the second level's list and its open section runs the
967
+ * root's whole height — the taller of the two — rather than the section's,
968
+ * which left a gap under a section shorter than the list.
969
+ */
970
+ [data-ui='navigation-menu'][data-nested]::before {
971
+ background-color: var(--_border-color);
972
+ content: '';
973
+ inline-size: var(--_border-width);
974
+ inset-block: 0;
975
+ inset-inline-start: calc(var(--_nested-list-size) + var(--_inset) / 2);
976
+ position: absolute;
977
+ }
978
+
979
+ [data-ui='navigation-menu'][data-nested] > [data-part='list'] {
980
+ align-self: flex-start;
981
+ inline-size: var(--_nested-list-size);
982
+ }
983
+
984
+ [data-ui='navigation-menu'][data-nested] > [data-part='viewport'] {
985
+ display: none;
986
+ }
987
+
988
+ [data-ui='navigation-menu'][data-nested]
989
+ > [data-part='list']
990
+ > [data-part='item']
991
+ > [data-part='content'] {
992
+ border: 0;
993
+ border-radius: 0;
994
+ clip-path: none;
995
+ inline-size: calc(100% - var(--_nested-list-size) - var(--_inset));
996
+ inset-block-start: 0;
997
+ inset-inline-start: calc(var(--_nested-list-size) + var(--_inset));
998
+ padding-block: 0;
999
+ padding-inline: var(--_inset) 0;
1000
+ }
1001
+
1002
+ /* ── Reduced motion ──────────────────────────────────────────────────── */
1003
+
1004
+ /* Stillness keeps the fades and drops every movement (R7). */
1005
+ @media (prefers-reduced-motion: reduce) {
1006
+ [data-ui='navigation-menu'] > [data-part='viewport'],
1007
+ [data-ui='navigation-menu'][data-orientation='vertical'] > [data-part='viewport'] {
1008
+ translate: 0 0;
1009
+ transition: opacity var(--slotted-duration-short) var(--slotted-easing-exit);
1010
+ }
1011
+
1012
+ [data-ui='navigation-menu'] > [data-part='viewport'][data-open][data-positioned],
1013
+ [data-ui='navigation-menu'][data-orientation='vertical']
1014
+ > [data-part='viewport'][data-open][data-positioned] {
1015
+ animation-name: slotted-navigation-menu-fade;
1016
+ }
1017
+
1018
+ [data-ui='navigation-menu']
1019
+ [data-part='content']:is([data-motion='from-end'], [data-motion='from-start']) {
1020
+ animation-name: slotted-navigation-menu-fade;
1021
+ }
1022
+
1023
+ [data-ui='navigation-menu']
1024
+ [data-part='content']:is([data-motion='to-end'], [data-motion='to-start']) {
1025
+ animation: none;
1026
+ opacity: 0;
1027
+ }
1028
+ }
1029
+ }