@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.
- package/LICENSE +21 -0
- package/README.md +10 -2
- package/package.json +276 -3
- package/src/accordion/accordion.css +96 -0
- package/src/accordion/accordion.tokens.json +14 -0
- package/src/action-bar/action-bar.css +455 -0
- package/src/action-bar/action-bar.tokens.json +50 -0
- package/src/action-sheet/action-sheet.css +462 -0
- package/src/action-sheet/action-sheet.tokens.json +59 -0
- package/src/alert/alert.css +764 -0
- package/src/alert/alert.tokens.json +77 -0
- package/src/app-shell/app-shell.css +1899 -0
- package/src/app-shell/app-shell.tokens.json +88 -0
- package/src/aspect-ratio/aspect-ratio.css +131 -0
- package/src/aspect-ratio/aspect-ratio.tokens.json +1 -0
- package/src/attachment/attachment.css +906 -0
- package/src/attachment/attachment.tokens.json +85 -0
- package/src/avatar/avatar.css +598 -0
- package/src/avatar/avatar.tokens.json +64 -0
- package/src/avatar-group/avatar-group.css +268 -0
- package/src/avatar-group/avatar-group.tokens.json +16 -0
- package/src/badge/badge.css +462 -0
- package/src/badge/badge.tokens.json +58 -0
- package/src/breadcrumb/breadcrumb.css +441 -0
- package/src/breadcrumb/breadcrumb.tokens.json +50 -0
- package/src/button/button.css +754 -0
- package/src/button/button.tokens.json +72 -0
- package/src/button-group/button-group.css +455 -0
- package/src/button-group/button-group.tokens.json +11 -0
- package/src/calendar/calendar.css +846 -0
- package/src/calendar/calendar.tokens.json +67 -0
- package/src/card/card.css +602 -0
- package/src/card/card.tokens.json +68 -0
- package/src/carousel/carousel.css +860 -0
- package/src/carousel/carousel.tokens.json +62 -0
- package/src/cascader/cascader.css +1320 -0
- package/src/cascader/cascader.tokens.json +103 -0
- package/src/chart/chart.css +1473 -0
- package/src/chart/chart.tokens.json +107 -0
- package/src/checkbox/checkbox.css +1011 -0
- package/src/checkbox/checkbox.tokens.json +102 -0
- package/src/checkbox-group/checkbox-group.css +70 -0
- package/src/checkbox-group/checkbox-group.tokens.json +6 -0
- package/src/code-block/code-block.css +555 -0
- package/src/code-block/code-block.tokens.json +69 -0
- package/src/collapsible/collapsible.css +546 -0
- package/src/collapsible/collapsible.tokens.json +55 -0
- package/src/color-picker/color-picker.css +607 -0
- package/src/color-picker/color-picker.tokens.json +58 -0
- package/src/column-manager/column-manager.css +452 -0
- package/src/column-manager/column-manager.tokens.json +43 -0
- package/src/combobox/combobox.css +1048 -0
- package/src/combobox/combobox.tokens.json +112 -0
- package/src/command-palette/command-palette.css +1000 -0
- package/src/command-palette/command-palette.tokens.json +75 -0
- package/src/container/container.css +198 -0
- package/src/container/container.tokens.json +18 -0
- package/src/context-menu/context-menu.css +104 -0
- package/src/context-menu/context-menu.tokens.json +11 -0
- package/src/currency-field/currency-field.css +787 -0
- package/src/currency-field/currency-field.tokens.json +80 -0
- package/src/dashboard-grid/dashboard-grid.css +748 -0
- package/src/dashboard-grid/dashboard-grid.tokens.json +67 -0
- package/src/data-grid/data-grid.css +2484 -0
- package/src/data-grid/data-grid.tokens.json +100 -0
- package/src/data-list/data-list.css +455 -0
- package/src/data-list/data-list.tokens.json +35 -0
- package/src/date-field/date-field.css +560 -0
- package/src/date-field/date-field.tokens.json +80 -0
- package/src/date-picker/date-picker.css +420 -0
- package/src/date-picker/date-picker.tokens.json +49 -0
- package/src/date-range-picker/date-range-picker.css +983 -0
- package/src/date-range-picker/date-range-picker.tokens.json +109 -0
- package/src/datetime-field/datetime-field.css +850 -0
- package/src/datetime-field/datetime-field.tokens.json +91 -0
- package/src/datetime-picker/datetime-picker.css +843 -0
- package/src/datetime-picker/datetime-picker.tokens.json +78 -0
- package/src/datetime-range-picker/datetime-range-picker.css +1375 -0
- package/src/datetime-range-picker/datetime-range-picker.tokens.json +135 -0
- package/src/description-list/description-list.css +675 -0
- package/src/description-list/description-list.tokens.json +66 -0
- package/src/detail-panel/detail-panel.css +329 -0
- package/src/detail-panel/detail-panel.tokens.json +33 -0
- package/src/dialog/dialog.css +968 -0
- package/src/dialog/dialog.tokens.json +66 -0
- package/src/divider/divider.css +131 -0
- package/src/divider/divider.tokens.json +18 -0
- package/src/drawer/drawer.css +1303 -0
- package/src/drawer/drawer.tokens.json +75 -0
- package/src/entity-picker/entity-picker.css +1367 -0
- package/src/entity-picker/entity-picker.tokens.json +118 -0
- package/src/event-calendar/event-calendar.css +2148 -0
- package/src/event-calendar/event-calendar.tokens.json +87 -0
- package/src/field/field.css +707 -0
- package/src/field/field.tokens.json +58 -0
- package/src/field-group/field-group.css +226 -0
- package/src/field-group/field-group.tokens.json +33 -0
- package/src/filter-bar/filter-bar.css +1306 -0
- package/src/filter-bar/filter-bar.tokens.json +78 -0
- package/src/form/form.css +218 -0
- package/src/form/form.tokens.json +32 -0
- package/src/fullscreen/fullscreen.css +376 -0
- package/src/fullscreen/fullscreen.tokens.json +50 -0
- package/src/grid/grid.css +173 -0
- package/src/grid/grid.tokens.json +20 -0
- package/src/highlight/highlight.css +135 -0
- package/src/highlight/highlight.tokens.json +16 -0
- package/src/hover-card/hover-card.css +93 -0
- package/src/hover-card/hover-card.tokens.json +17 -0
- package/src/icon/icon.css +136 -0
- package/src/icon/icon.tokens.json +14 -0
- package/src/image/image.css +449 -0
- package/src/image/image.tokens.json +27 -0
- package/src/import-export-center/import-export-center.css +1175 -0
- package/src/import-export-center/import-export-center.tokens.json +84 -0
- package/src/inline/inline.css +149 -0
- package/src/inline/inline.tokens.json +14 -0
- package/src/inline-message/inline-message.css +396 -0
- package/src/inline-message/inline-message.tokens.json +19 -0
- package/src/kbd/kbd.css +490 -0
- package/src/kbd/kbd.tokens.json +40 -0
- package/src/link/link.css +237 -0
- package/src/link/link.tokens.json +25 -0
- package/src/list/list.css +240 -0
- package/src/list/list.tokens.json +42 -0
- package/src/list-item/list-item.css +937 -0
- package/src/list-item/list-item.tokens.json +114 -0
- package/src/listbox/listbox.css +674 -0
- package/src/listbox/listbox.tokens.json +72 -0
- package/src/loading-overlay/loading-overlay.css +730 -0
- package/src/loading-overlay/loading-overlay.tokens.json +48 -0
- package/src/markdown/markdown.css +168 -0
- package/src/markdown/markdown.tokens.json +18 -0
- package/src/menu/menu.css +817 -0
- package/src/menu/menu.tokens.json +78 -0
- package/src/menubar/menubar.css +170 -0
- package/src/menubar/menubar.tokens.json +32 -0
- package/src/message/message.css +1453 -0
- package/src/message/message.tokens.json +85 -0
- package/src/message-scroller/message-scroller.css +371 -0
- package/src/message-scroller/message-scroller.tokens.json +47 -0
- package/src/multi-select/multi-select.css +1427 -0
- package/src/multi-select/multi-select.tokens.json +114 -0
- package/src/navigation-menu/navigation-menu.css +1029 -0
- package/src/navigation-menu/navigation-menu.tokens.json +70 -0
- package/src/notification-center/notification-center.css +856 -0
- package/src/notification-center/notification-center.tokens.json +84 -0
- package/src/number-field/number-field.css +794 -0
- package/src/number-field/number-field.tokens.json +80 -0
- package/src/otp-input/otp-input.css +525 -0
- package/src/otp-input/otp-input.tokens.json +69 -0
- package/src/page/page.css +179 -0
- package/src/page/page.tokens.json +20 -0
- package/src/page-header/page-header.css +1181 -0
- package/src/page-header/page-header.tokens.json +71 -0
- package/src/pagination/pagination.css +500 -0
- package/src/pagination/pagination.tokens.json +56 -0
- package/src/popover/popover.css +526 -0
- package/src/popover/popover.tokens.json +60 -0
- package/src/progress-indicator/progress-indicator.css +1584 -0
- package/src/progress-indicator/progress-indicator.tokens.json +50 -0
- package/src/prompt-composer/prompt-composer.css +680 -0
- package/src/prompt-composer/prompt-composer.tokens.json +99 -0
- package/src/prose/prose.css +733 -0
- package/src/prose/prose.tokens.json +79 -0
- package/src/radio-group/radio-group.css +778 -0
- package/src/radio-group/radio-group.tokens.json +103 -0
- package/src/rating/rating.css +1071 -0
- package/src/rating/rating.tokens.json +88 -0
- package/src/result-state/result-state.css +980 -0
- package/src/result-state/result-state.tokens.json +63 -0
- package/src/runtime-properties.mjs +321 -0
- package/src/saved-views/saved-views.css +394 -0
- package/src/saved-views/saved-views.tokens.json +41 -0
- package/src/scroll-area/scroll-area.css +481 -0
- package/src/scroll-area/scroll-area.tokens.json +15 -0
- package/src/section/section.css +177 -0
- package/src/section/section.tokens.json +39 -0
- package/src/segmented-control/segmented-control.css +564 -0
- package/src/segmented-control/segmented-control.tokens.json +67 -0
- package/src/select/select.css +1593 -0
- package/src/select/select.tokens.json +110 -0
- package/src/side-navigation/side-navigation.css +1096 -0
- package/src/side-navigation/side-navigation.tokens.json +87 -0
- package/src/skeleton/skeleton.css +431 -0
- package/src/skeleton/skeleton.tokens.json +29 -0
- package/src/slider/slider.css +792 -0
- package/src/slider/slider.tokens.json +75 -0
- package/src/sparkline/sparkline.css +282 -0
- package/src/sparkline/sparkline.tokens.json +45 -0
- package/src/spinner/spinner.css +224 -0
- package/src/spinner/spinner.tokens.json +8 -0
- package/src/split-button/split-button.css +253 -0
- package/src/split-button/split-button.tokens.json +12 -0
- package/src/splitter/splitter.css +336 -0
- package/src/splitter/splitter.tokens.json +24 -0
- package/src/stack/stack.css +128 -0
- package/src/stack/stack.tokens.json +14 -0
- package/src/stat-card/stat-card.css +641 -0
- package/src/stat-card/stat-card.tokens.json +95 -0
- package/src/status-indicator/status-indicator.css +481 -0
- package/src/status-indicator/status-indicator.tokens.json +38 -0
- package/src/stepper/stepper.css +629 -0
- package/src/stepper/stepper.tokens.json +72 -0
- package/src/switch/switch.css +703 -0
- package/src/switch/switch.tokens.json +75 -0
- package/src/table/table.css +1482 -0
- package/src/table/table.tokens.json +69 -0
- package/src/table-of-contents/table-of-contents.css +533 -0
- package/src/table-of-contents/table-of-contents.tokens.json +53 -0
- package/src/tabs/tabs.css +998 -0
- package/src/tabs/tabs.tokens.json +82 -0
- package/src/tag/tag.css +768 -0
- package/src/tag/tag.tokens.json +85 -0
- package/src/tags-input/tags-input.css +757 -0
- package/src/tags-input/tags-input.tokens.json +84 -0
- package/src/text-field/text-field.css +900 -0
- package/src/text-field/text-field.tokens.json +87 -0
- package/src/textarea/textarea.css +365 -0
- package/src/textarea/textarea.tokens.json +59 -0
- package/src/time-field/time-field.css +719 -0
- package/src/time-field/time-field.tokens.json +86 -0
- package/src/time-picker/time-picker.css +665 -0
- package/src/time-picker/time-picker.tokens.json +66 -0
- package/src/time-range-picker/time-range-picker.css +1287 -0
- package/src/time-range-picker/time-range-picker.tokens.json +134 -0
- package/src/timeline/timeline.css +1596 -0
- package/src/timeline/timeline.tokens.json +96 -0
- package/src/toast/toast.css +943 -0
- package/src/toast/toast.tokens.json +90 -0
- package/src/toggle/toggle.css +290 -0
- package/src/toggle/toggle.tokens.json +54 -0
- package/src/toggle-group/toggle-group.css +463 -0
- package/src/toggle-group/toggle-group.tokens.json +54 -0
- package/src/toolbar/toolbar.css +434 -0
- package/src/toolbar/toolbar.tokens.json +49 -0
- package/src/tooltip/tooltip.css +368 -0
- package/src/tooltip/tooltip.tokens.json +39 -0
- package/src/top-navigation/top-navigation.css +1287 -0
- package/src/top-navigation/top-navigation.tokens.json +91 -0
- package/src/tour/tour.css +680 -0
- package/src/tour/tour.tokens.json +67 -0
- package/src/transfer/transfer.css +571 -0
- package/src/transfer/transfer.tokens.json +49 -0
- package/src/tree/tree.css +1000 -0
- package/src/tree/tree.tokens.json +80 -0
- package/src/typography/typography.css +211 -0
- package/src/typography/typography.tokens.json +31 -0
- package/src/upload/upload.css +1706 -0
- package/src/upload/upload.tokens.json +123 -0
- package/src/visually-hidden/visually-hidden.css +52 -0
- package/src/visually-hidden/visually-hidden.tokens.json +1 -0
- package/src/wizard/wizard.css +740 -0
- package/src/wizard/wizard.tokens.json +63 -0
|
@@ -0,0 +1,1287 @@
|
|
|
1
|
+
@layer slotted.components {
|
|
2
|
+
/**
|
|
3
|
+
* The bar across the top of an application: the mark, what the application
|
|
4
|
+
* is right now, the destinations, the search, and the global actions —
|
|
5
|
+
* reading its own width and folding by priority as the width goes.
|
|
6
|
+
*
|
|
7
|
+
* root ▸ skip · brand ▸ home ▸ mark · name
|
|
8
|
+
* · context
|
|
9
|
+
* · nav ▸ list ▸ item ▸ link | trigger ▸ indicator
|
|
10
|
+
* ▸ item ▸ more
|
|
11
|
+
* · panel ▸ context · panel-list ▸ item… · help
|
|
12
|
+
* · search ▸ … · search-close
|
|
13
|
+
* · actions ▸ search-toggle · help · notifications ▸ count · account
|
|
14
|
+
*
|
|
15
|
+
* ── The bar folds by container query ────────────────────────────────────
|
|
16
|
+
*
|
|
17
|
+
* Three literal steps, declared in the contract as `collapseAt` and compared
|
|
18
|
+
* by `top-navigation.styles.test.mjs`: below 1024 the low-priority items
|
|
19
|
+
* leave the list, below 600 the medium ones, the search becomes its toggle
|
|
20
|
+
* and the context moves to the panel, below 480 the high ones and the help
|
|
21
|
+
* go with them and the name leaves the eye. The stylesheet decides the whole picture from the
|
|
22
|
+
* width; the script that comes later writes `data-collapsed` from the same
|
|
23
|
+
* three numbers, counts what folded onto `more`, and moves the folded parts
|
|
24
|
+
* into the panel while it is open.
|
|
25
|
+
*
|
|
26
|
+
* ── The panel is the same DOM ───────────────────────────────────────────
|
|
27
|
+
*
|
|
28
|
+
* What folds is not rebuilt: the consumer's `li` is moved (Angular) or
|
|
29
|
+
* portalled (React) into `panel-list`, so a trigger keeps the menu wrapped
|
|
30
|
+
* around it and a link keeps the badge inside it. The panel stands inside
|
|
31
|
+
* the root and after `more` in DOM order, which is what lets Tab enter it.
|
|
32
|
+
*
|
|
33
|
+
* ── Geometry is the shell's where the shell is ──────────────────────────
|
|
34
|
+
*
|
|
35
|
+
* `brand` starts on `--slotted-app-shell-row-inset` so the shell's toggle
|
|
36
|
+
* and the mark stand over the marks in the navigation column, and the
|
|
37
|
+
* panel's rows read the row the shell publishes so a folded destination
|
|
38
|
+
* reads as the row it would be in `side-navigation`. Outside the shell the
|
|
39
|
+
* fallbacks are the control scale.
|
|
40
|
+
*/
|
|
41
|
+
[data-ui='top-navigation'] {
|
|
42
|
+
--_control-height: var(--slotted-control-height-md, 34px);
|
|
43
|
+
--_control-padding: var(--slotted-control-padding-inline-md, 13px);
|
|
44
|
+
--_control-font-size: var(--slotted-control-font-size-md, 13px);
|
|
45
|
+
--_icon-size: var(--slotted-control-icon-size-md, 16px);
|
|
46
|
+
--_gap: var(--slotted-control-gap-md, 8px);
|
|
47
|
+
--_action-gap: var(--slotted-control-gap-sm, 6px);
|
|
48
|
+
/** The start inset the shell publishes; nothing outside it. */
|
|
49
|
+
--_row-inset: var(--slotted-app-shell-row-inset, 0px);
|
|
50
|
+
--_row-height: var(--slotted-app-shell-row-height, var(--slotted-control-height-md, 34px));
|
|
51
|
+
--_row-font-size: var(
|
|
52
|
+
--slotted-app-shell-row-font-size,
|
|
53
|
+
var(--slotted-font-size-sm, 0.8125rem)
|
|
54
|
+
);
|
|
55
|
+
--_row-line-height: var(
|
|
56
|
+
--slotted-app-shell-row-line-height,
|
|
57
|
+
var(--slotted-line-height-sm, 1.45)
|
|
58
|
+
);
|
|
59
|
+
--_inset: var(--slotted-top-navigation-inset, var(--slotted-space-5, 0.75rem));
|
|
60
|
+
--_block-size: var(
|
|
61
|
+
--slotted-top-navigation-block-size,
|
|
62
|
+
calc(var(--slotted-control-height-lg, 38px) + var(--slotted-space-5, 0.75rem) * 2)
|
|
63
|
+
);
|
|
64
|
+
--_radius: var(--slotted-top-navigation-radius, var(--slotted-control-radius, 4px));
|
|
65
|
+
--_name-font-size: var(
|
|
66
|
+
--slotted-top-navigation-name-font-size,
|
|
67
|
+
var(--slotted-font-size-md, 0.875rem)
|
|
68
|
+
);
|
|
69
|
+
--_name-max: var(--slotted-top-navigation-name-max, 16rem);
|
|
70
|
+
--_search-size: var(--slotted-top-navigation-search-size, 28rem);
|
|
71
|
+
/** The floor a field is still a field at: nine characters and the shortcut. */
|
|
72
|
+
--_search-min: var(--slotted-top-navigation-search-min, 10rem);
|
|
73
|
+
/** The inset a framed bar carries at both ends; nought inside the shell, which insets the banner itself. */
|
|
74
|
+
--_edge: 0px;
|
|
75
|
+
--_panel-size: var(--slotted-top-navigation-panel-size, 20rem);
|
|
76
|
+
--_mark-size: calc(var(--_control-height) - var(--slotted-space-2, 0.25rem) * 2);
|
|
77
|
+
|
|
78
|
+
--_surface: var(--slotted-top-navigation-surface, var(--slotted-surface, Canvas));
|
|
79
|
+
--_color: var(--slotted-top-navigation-color, var(--slotted-text, CanvasText));
|
|
80
|
+
--_muted-color: var(--slotted-top-navigation-muted-color, var(--slotted-text-muted, GrayText));
|
|
81
|
+
--_border-color: var(
|
|
82
|
+
--slotted-top-navigation-border-color,
|
|
83
|
+
var(--slotted-border-subtle, ButtonBorder)
|
|
84
|
+
);
|
|
85
|
+
--_hover-background: var(
|
|
86
|
+
--slotted-top-navigation-hover-background,
|
|
87
|
+
var(--slotted-tone-secondary-subtle-hover)
|
|
88
|
+
);
|
|
89
|
+
--_active-background: var(
|
|
90
|
+
--slotted-top-navigation-active-background,
|
|
91
|
+
var(--slotted-tone-secondary-subtle-active)
|
|
92
|
+
);
|
|
93
|
+
--_current-color: var(--slotted-top-navigation-current-color, var(--slotted-tone-accent-text));
|
|
94
|
+
--_current-background: var(
|
|
95
|
+
--slotted-top-navigation-current-background,
|
|
96
|
+
var(--slotted-tone-accent-surface)
|
|
97
|
+
);
|
|
98
|
+
/**
|
|
99
|
+
* The state is a pair, ground and edge, for the reason `side-navigation`
|
|
100
|
+
* gives: the foundation's `--slotted-current-edge` is transparent where the
|
|
101
|
+
* tone ground says the state and black in `high-contrast`, where every tone
|
|
102
|
+
* ground is the page's white. Drawn as an inset shadow, so nothing moves.
|
|
103
|
+
*/
|
|
104
|
+
--_current-edge: var(
|
|
105
|
+
--slotted-top-navigation-current-edge,
|
|
106
|
+
var(--slotted-current-edge, transparent)
|
|
107
|
+
);
|
|
108
|
+
--_count-background: var(
|
|
109
|
+
--slotted-top-navigation-count-background,
|
|
110
|
+
var(--slotted-tone-accent-solid)
|
|
111
|
+
);
|
|
112
|
+
--_count-color: var(--slotted-top-navigation-count-color, var(--slotted-tone-accent-on-solid));
|
|
113
|
+
--_panel-surface: var(
|
|
114
|
+
--slotted-top-navigation-panel-surface,
|
|
115
|
+
var(--slotted-surface-raised, Canvas)
|
|
116
|
+
);
|
|
117
|
+
--_panel-shadow: var(--slotted-top-navigation-panel-shadow, var(--slotted-shadow-md));
|
|
118
|
+
--_panel-radius: var(--slotted-top-navigation-panel-radius, var(--slotted-radius-lg, 8px));
|
|
119
|
+
--_disabled-color: var(--slotted-disabled-foreground, GrayText);
|
|
120
|
+
--_rule-width: var(--slotted-border-width-thin, 1px);
|
|
121
|
+
|
|
122
|
+
--_duration: var(--slotted-control-transition-duration, var(--slotted-duration-short));
|
|
123
|
+
--_easing: var(--slotted-control-transition-easing, var(--slotted-easing-standard));
|
|
124
|
+
|
|
125
|
+
align-items: center;
|
|
126
|
+
box-sizing: border-box;
|
|
127
|
+
color: var(--_color);
|
|
128
|
+
container-name: slotted-top-navigation;
|
|
129
|
+
container-type: inline-size;
|
|
130
|
+
display: flex;
|
|
131
|
+
font-family: var(--slotted-control-font-family, inherit);
|
|
132
|
+
font-size: var(--_control-font-size);
|
|
133
|
+
gap: var(--_gap);
|
|
134
|
+
line-height: var(--slotted-control-line-height, 1);
|
|
135
|
+
min-block-size: var(--_control-height);
|
|
136
|
+
min-inline-size: 0;
|
|
137
|
+
/* The panel's containing block, and a flex item that fills the shell's banner. */
|
|
138
|
+
flex: 1 1 auto;
|
|
139
|
+
position: relative;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Standing alone the bar paints its own ground, a rule along its end edge
|
|
144
|
+
* and its own inset; inside the shell the banner already does all three,
|
|
145
|
+
* and the bar paints nothing over what the shell painted.
|
|
146
|
+
*
|
|
147
|
+
* The inset is not padding on the root. A container query resolves against
|
|
148
|
+
* the container's content box, and the width gate in the script measures
|
|
149
|
+
* the border box: with twelve pixels of padding a side the stylesheet folded
|
|
150
|
+
* at 1048 and the script at 1024, and a bar in a room of exactly 1024 drew
|
|
151
|
+
* `more` for two items the script said were in the list. So the root's
|
|
152
|
+
* content box is its border box, and the first and last clusters carry the
|
|
153
|
+
* edge — `--_edge`, nought inside the shell — beside the shell's row inset.
|
|
154
|
+
*/
|
|
155
|
+
[data-ui='top-navigation'][data-frame] {
|
|
156
|
+
--_edge: var(--_inset);
|
|
157
|
+
|
|
158
|
+
background-color: var(--_surface);
|
|
159
|
+
border-block-end: var(--_rule-width) solid var(--_border-color);
|
|
160
|
+
min-block-size: var(--_block-size);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
[data-ui='top-navigation'][data-size='sm'] {
|
|
164
|
+
--_control-height: var(--slotted-control-height-sm, 30px);
|
|
165
|
+
--_control-padding: var(--slotted-control-padding-inline-sm, 10px);
|
|
166
|
+
--_control-font-size: var(--slotted-control-font-size-sm, 12px);
|
|
167
|
+
--_icon-size: var(--slotted-control-icon-size-sm, 14px);
|
|
168
|
+
--_gap: var(--slotted-control-gap-sm, 6px);
|
|
169
|
+
--_action-gap: var(--slotted-control-gap-sm, 6px);
|
|
170
|
+
--_row-height: var(--slotted-control-height-sm, 30px);
|
|
171
|
+
--_row-font-size: var(--slotted-font-size-xs, 0.75rem);
|
|
172
|
+
--_row-line-height: var(--slotted-line-height-xs, 1.4);
|
|
173
|
+
--_name-font-size: var(
|
|
174
|
+
--slotted-top-navigation-name-font-size,
|
|
175
|
+
var(--slotted-font-size-sm, 0.8125rem)
|
|
176
|
+
);
|
|
177
|
+
--_block-size: var(
|
|
178
|
+
--slotted-top-navigation-block-size,
|
|
179
|
+
calc(var(--slotted-control-height-md, 34px) + var(--slotted-space-4, 0.5rem) * 2)
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
[data-ui='top-navigation'][data-size='lg'] {
|
|
184
|
+
--_control-height: var(--slotted-control-height-lg, 38px);
|
|
185
|
+
--_control-padding: var(--slotted-control-padding-inline-lg, 16px);
|
|
186
|
+
--_control-font-size: var(--slotted-control-font-size-lg, 14px);
|
|
187
|
+
--_icon-size: var(--slotted-control-icon-size-lg, 18px);
|
|
188
|
+
--_gap: var(--slotted-control-gap-lg, 8px);
|
|
189
|
+
--_action-gap: var(--slotted-control-gap-md, 8px);
|
|
190
|
+
--_row-height: var(--slotted-control-height-lg, 38px);
|
|
191
|
+
--_row-font-size: var(--slotted-font-size-md, 0.875rem);
|
|
192
|
+
--_row-line-height: var(--slotted-line-height-md, 1.5);
|
|
193
|
+
--_name-font-size: var(
|
|
194
|
+
--slotted-top-navigation-name-font-size,
|
|
195
|
+
var(--slotted-font-size-lg, 1rem)
|
|
196
|
+
);
|
|
197
|
+
--_block-size: var(
|
|
198
|
+
--slotted-top-navigation-block-size,
|
|
199
|
+
calc(var(--slotted-control-height-lg, 38px) + var(--slotted-space-6, 1rem) * 2)
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* ── The skip link ──────────────────────────────────────────────────────── */
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Out of sight until it holds focus, and then a control at the start of the
|
|
207
|
+
* bar, on the bar's own ground: a reader tabbing into the page sees where
|
|
208
|
+
* they are before they see anything else.
|
|
209
|
+
*/
|
|
210
|
+
[data-ui='top-navigation'] > [data-part='skip'] {
|
|
211
|
+
background-color: var(--_surface);
|
|
212
|
+
block-size: var(--_control-height);
|
|
213
|
+
border-radius: var(--_radius);
|
|
214
|
+
box-sizing: border-box;
|
|
215
|
+
clip-path: inset(50%);
|
|
216
|
+
color: var(--_color);
|
|
217
|
+
display: inline-flex;
|
|
218
|
+
align-items: center;
|
|
219
|
+
font-weight: var(--slotted-font-weight-semibold, 600);
|
|
220
|
+
inset-block-start: 50%;
|
|
221
|
+
inset-inline-start: var(--_edge);
|
|
222
|
+
padding-inline: var(--_control-padding);
|
|
223
|
+
position: absolute;
|
|
224
|
+
text-decoration: none;
|
|
225
|
+
translate: 0 -50%;
|
|
226
|
+
white-space: nowrap;
|
|
227
|
+
z-index: 1;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
[data-ui='top-navigation'] > [data-part='skip']:focus-visible {
|
|
231
|
+
clip-path: none;
|
|
232
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
233
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* ── Brand ──────────────────────────────────────────────────────────────── */
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* The root part is named in the selector for one reason: `app-shell` styles
|
|
240
|
+
* its own brand cluster with a descendant selector,
|
|
241
|
+
* `[data-ui='app-shell'] [data-part='brand']`, which reaches this part when
|
|
242
|
+
* the bar stands in the shell's banner and clips `home` to a sliver at 240
|
|
243
|
+
* pixels. Naming the root outranks it. The shell's own reopening narrows
|
|
244
|
+
* that selector to its banner; until then the two declarations it leaks —
|
|
245
|
+
* the inset, and the overflow on every child — are restated here.
|
|
246
|
+
*/
|
|
247
|
+
/**
|
|
248
|
+
* No `min-inline-size: 0` here: the cluster's minimum is its automatic one,
|
|
249
|
+
* the marks it holds, which `home` below contributes without the name. At
|
|
250
|
+
* nought it shrank under its own marks on a phone whose actions held seven
|
|
251
|
+
* touch-sized controls, and the marks spilled over the cluster beside it.
|
|
252
|
+
*/
|
|
253
|
+
[data-ui='top-navigation'][data-part='root'] > [data-part='brand'] {
|
|
254
|
+
align-items: center;
|
|
255
|
+
display: flex;
|
|
256
|
+
flex: 0 1 auto;
|
|
257
|
+
font-weight: inherit;
|
|
258
|
+
gap: var(--_gap);
|
|
259
|
+
padding-inline-start: calc(var(--_edge) + var(--_row-inset));
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
[data-ui='top-navigation'][data-part='root'] > [data-part='brand'] > [data-part='home'] {
|
|
263
|
+
min-inline-size: var(--_control-height);
|
|
264
|
+
overflow: visible;
|
|
265
|
+
white-space: normal;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
[data-ui='top-navigation'] [data-part='home'] {
|
|
269
|
+
align-items: center;
|
|
270
|
+
border-radius: var(--_radius);
|
|
271
|
+
color: var(--_color);
|
|
272
|
+
/*
|
|
273
|
+
* A grid of two tracks, the mark's and the name's, rather than a flex row.
|
|
274
|
+
* The name gives way to its ellipsis and, past it, to the mark alone —
|
|
275
|
+
* the mark never does. As a flex row that order could not be stated: a
|
|
276
|
+
* flex item's minimum is its content's contribution, which for a nowrap
|
|
277
|
+
* string is the whole string, so a floor on the name became a floor on
|
|
278
|
+
* the cluster and the bar overflowed at its end. A `minmax(0, 1fr)` track
|
|
279
|
+
* contributes nothing to the grid's min-content size, so the link's
|
|
280
|
+
* minimum is the mark's track and the name still shrinks to its ellipsis
|
|
281
|
+
* inside its own.
|
|
282
|
+
*/
|
|
283
|
+
display: inline-grid;
|
|
284
|
+
flex: 0 1 auto;
|
|
285
|
+
gap: var(--_gap);
|
|
286
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
287
|
+
min-block-size: var(--_control-height);
|
|
288
|
+
/*
|
|
289
|
+
* A bar whose priorities leave it short of room loses the name before it
|
|
290
|
+
* loses a control, which is the order the name's own step at 480 already sets.
|
|
291
|
+
*/
|
|
292
|
+
min-inline-size: var(--_control-height);
|
|
293
|
+
text-decoration: none;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
[data-ui='top-navigation'] [data-part='home']:focus-visible {
|
|
297
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
298
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/** A square the mark is centred in, the height of the bar's controls. */
|
|
302
|
+
[data-ui='top-navigation'] [data-part='mark'] {
|
|
303
|
+
align-items: center;
|
|
304
|
+
block-size: var(--_control-height);
|
|
305
|
+
display: inline-flex;
|
|
306
|
+
flex: 0 0 auto;
|
|
307
|
+
inline-size: var(--_control-height);
|
|
308
|
+
justify-content: center;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
[data-ui='top-navigation'] [data-part='mark'] > :is(svg, img) {
|
|
312
|
+
block-size: var(--_mark-size);
|
|
313
|
+
inline-size: var(--_mark-size);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* One line. It ends in an ellipsis rather than pushing the bar wider than
|
|
318
|
+
* the space there is — the rule `app-shell` states for its own brand.
|
|
319
|
+
*/
|
|
320
|
+
[data-ui='top-navigation'] [data-part='name'] {
|
|
321
|
+
font-size: var(--_name-font-size);
|
|
322
|
+
font-weight: var(--slotted-font-weight-semibold, 600);
|
|
323
|
+
max-inline-size: var(--_name-max);
|
|
324
|
+
min-inline-size: 0;
|
|
325
|
+
overflow: hidden;
|
|
326
|
+
text-overflow: ellipsis;
|
|
327
|
+
white-space: nowrap;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/* ── Context ────────────────────────────────────────────────────────────── */
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* What gives way when the bar is short of room, and in which order: the
|
|
334
|
+
* search shrinks first, to the floor a field is still a field at; then the
|
|
335
|
+
* name, to its ellipsis. The context, the destinations and the actions keep
|
|
336
|
+
* their width — a workspace switcher wrapped one letter per line, which is
|
|
337
|
+
* what a shrinking cluster does to a button — and the steps below are what
|
|
338
|
+
* takes their room back.
|
|
339
|
+
*/
|
|
340
|
+
[data-ui='top-navigation'] [data-part='context'] {
|
|
341
|
+
align-items: center;
|
|
342
|
+
display: flex;
|
|
343
|
+
flex: 0 0 auto;
|
|
344
|
+
gap: var(--_action-gap);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/* ── Navigation ─────────────────────────────────────────────────────────── */
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* The nav part is also a `navigation-menu` root, which declares private
|
|
351
|
+
* variables of the same names on the same element. The bar's own values are
|
|
352
|
+
* inherited back, so the bar's rows and the sections' panels read the bar's
|
|
353
|
+
* tokens — one bar, one set of decisions.
|
|
354
|
+
*/
|
|
355
|
+
[data-ui='top-navigation'] [data-part='nav'] {
|
|
356
|
+
--_control-height: inherit;
|
|
357
|
+
--_control-padding: inherit;
|
|
358
|
+
--_control-font-size: inherit;
|
|
359
|
+
--_icon-size: inherit;
|
|
360
|
+
--_gap: inherit;
|
|
361
|
+
--_radius: inherit;
|
|
362
|
+
--_color: inherit;
|
|
363
|
+
--_muted-color: inherit;
|
|
364
|
+
--_hover-background: inherit;
|
|
365
|
+
--_active-background: inherit;
|
|
366
|
+
--_current-color: inherit;
|
|
367
|
+
--_current-background: inherit;
|
|
368
|
+
--_current-edge: inherit;
|
|
369
|
+
--_disabled-color: inherit;
|
|
370
|
+
--_duration: inherit;
|
|
371
|
+
--_easing: inherit;
|
|
372
|
+
|
|
373
|
+
display: flex;
|
|
374
|
+
flex: 0 0 auto;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
[data-ui='top-navigation'] [data-part='list'] {
|
|
378
|
+
align-items: center;
|
|
379
|
+
display: flex;
|
|
380
|
+
gap: var(--slotted-space-1, 0.125rem);
|
|
381
|
+
list-style: none;
|
|
382
|
+
margin: 0;
|
|
383
|
+
min-inline-size: 0;
|
|
384
|
+
padding: 0;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
[data-ui='top-navigation'] [data-part='item'] {
|
|
388
|
+
display: flex;
|
|
389
|
+
flex: 0 0 auto;
|
|
390
|
+
min-inline-size: 0;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* A destination and a section share one row: the control's height and
|
|
395
|
+
* inset, the page's ink at rest and a ground under the pointer. The ink is
|
|
396
|
+
* the page's rather than the muted step because a disabled row has to read
|
|
397
|
+
* as one beside its neighbours, and the disabled ink is one step from the
|
|
398
|
+
* muted ink in `light`; the icon-only controls stay muted, the way Carbon's
|
|
399
|
+
* global actions do, because a mark carries less weight than a word.
|
|
400
|
+
*/
|
|
401
|
+
[data-ui='top-navigation']
|
|
402
|
+
:is([data-part='nav'] > [data-part='list'], [data-part='panel-list'])
|
|
403
|
+
> [data-part='item']
|
|
404
|
+
> :is([data-part='link'], [data-part='trigger']) {
|
|
405
|
+
align-items: center;
|
|
406
|
+
appearance: none;
|
|
407
|
+
background-color: transparent;
|
|
408
|
+
border: 0;
|
|
409
|
+
border-radius: var(--_radius);
|
|
410
|
+
box-sizing: border-box;
|
|
411
|
+
color: var(--_color);
|
|
412
|
+
cursor: pointer;
|
|
413
|
+
display: inline-flex;
|
|
414
|
+
font: inherit;
|
|
415
|
+
font-weight: var(--slotted-font-weight-medium, 500);
|
|
416
|
+
gap: var(--_action-gap);
|
|
417
|
+
margin: 0;
|
|
418
|
+
min-block-size: var(--_control-height);
|
|
419
|
+
padding-block: 0;
|
|
420
|
+
padding-inline: var(--_control-padding);
|
|
421
|
+
text-decoration: none;
|
|
422
|
+
transition:
|
|
423
|
+
background-color var(--_duration) var(--_easing),
|
|
424
|
+
color var(--_duration) var(--_easing);
|
|
425
|
+
white-space: nowrap;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
[data-ui='top-navigation']
|
|
429
|
+
[data-part='item']:not([data-disabled])
|
|
430
|
+
> [data-part='link']:not([data-current], [aria-current='page']):hover,
|
|
431
|
+
[data-ui='top-navigation']
|
|
432
|
+
[data-part='item']:not([data-disabled])
|
|
433
|
+
> [data-part='trigger']:enabled:hover {
|
|
434
|
+
background-color: var(--_hover-background);
|
|
435
|
+
color: var(--_color);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
[data-ui='top-navigation']
|
|
439
|
+
[data-part='item']:not([data-disabled])
|
|
440
|
+
> [data-part='link']:not([data-current], [aria-current='page']):active,
|
|
441
|
+
[data-ui='top-navigation']
|
|
442
|
+
[data-part='item']:not([data-disabled])
|
|
443
|
+
> [data-part='trigger']:enabled:active {
|
|
444
|
+
background-color: var(--_active-background);
|
|
445
|
+
color: var(--_color);
|
|
446
|
+
transition-duration: var(--slotted-duration-instant);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* A section that is open holds the ground the pointer gave it. `data-open`
|
|
451
|
+
* is written on the trigger by the consumer's `menu`, whose trigger the
|
|
452
|
+
* family's part is rendered as, so the family wires nothing for it.
|
|
453
|
+
*/
|
|
454
|
+
[data-ui='top-navigation']
|
|
455
|
+
[data-part='item']:not([data-disabled])
|
|
456
|
+
> [data-part='trigger'][data-open]:enabled {
|
|
457
|
+
background-color: var(--_hover-background);
|
|
458
|
+
color: var(--_color);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Current by the family's own attribute, or by the `aria-current` a router
|
|
463
|
+
* wrote on the anchor it rendered: React cannot read the DOM back, so a
|
|
464
|
+
* router link rendered through `render` says where the reader is in the one
|
|
465
|
+
* attribute it owns, and the stylesheet reads it as the same state.
|
|
466
|
+
*/
|
|
467
|
+
[data-ui='top-navigation']
|
|
468
|
+
:is([data-part='nav'] > [data-part='list'], [data-part='panel-list'])
|
|
469
|
+
> [data-part='item']
|
|
470
|
+
> [data-part='link']:is([data-current], [aria-current='page']) {
|
|
471
|
+
background-color: var(--_current-background);
|
|
472
|
+
box-shadow: inset 0 0 0 var(--_rule-width) var(--_current-edge);
|
|
473
|
+
color: var(--_current-color);
|
|
474
|
+
font-weight: var(--slotted-font-weight-semibold, 600);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
[data-ui='top-navigation']
|
|
478
|
+
:is([data-part='nav'] > [data-part='list'], [data-part='panel-list'])
|
|
479
|
+
> [data-part='item'][data-disabled]
|
|
480
|
+
> [data-part='link'],
|
|
481
|
+
[data-ui='top-navigation']
|
|
482
|
+
:is([data-part='nav'] > [data-part='list'], [data-part='panel-list'])
|
|
483
|
+
> [data-part='item']
|
|
484
|
+
> [data-part='trigger']:disabled {
|
|
485
|
+
color: var(--_disabled-color);
|
|
486
|
+
cursor: not-allowed;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
[data-ui='top-navigation']
|
|
490
|
+
:is([data-part='nav'] > [data-part='list'], [data-part='panel-list'])
|
|
491
|
+
> [data-part='item']
|
|
492
|
+
> :is([data-part='link'], [data-part='trigger']):focus-visible {
|
|
493
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
494
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* The chevron says a section opens below the bar — the promise `select`
|
|
499
|
+
* makes with the same mark — and turns half a turn while it is open. It is
|
|
500
|
+
* the `chevron-down` Glyph element the binding renders in the part. Down is
|
|
501
|
+
* down in both directions, so its box is not `directional`.
|
|
502
|
+
*/
|
|
503
|
+
[data-ui='top-navigation']
|
|
504
|
+
:is([data-part='nav'] > [data-part='list'], [data-part='panel-list'])
|
|
505
|
+
> [data-part='item']
|
|
506
|
+
> [data-part='trigger']
|
|
507
|
+
> [data-part='indicator'] {
|
|
508
|
+
--slotted-icon-size: var(--_icon-size);
|
|
509
|
+
|
|
510
|
+
display: flex;
|
|
511
|
+
flex: 0 0 auto;
|
|
512
|
+
margin-inline-end: calc(-1 * var(--slotted-space-2, 0.25rem));
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
[data-ui='top-navigation']
|
|
516
|
+
:is([data-part='nav'] > [data-part='list'], [data-part='panel-list'])
|
|
517
|
+
> [data-part='item']
|
|
518
|
+
> [data-part='trigger']
|
|
519
|
+
> [data-part='indicator']
|
|
520
|
+
> [data-ui='icon'] {
|
|
521
|
+
transition: rotate var(--slotted-duration-medium) var(--_easing);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
[data-ui='top-navigation']
|
|
525
|
+
[data-part='trigger'][data-open]
|
|
526
|
+
> [data-part='indicator']
|
|
527
|
+
> [data-ui='icon'] {
|
|
528
|
+
rotate: 0.5turn;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/* ── Icon-only controls ─────────────────────────────────────────────────── */
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* One shape for every control the family draws a mark on: a square the
|
|
535
|
+
* control's height, no frame at rest, the ground under the pointer, the
|
|
536
|
+
* mark a Glyph element the binding renders in the control's own ink.
|
|
537
|
+
* `action` is the same shape for a global control the family did not
|
|
538
|
+
* foresee — approvals, tasks — with the consumer's own glyph where the
|
|
539
|
+
* family's would be, so the cluster is one row of equals and not four of
|
|
540
|
+
* the family's beside three of another.
|
|
541
|
+
*/
|
|
542
|
+
[data-ui='top-navigation']
|
|
543
|
+
:is(
|
|
544
|
+
[data-part='more'],
|
|
545
|
+
[data-part='search-toggle'],
|
|
546
|
+
[data-part='search-close'],
|
|
547
|
+
[data-part='help'],
|
|
548
|
+
[data-part='notifications'],
|
|
549
|
+
[data-part='account'],
|
|
550
|
+
[data-part='action']
|
|
551
|
+
) {
|
|
552
|
+
align-items: center;
|
|
553
|
+
appearance: none;
|
|
554
|
+
background-color: transparent;
|
|
555
|
+
border: 0;
|
|
556
|
+
border-radius: var(--_radius);
|
|
557
|
+
box-sizing: border-box;
|
|
558
|
+
color: var(--_muted-color);
|
|
559
|
+
cursor: pointer;
|
|
560
|
+
display: inline-flex;
|
|
561
|
+
flex: 0 0 auto;
|
|
562
|
+
font: inherit;
|
|
563
|
+
font-weight: var(--slotted-font-weight-medium, 500);
|
|
564
|
+
gap: var(--_action-gap);
|
|
565
|
+
justify-content: center;
|
|
566
|
+
margin: 0;
|
|
567
|
+
min-block-size: var(--_control-height);
|
|
568
|
+
min-inline-size: var(--_control-height);
|
|
569
|
+
padding: 0;
|
|
570
|
+
position: relative;
|
|
571
|
+
text-decoration: none;
|
|
572
|
+
transition:
|
|
573
|
+
background-color var(--_duration) var(--_easing),
|
|
574
|
+
color var(--_duration) var(--_easing);
|
|
575
|
+
white-space: nowrap;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* The family's marks — `ellipsis`, `search`, `x`, `circle-question` and
|
|
580
|
+
* `bell` — are sized by the control they stand in.
|
|
581
|
+
*/
|
|
582
|
+
[data-ui='top-navigation']
|
|
583
|
+
:is(
|
|
584
|
+
[data-part='more'],
|
|
585
|
+
[data-part='search-toggle'],
|
|
586
|
+
[data-part='search-close'],
|
|
587
|
+
[data-part='help'],
|
|
588
|
+
[data-part='notifications']
|
|
589
|
+
) {
|
|
590
|
+
--slotted-icon-size: var(--_icon-size);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* The glyph inside an action is the consumer's, and the control sizes it:
|
|
595
|
+
* an icon box reads `--slotted-icon-size` from the control, a bare glyph
|
|
596
|
+
* host such as `ng-icon` reads the font-size the child rule gives it. The
|
|
597
|
+
* count stands out of the flow and is not the glyph.
|
|
598
|
+
*/
|
|
599
|
+
[data-ui='top-navigation'] [data-part='action'] {
|
|
600
|
+
--slotted-icon-size: var(--_icon-size);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
[data-ui='top-navigation'] [data-part='action'] > :not([data-part='count']) {
|
|
604
|
+
block-size: var(--_icon-size);
|
|
605
|
+
flex: 0 0 auto;
|
|
606
|
+
font-size: var(--_icon-size);
|
|
607
|
+
inline-size: var(--_icon-size);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
[data-ui='top-navigation']
|
|
611
|
+
:is(
|
|
612
|
+
[data-part='more'],
|
|
613
|
+
[data-part='search-toggle'],
|
|
614
|
+
[data-part='search-close'],
|
|
615
|
+
[data-part='notifications'],
|
|
616
|
+
[data-part='account']
|
|
617
|
+
):enabled:hover,
|
|
618
|
+
[data-ui='top-navigation']
|
|
619
|
+
a:is([data-part='help'], [data-part='action']):not([data-disabled]):hover,
|
|
620
|
+
[data-ui='top-navigation'] button:is([data-part='help'], [data-part='action']):enabled:hover {
|
|
621
|
+
background-color: var(--_hover-background);
|
|
622
|
+
color: var(--_color);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
[data-ui='top-navigation']
|
|
626
|
+
:is(
|
|
627
|
+
[data-part='more'],
|
|
628
|
+
[data-part='search-toggle'],
|
|
629
|
+
[data-part='search-close'],
|
|
630
|
+
[data-part='notifications'],
|
|
631
|
+
[data-part='account']
|
|
632
|
+
):enabled:active,
|
|
633
|
+
[data-ui='top-navigation']
|
|
634
|
+
a:is([data-part='help'], [data-part='action']):not([data-disabled]):active,
|
|
635
|
+
[data-ui='top-navigation'] button:is([data-part='help'], [data-part='action']):enabled:active {
|
|
636
|
+
background-color: var(--_active-background);
|
|
637
|
+
color: var(--_color);
|
|
638
|
+
transition-duration: var(--slotted-duration-instant);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/** A control whose layer is open holds the ground the pointer gave it. */
|
|
642
|
+
[data-ui='top-navigation']
|
|
643
|
+
:is(
|
|
644
|
+
[data-part='more'],
|
|
645
|
+
[data-part='notifications'],
|
|
646
|
+
[data-part='account'],
|
|
647
|
+
[data-part='help'],
|
|
648
|
+
[data-part='action']
|
|
649
|
+
)[data-open] {
|
|
650
|
+
background-color: var(--_hover-background);
|
|
651
|
+
color: var(--_color);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
[data-ui='top-navigation']
|
|
655
|
+
:is(
|
|
656
|
+
[data-part='more'],
|
|
657
|
+
[data-part='search-toggle'],
|
|
658
|
+
[data-part='search-close'],
|
|
659
|
+
[data-part='help'],
|
|
660
|
+
[data-part='notifications'],
|
|
661
|
+
[data-part='account'],
|
|
662
|
+
[data-part='action']
|
|
663
|
+
):focus-visible {
|
|
664
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
665
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
[data-ui='top-navigation']
|
|
669
|
+
:is(
|
|
670
|
+
[data-part='more'],
|
|
671
|
+
[data-part='search-toggle'],
|
|
672
|
+
[data-part='search-close'],
|
|
673
|
+
[data-part='notifications'],
|
|
674
|
+
[data-part='account']
|
|
675
|
+
):disabled,
|
|
676
|
+
[data-ui='top-navigation'] button:is([data-part='help'], [data-part='action']):disabled {
|
|
677
|
+
color: var(--_disabled-color);
|
|
678
|
+
cursor: not-allowed;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/** The folded destination is where the reader is: `more` says so the way a closed parent does. */
|
|
682
|
+
[data-ui='top-navigation'] [data-part='more'][data-current] {
|
|
683
|
+
color: var(--_current-color);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* The account is a pill: the consumer's avatar inside a halo of one space
|
|
688
|
+
* step, and, when there is room, a name after it. The halo is the space the
|
|
689
|
+
* pointer's ground keeps between the control's edge and the avatar's edge,
|
|
690
|
+
* and the avatar the bar expects is one step under the control — `xs` at
|
|
691
|
+
* `md` — which is what leaves the halo whole inside the control's height.
|
|
692
|
+
*/
|
|
693
|
+
[data-ui='top-navigation'] [data-part='account'] {
|
|
694
|
+
border-radius: var(--slotted-radius-full, 9999px);
|
|
695
|
+
gap: var(--slotted-space-3, 0.375rem);
|
|
696
|
+
padding: var(--slotted-space-2, 0.25rem);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
[data-ui='top-navigation'] [data-part='account'] > :not([data-ui='avatar']) {
|
|
700
|
+
padding-inline-end: var(--slotted-space-3, 0.375rem);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* The count of what is waiting, over the bell's top-end corner: a disc for
|
|
705
|
+
* one digit and a pill from two, knocked out of the bar's ground by a ring
|
|
706
|
+
* so it reads over the bell's edge. It stands out of the flow, so it adds
|
|
707
|
+
* nothing to the control's width — the control is the bell's box, like the
|
|
708
|
+
* boxes beside it — and a third digit grows away from the bell, over the gap,
|
|
709
|
+
* where the control beside it holds no ink. Tabular figures, so a count that
|
|
710
|
+
* goes from 9 to 10 does not shift the ring.
|
|
711
|
+
*
|
|
712
|
+
* The count is type, and it is sized as the type it is, the way `badge`
|
|
713
|
+
* sizes a count: the control scale's small step — which is the step that
|
|
714
|
+
* moves with density — on a disc the height of that type's line, with a
|
|
715
|
+
* space step of inset on either side of the figures. Sized as a fraction of
|
|
716
|
+
* the bell instead, it was 14 pixels holding 10-pixel semibold figures with
|
|
717
|
+
* two pixels of inset, and the figures were crushed against the edge.
|
|
718
|
+
*
|
|
719
|
+
* A block container rather than a flex one: a flex container centres the
|
|
720
|
+
* line box, which is not symmetric around the figures inside it, and the
|
|
721
|
+
* figures sat high. `align-content` centres the one line, and the trim
|
|
722
|
+
* below makes that line the ink.
|
|
723
|
+
*/
|
|
724
|
+
[data-ui='top-navigation'] [data-part='count'] {
|
|
725
|
+
--_count-font: var(--slotted-control-font-size-sm, 12px);
|
|
726
|
+
--_count-size: calc(var(--_count-font) * var(--slotted-line-height-xs, 1.4));
|
|
727
|
+
--_count-inset: calc((var(--_control-height) - var(--_icon-size)) / 2);
|
|
728
|
+
align-content: center;
|
|
729
|
+
background-color: var(--_count-background);
|
|
730
|
+
block-size: var(--_count-size);
|
|
731
|
+
border-radius: var(--slotted-radius-full, 9999px);
|
|
732
|
+
box-shadow: 0 0 0 var(--slotted-border-width-thick, 2px) var(--_surface);
|
|
733
|
+
box-sizing: border-box;
|
|
734
|
+
color: var(--_count-color);
|
|
735
|
+
display: block;
|
|
736
|
+
font-size: var(--_count-font);
|
|
737
|
+
font-variant-numeric: tabular-nums;
|
|
738
|
+
font-weight: var(--slotted-font-weight-semibold, 600);
|
|
739
|
+
inset-block-start: calc(var(--_count-inset) - var(--_count-size) / 2);
|
|
740
|
+
/* Its centre on the bell's top-end corner, so the disc covers a corner of the mark and no more; a pill of three ends inside the account's halo. */
|
|
741
|
+
inset-inline-start: calc(100% - var(--_count-inset) - var(--_count-size) / 2);
|
|
742
|
+
line-height: 1;
|
|
743
|
+
min-inline-size: var(--_count-size);
|
|
744
|
+
padding-inline: var(--slotted-space-2, 0.25rem);
|
|
745
|
+
pointer-events: none;
|
|
746
|
+
position: absolute;
|
|
747
|
+
text-align: center;
|
|
748
|
+
white-space: nowrap;
|
|
749
|
+
z-index: 1;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/** What is centred is the ink rather than the font's metrics, as `badge` and `avatar` do it. */
|
|
753
|
+
@supports (text-box: trim-both cap alphabetic) {
|
|
754
|
+
[data-ui='top-navigation'] [data-part='count'] {
|
|
755
|
+
text-box: trim-both cap alphabetic;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
/* ── Search ─────────────────────────────────────────────────────────────── */
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* The one thing in the bar that grows: it takes the middle, up to the
|
|
763
|
+
* measure a search field is read at, and gives way before anything else
|
|
764
|
+
* does. What stands inside it is the consumer's field.
|
|
765
|
+
*
|
|
766
|
+
* It stands at the start of the middle, and the free space is between it
|
|
767
|
+
* and the actions. It was centred in that space, and the two end clusters
|
|
768
|
+
* are never the same width, so the field stood off the bar's centre by half
|
|
769
|
+
* their difference — twenty pixels in the first demo capture, aligned with
|
|
770
|
+
* nothing. Centring on the bar itself needs the two clusters laid out as
|
|
771
|
+
* one grid track each, which is not this family's tree; what a field at the
|
|
772
|
+
* start of the middle aligns with is the brand it follows.
|
|
773
|
+
*/
|
|
774
|
+
[data-ui='top-navigation'] [data-part='search'] {
|
|
775
|
+
align-items: center;
|
|
776
|
+
display: flex;
|
|
777
|
+
/* A shrink weight far above the brand's, so the field gives way to its
|
|
778
|
+
floor before the name gives up a letter: flex shares a deficit by weight
|
|
779
|
+
and basis, not in order, and the weight is how an order is stated. Four
|
|
780
|
+
orders of magnitude, because the brand's share of a deficit is what is
|
|
781
|
+
left after the weight, and at a hundred it was four tenths of a pixel —
|
|
782
|
+
enough to overflow the name's box and draw an ellipsis over a whole name. */
|
|
783
|
+
flex: 1 10000 var(--_search-size);
|
|
784
|
+
gap: var(--_action-gap);
|
|
785
|
+
margin-inline: 0 auto;
|
|
786
|
+
max-inline-size: var(--_search-size);
|
|
787
|
+
min-inline-size: var(--_search-min);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
[data-ui='top-navigation'] [data-part='search'] > :not([data-part='search-close']) {
|
|
791
|
+
flex: 1 1 auto;
|
|
792
|
+
min-inline-size: 0;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/** The toggle and the close exist for the narrow bar alone. */
|
|
796
|
+
[data-ui='top-navigation'] [data-part='search-toggle'],
|
|
797
|
+
[data-ui='top-navigation'] [data-part='search-close'] {
|
|
798
|
+
display: none;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/* ── Actions ────────────────────────────────────────────────────────────── */
|
|
802
|
+
|
|
803
|
+
[data-ui='top-navigation'] [data-part='actions'] {
|
|
804
|
+
align-items: center;
|
|
805
|
+
display: flex;
|
|
806
|
+
flex: 0 0 auto;
|
|
807
|
+
gap: var(--_action-gap);
|
|
808
|
+
margin-inline-start: auto;
|
|
809
|
+
padding-inline-end: calc(var(--_edge) + var(--_row-inset));
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
/* ── More, and the panel ────────────────────────────────────────────────── */
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* Hidden while nothing folds. The container queries below show it as soon
|
|
816
|
+
* as the list holds an item of a priority that has folded; the script
|
|
817
|
+
* shows it by the count it writes, which is what a list whose folded items
|
|
818
|
+
* have all moved into the panel is left with.
|
|
819
|
+
*/
|
|
820
|
+
[data-ui='top-navigation'] [data-part='item']:has(> [data-part='more']) {
|
|
821
|
+
display: none;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
[data-ui='top-navigation'] [data-part='item']:has(> [data-part='more'][data-overflow]) {
|
|
825
|
+
display: flex;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* Under the bar's end edge, on a raised ground, the width a column of
|
|
830
|
+
* destinations is read at. It stays in the DOM closed — out of sight and
|
|
831
|
+
* out of the tab order by `visibility` — so opening is a transition from a
|
|
832
|
+
* style the browser has already computed, and closing leaves from wherever
|
|
833
|
+
* the panel is. It arrives from one step above its place (R7).
|
|
834
|
+
*/
|
|
835
|
+
[data-ui='top-navigation'] [data-part='panel'] {
|
|
836
|
+
--_enter-distance: var(--slotted-space-2, 0.25rem);
|
|
837
|
+
|
|
838
|
+
background-color: var(--_panel-surface);
|
|
839
|
+
border: var(--_rule-width) solid var(--_border-color);
|
|
840
|
+
border-radius: var(--_panel-radius);
|
|
841
|
+
box-shadow: var(--_panel-shadow);
|
|
842
|
+
box-sizing: border-box;
|
|
843
|
+
color: var(--_color);
|
|
844
|
+
display: flex;
|
|
845
|
+
flex-direction: column;
|
|
846
|
+
gap: var(--slotted-space-2, 0.25rem);
|
|
847
|
+
inline-size: var(--_panel-size);
|
|
848
|
+
inset-block-start: calc(100% + var(--slotted-space-2, 0.25rem));
|
|
849
|
+
inset-inline-end: var(--_edge);
|
|
850
|
+
max-inline-size: 100%;
|
|
851
|
+
opacity: 0;
|
|
852
|
+
padding: var(--slotted-space-2, 0.25rem);
|
|
853
|
+
position: absolute;
|
|
854
|
+
transition:
|
|
855
|
+
opacity var(--slotted-duration-short) var(--slotted-easing-exit),
|
|
856
|
+
translate var(--slotted-duration-short) var(--slotted-easing-exit),
|
|
857
|
+
visibility var(--slotted-duration-short) step-end;
|
|
858
|
+
translate: 0 calc(-1 * var(--_enter-distance));
|
|
859
|
+
visibility: hidden;
|
|
860
|
+
z-index: calc(var(--slotted-z-index-popover, 1100) + var(--slotted-layer-depth, 0));
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
[data-ui='top-navigation'] [data-part='panel'][data-open] {
|
|
864
|
+
opacity: 1;
|
|
865
|
+
transition:
|
|
866
|
+
opacity var(--slotted-duration-medium) var(--slotted-easing-enter),
|
|
867
|
+
translate var(--slotted-duration-medium) var(--slotted-easing-enter),
|
|
868
|
+
visibility var(--slotted-duration-medium) step-start;
|
|
869
|
+
translate: 0 0;
|
|
870
|
+
visibility: visible;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
[data-ui='top-navigation'] [data-part='panel-list'] {
|
|
874
|
+
display: flex;
|
|
875
|
+
flex-direction: column;
|
|
876
|
+
gap: var(--slotted-space-1, 0.125rem);
|
|
877
|
+
list-style: none;
|
|
878
|
+
margin: 0;
|
|
879
|
+
padding: 0;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
[data-ui='top-navigation'] [data-part='panel-list']:empty {
|
|
883
|
+
display: none;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/**
|
|
887
|
+
* A folded destination is a row of the column: the shell's row height and
|
|
888
|
+
* type, the whole width, the label at the start. A section trigger in the
|
|
889
|
+
* panel keeps its chevron at the end of the row.
|
|
890
|
+
*/
|
|
891
|
+
[data-ui='top-navigation'] [data-part='panel'] [data-part='item'] {
|
|
892
|
+
display: flex;
|
|
893
|
+
flex: 0 0 auto;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
[data-ui='top-navigation']
|
|
897
|
+
[data-part='panel-list']
|
|
898
|
+
> [data-part='item']
|
|
899
|
+
> :is([data-part='link'], [data-part='trigger']),
|
|
900
|
+
[data-ui='top-navigation'] [data-part='panel'] > [data-part='help'] {
|
|
901
|
+
flex: 1 1 auto;
|
|
902
|
+
font-size: var(--_row-font-size);
|
|
903
|
+
justify-content: flex-start;
|
|
904
|
+
line-height: var(--_row-line-height);
|
|
905
|
+
min-block-size: var(--_row-height);
|
|
906
|
+
padding-inline: var(--_control-padding);
|
|
907
|
+
white-space: normal;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
[data-ui='top-navigation']
|
|
911
|
+
[data-part='panel-list']
|
|
912
|
+
> [data-part='item']
|
|
913
|
+
> [data-part='trigger']
|
|
914
|
+
> [data-part='indicator'] {
|
|
915
|
+
margin-inline-end: 0;
|
|
916
|
+
margin-inline-start: auto;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* A section folded into the panel opens its links in line under its
|
|
921
|
+
* trigger, as a group of the column does: the shared surface belongs to
|
|
922
|
+
* the bar's row, and a panel floating out of a panel is a second layer the
|
|
923
|
+
* reader did not ask for. The rows read the row geometry the folded links
|
|
924
|
+
* already read.
|
|
925
|
+
*/
|
|
926
|
+
[data-ui='top-navigation']
|
|
927
|
+
[data-part='panel-list']
|
|
928
|
+
> [data-part='item']:has(> [data-part='content']) {
|
|
929
|
+
align-items: stretch;
|
|
930
|
+
flex-direction: column;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
[data-ui='top-navigation'] [data-part='panel-list'] > [data-part='item'] > [data-part='content'] {
|
|
934
|
+
display: grid;
|
|
935
|
+
gap: var(--slotted-space-1, 0.125rem);
|
|
936
|
+
padding-block-end: var(--slotted-space-2, 0.25rem);
|
|
937
|
+
padding-inline-start: var(--_control-padding);
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
[data-ui='top-navigation']
|
|
941
|
+
[data-part='panel-list']
|
|
942
|
+
> [data-part='item']
|
|
943
|
+
> [data-part='content'][hidden] {
|
|
944
|
+
display: none;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
[data-ui='top-navigation'] [data-part='panel-list'] [data-part='content'] [data-part='links'] {
|
|
948
|
+
display: grid;
|
|
949
|
+
gap: var(--slotted-space-1, 0.125rem);
|
|
950
|
+
list-style: none;
|
|
951
|
+
margin: 0;
|
|
952
|
+
padding: 0;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
[data-ui='top-navigation'] [data-part='panel-list'] [data-part='content'] [data-part='link'] {
|
|
956
|
+
align-content: center;
|
|
957
|
+
border-radius: var(--_radius);
|
|
958
|
+
color: var(--_color);
|
|
959
|
+
column-gap: var(--_action-gap);
|
|
960
|
+
display: grid;
|
|
961
|
+
font-size: var(--_row-font-size);
|
|
962
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
963
|
+
line-height: var(--_row-line-height);
|
|
964
|
+
min-block-size: var(--_row-height);
|
|
965
|
+
padding-inline: var(--_control-padding);
|
|
966
|
+
text-decoration: none;
|
|
967
|
+
transition: background-color var(--_duration) var(--_easing);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
[data-ui='top-navigation']
|
|
971
|
+
[data-part='panel-list']
|
|
972
|
+
[data-part='content']
|
|
973
|
+
[data-part='link']:not([data-disabled], [data-current], [aria-current='page']):hover {
|
|
974
|
+
background-color: var(--_hover-background);
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
[data-ui='top-navigation']
|
|
978
|
+
[data-part='panel-list']
|
|
979
|
+
[data-part='content']
|
|
980
|
+
[data-part='link']:not([data-disabled], [data-current], [aria-current='page']):active {
|
|
981
|
+
background-color: var(--_active-background);
|
|
982
|
+
transition-duration: var(--slotted-duration-instant);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
[data-ui='top-navigation']
|
|
986
|
+
[data-part='panel-list']
|
|
987
|
+
[data-part='content']
|
|
988
|
+
[data-part='link']:is([data-current], [aria-current='page']) {
|
|
989
|
+
background-color: var(--_current-background);
|
|
990
|
+
box-shadow: inset 0 0 0 var(--_rule-width) var(--_current-edge);
|
|
991
|
+
color: var(--_current-color);
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
[data-ui='top-navigation']
|
|
995
|
+
[data-part='panel-list']
|
|
996
|
+
[data-part='content']
|
|
997
|
+
[data-part='link'][data-disabled] {
|
|
998
|
+
color: var(--_disabled-color);
|
|
999
|
+
cursor: not-allowed;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
[data-ui='top-navigation']
|
|
1003
|
+
[data-part='panel-list']
|
|
1004
|
+
[data-part='content']
|
|
1005
|
+
[data-part='link']:focus-visible {
|
|
1006
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
1007
|
+
outline-offset: calc(var(--slotted-focus-ring-width, 2px) * -1);
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
/** A link of plain words, or a rich one with no mark, starts its text at the inset. */
|
|
1011
|
+
[data-ui='top-navigation']
|
|
1012
|
+
[data-part='panel-list']
|
|
1013
|
+
[data-part='content']
|
|
1014
|
+
[data-part='link']:not(:has(> [data-part='icon']))
|
|
1015
|
+
> * {
|
|
1016
|
+
grid-column: 1 / -1;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
[data-ui='top-navigation'] [data-part='panel-list'] [data-part='content'] [data-part='icon'] {
|
|
1020
|
+
--slotted-icon-size: var(--_icon-size);
|
|
1021
|
+
|
|
1022
|
+
color: var(--_muted-color);
|
|
1023
|
+
display: flex;
|
|
1024
|
+
grid-row: 1 / span 2;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
[data-ui='top-navigation']
|
|
1028
|
+
[data-part='panel-list']
|
|
1029
|
+
[data-part='content']
|
|
1030
|
+
[data-part='description'] {
|
|
1031
|
+
color: var(--_muted-color);
|
|
1032
|
+
font-size: var(--slotted-font-size-xs, 0.75rem);
|
|
1033
|
+
grid-column: 2;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
[data-ui='top-navigation']
|
|
1037
|
+
[data-part='panel-list']
|
|
1038
|
+
[data-part='content']
|
|
1039
|
+
[data-part='group-label'] {
|
|
1040
|
+
color: var(--_muted-color);
|
|
1041
|
+
font-size: var(--slotted-font-size-xs, 0.75rem);
|
|
1042
|
+
font-weight: var(--slotted-font-weight-semibold, 600);
|
|
1043
|
+
padding-block: var(--slotted-space-2, 0.25rem);
|
|
1044
|
+
padding-inline: var(--_control-padding);
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
[data-ui='top-navigation'] [data-part='panel-list'] [data-part='content'] [data-part='footer'] {
|
|
1048
|
+
align-items: center;
|
|
1049
|
+
border-block-start: var(--_rule-width) solid var(--_border-color);
|
|
1050
|
+
display: flex;
|
|
1051
|
+
gap: var(--_action-gap);
|
|
1052
|
+
justify-content: space-between;
|
|
1053
|
+
padding-block-start: var(--slotted-space-2, 0.25rem);
|
|
1054
|
+
padding-inline: var(--_control-padding);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
/**
|
|
1058
|
+
* Help's children are its label: pushed out of the box and clipped in the
|
|
1059
|
+
* bar, where the mark stands alone and the tooltip repeats the words, and
|
|
1060
|
+
* shown after the mark in the panel, where it is a row. One accessible name
|
|
1061
|
+
* in both places, from the same text. The words are a text node, which no
|
|
1062
|
+
* child selector reaches, so the box itself does the hiding.
|
|
1063
|
+
*/
|
|
1064
|
+
[data-ui='top-navigation'] [data-part='actions'] > [data-part='help'] {
|
|
1065
|
+
gap: var(--_control-height);
|
|
1066
|
+
inline-size: var(--_control-height);
|
|
1067
|
+
justify-content: flex-start;
|
|
1068
|
+
overflow: hidden;
|
|
1069
|
+
padding-inline-start: calc((var(--_control-height) - var(--_icon-size)) / 2);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
[data-ui='top-navigation'] [data-part='panel'] > [data-part='help'] {
|
|
1073
|
+
gap: var(--_gap);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
[data-ui='top-navigation'] [data-part='panel'] > [data-part='context'] {
|
|
1077
|
+
padding: var(--slotted-space-2, 0.25rem) var(--slotted-space-3, 0.375rem);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* The panel reads context, list, help whatever order they arrived in: React
|
|
1082
|
+
* renders each into the panel through a portal in the order the parts mount,
|
|
1083
|
+
* Angular moves them into place. The rules between the three are drawn on
|
|
1084
|
+
* the list and on help, from what the panel holds rather than from what
|
|
1085
|
+
* stands before them, for the same reason.
|
|
1086
|
+
*/
|
|
1087
|
+
[data-ui='top-navigation'] [data-part='panel'] > [data-part='context'] {
|
|
1088
|
+
order: -1;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
[data-ui='top-navigation'] [data-part='panel'] > [data-part='help'] {
|
|
1092
|
+
order: 1;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
[data-ui='top-navigation']
|
|
1096
|
+
[data-part='panel']:has(> [data-part='context'])
|
|
1097
|
+
> [data-part='panel-list']:not(:empty),
|
|
1098
|
+
[data-ui='top-navigation']
|
|
1099
|
+
[data-part='panel']:has(> [data-part='panel-list']:not(:empty), > [data-part='context'])
|
|
1100
|
+
> [data-part='help'] {
|
|
1101
|
+
border-block-start: var(--_rule-width) solid var(--_border-color);
|
|
1102
|
+
padding-block-start: var(--slotted-space-2, 0.25rem);
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
/* ── The bar folds ──────────────────────────────────────────────────────── */
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* An item without a priority is a medium one, so the default folds where
|
|
1109
|
+
* the shell goes to overlay. `more` shows itself as soon as the list holds
|
|
1110
|
+
* an item of the priority that just folded, so a server render at a narrow
|
|
1111
|
+
* width already has the button.
|
|
1112
|
+
*/
|
|
1113
|
+
@container slotted-top-navigation (inline-size < 1024px) {
|
|
1114
|
+
[data-ui='top-navigation'] [data-part='list'] > [data-part='item'][data-priority='low'] {
|
|
1115
|
+
display: none;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
[data-ui='top-navigation']
|
|
1119
|
+
[data-part='list']:has(> [data-part='item'][data-priority='low'])
|
|
1120
|
+
> [data-part='item']:has(> [data-part='more']) {
|
|
1121
|
+
display: flex;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
@container slotted-top-navigation (inline-size < 600px) {
|
|
1126
|
+
[data-ui='top-navigation']
|
|
1127
|
+
[data-part='list']
|
|
1128
|
+
> [data-part='item']:not([data-priority='low']):not([data-priority='high']):not(
|
|
1129
|
+
:has(> [data-part='more'])
|
|
1130
|
+
) {
|
|
1131
|
+
display: none;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
[data-ui='top-navigation']
|
|
1135
|
+
[data-part='list']:has(
|
|
1136
|
+
> [data-part='item']:not([data-priority='low']):not([data-priority='high']):not(
|
|
1137
|
+
:has(> [data-part='more'])
|
|
1138
|
+
)
|
|
1139
|
+
)
|
|
1140
|
+
> [data-part='item']:has(> [data-part='more']) {
|
|
1141
|
+
display: flex;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/* The field gives way to its toggle; open, it takes the whole bar. */
|
|
1145
|
+
[data-ui='top-navigation']:not([data-search-open]) [data-part='search'] {
|
|
1146
|
+
display: none;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
[data-ui='top-navigation']:not([data-search-open]) [data-part='search-toggle'] {
|
|
1150
|
+
display: inline-flex;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
[data-ui='top-navigation'][data-search-open] [data-part='search'] {
|
|
1154
|
+
max-inline-size: none;
|
|
1155
|
+
padding-inline: var(--_edge);
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
[data-ui='top-navigation'][data-search-open] [data-part='search-close'] {
|
|
1159
|
+
display: inline-flex;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
[data-ui='top-navigation'][data-search-open]
|
|
1163
|
+
> :is([data-part='brand'], [data-part='context'], [data-part='nav'], [data-part='actions']) {
|
|
1164
|
+
display: none;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/* The account keeps its avatar and gives up the name beside it. */
|
|
1168
|
+
[data-ui='top-navigation'] [data-part='account'] > :not([data-ui='avatar']) {
|
|
1169
|
+
display: none;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
/* The context moves to the panel; in the bar it leaves, and `more` shows for it. */
|
|
1173
|
+
[data-ui='top-navigation'] > [data-part='context'] {
|
|
1174
|
+
display: none;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
[data-ui='top-navigation']:has(> [data-part='context'])
|
|
1178
|
+
[data-part='list']
|
|
1179
|
+
> [data-part='item']:has(> [data-part='more']) {
|
|
1180
|
+
display: flex;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
@container slotted-top-navigation (inline-size < 480px) {
|
|
1185
|
+
/* Six controls in a row: the air between them is what gives way. */
|
|
1186
|
+
[data-ui='top-navigation'] {
|
|
1187
|
+
--_gap: var(--slotted-space-2, 0.25rem);
|
|
1188
|
+
--_action-gap: var(--slotted-space-2, 0.25rem);
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
[data-ui='top-navigation'] [data-part='list'] > [data-part='item'][data-priority='high'] {
|
|
1192
|
+
display: none;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
[data-ui='top-navigation']
|
|
1196
|
+
[data-part='list']:has(> [data-part='item'][data-priority='high'])
|
|
1197
|
+
> [data-part='item']:has(> [data-part='more']) {
|
|
1198
|
+
display: flex;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
/**
|
|
1202
|
+
* With one space step between the controls, a pill of three anchored on
|
|
1203
|
+
* the bell's corner would reach the avatar. Here the count hangs from the
|
|
1204
|
+
* gap's far edge instead and grows toward the bell: the disc still sits on
|
|
1205
|
+
* the corner, and a pill covers the bell's top before it covers a control.
|
|
1206
|
+
*/
|
|
1207
|
+
[data-ui='top-navigation'] [data-part='count'] {
|
|
1208
|
+
inset-inline-end: calc(var(--slotted-border-width-thick, 2px) - var(--_action-gap));
|
|
1209
|
+
inset-inline-start: auto;
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/* The name leaves the eye and not the DOM: `home` keeps its accessible name. */
|
|
1213
|
+
[data-ui='top-navigation'] [data-part='name'] {
|
|
1214
|
+
clip-path: inset(50%);
|
|
1215
|
+
inline-size: 1px;
|
|
1216
|
+
margin: 0;
|
|
1217
|
+
overflow: hidden;
|
|
1218
|
+
position: absolute;
|
|
1219
|
+
white-space: nowrap;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
/* Out of flow, the name leaves its track empty; one track, or the gap stays. */
|
|
1223
|
+
[data-ui='top-navigation'] [data-part='home'] {
|
|
1224
|
+
grid-template-columns: auto;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
/* Help moves to the panel; in the bar it leaves, and `more` shows for it. */
|
|
1228
|
+
[data-ui='top-navigation'] [data-part='actions'] > [data-part='help'] {
|
|
1229
|
+
display: none;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
[data-ui='top-navigation']:has([data-part='actions'] > [data-part='help'])
|
|
1233
|
+
[data-part='list']
|
|
1234
|
+
> [data-part='item']:has(> [data-part='more']) {
|
|
1235
|
+
display: flex;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
[data-ui='top-navigation'] [data-part='panel'] {
|
|
1239
|
+
inline-size: auto;
|
|
1240
|
+
inset-inline: var(--_edge);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
/* ── Stillness ──────────────────────────────────────────────────────────── */
|
|
1245
|
+
|
|
1246
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1247
|
+
[data-ui='top-navigation'] [data-part='panel'],
|
|
1248
|
+
[data-ui='top-navigation'] [data-part='panel'][data-open] {
|
|
1249
|
+
translate: 0 0;
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
/* ── Forced colours ─────────────────────────────────────────────────────── */
|
|
1254
|
+
|
|
1255
|
+
@media (forced-colors: active) {
|
|
1256
|
+
[data-ui='top-navigation']
|
|
1257
|
+
:is([data-part='nav'] > [data-part='list'], [data-part='panel-list'])
|
|
1258
|
+
> [data-part='item']
|
|
1259
|
+
> [data-part='link']:is([data-current], [aria-current='page']) {
|
|
1260
|
+
background-color: Highlight;
|
|
1261
|
+
color: HighlightText;
|
|
1262
|
+
forced-color-adjust: none;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
[data-ui='top-navigation'] [data-part='count'] {
|
|
1266
|
+
background-color: Highlight;
|
|
1267
|
+
color: HighlightText;
|
|
1268
|
+
forced-color-adjust: none;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
[data-ui='top-navigation']
|
|
1272
|
+
:is([data-part='nav'] > [data-part='list'], [data-part='panel-list'])
|
|
1273
|
+
> [data-part='item'][data-disabled]
|
|
1274
|
+
> [data-part='link'],
|
|
1275
|
+
[data-ui='top-navigation']
|
|
1276
|
+
:is([data-part='nav'] > [data-part='list'], [data-part='panel-list'])
|
|
1277
|
+
> [data-part='item']
|
|
1278
|
+
> [data-part='trigger']:disabled {
|
|
1279
|
+
color: GrayText;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
[data-ui='top-navigation'][data-frame],
|
|
1283
|
+
[data-ui='top-navigation'] [data-part='panel'] {
|
|
1284
|
+
border-color: CanvasText;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
}
|