actual-css 0.1.0 → 0.3.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.
- package/CHANGELOG.md +90 -1
- package/README.md +25 -8
- package/dist/actual-themes.min.css +1 -0
- package/dist/actual.css +1492 -931
- package/dist/actual.js +1 -3
- package/dist/actual.min.css +1 -1
- package/dist/optional.css +1048 -0
- package/dist/optional.min.css +1 -0
- package/docs/design-notes/browser-support.md +95 -6
- package/docs/design-notes/cascade-layer.md +1 -1
- package/docs/design-notes/enhancement-contract.md +101 -0
- package/docs/design-notes/forced-colors.md +105 -0
- package/docs/design-notes/naming.md +3 -1
- package/docs/design-notes/platform-alignment.md +492 -0
- package/docs/design-notes/references.md +8 -0
- package/docs/design-notes/widget-primitives.md +119 -0
- package/docs/navigation.json +135 -0
- package/docs/pages/components/accordion.md +80 -0
- package/docs/pages/components/alert.md +203 -0
- package/docs/pages/components/aura.md +35 -0
- package/docs/pages/components/avatar.md +95 -0
- package/docs/pages/components/badge.md +102 -0
- package/docs/pages/components/breadcrumb.md +19 -0
- package/docs/pages/components/button.md +205 -0
- package/docs/pages/components/card.md +183 -0
- package/docs/pages/components/chat.md +50 -0
- package/docs/pages/components/dialog.md +367 -0
- package/docs/pages/components/drawer.md +113 -0
- package/docs/pages/components/fab.md +118 -0
- package/docs/pages/components/key.md +33 -0
- package/docs/pages/components/meter.md +23 -0
- package/docs/pages/components/navbar.md +92 -0
- package/docs/pages/components/pagination.md +55 -0
- package/docs/pages/components/progress.md +29 -0
- package/docs/pages/components/skeleton.md +38 -0
- package/docs/pages/components/spinner.md +93 -0
- package/docs/pages/components/table.md +102 -0
- package/docs/pages/enhancements/flyout.md +391 -0
- package/docs/pages/enhancements/overview.md +36 -0
- package/docs/pages/enhancements/scrollspy.md +71 -0
- package/docs/pages/enhancements/status-bar.md +72 -0
- package/docs/pages/enhancements/tabs.md +80 -0
- package/docs/pages/enhancements/tooltip.md +130 -0
- package/docs/pages/examples/overview.md +41 -0
- package/docs/pages/forms/choice-cards.md +102 -0
- package/docs/pages/forms/controls.md +32 -0
- package/docs/pages/forms/detached-actions.md +59 -0
- package/docs/pages/forms/floating-field.md +88 -0
- package/docs/pages/forms/form-actions.md +56 -0
- package/docs/pages/forms/input-policy.md +91 -0
- package/docs/pages/forms/joined-controls.md +37 -0
- package/docs/pages/forms/labels.md +42 -0
- package/docs/pages/forms/otp.md +50 -0
- package/docs/pages/forms/overview.md +188 -0
- package/docs/pages/forms/password.md +40 -0
- package/docs/pages/forms/range.md +17 -0
- package/docs/pages/forms/states-and-sizes.md +321 -0
- package/docs/pages/forms/sticky-actions.md +187 -0
- package/docs/pages/forms/switch.md +31 -0
- package/docs/pages/forms/validation.md +241 -0
- package/docs/{mental-model.md → pages/foundations/philosophy.md} +33 -18
- package/docs/pages/foundations/theming.md +92 -0
- package/docs/pages/foundations/tokens.md +421 -0
- package/docs/{typography.md → pages/foundations/typography.md} +27 -9
- package/docs/pages/guides/bootstrap.md +438 -0
- package/docs/pages/guides/introduction.md +157 -0
- package/docs/pages/guides/optional-components.md +33 -0
- package/docs/pages/guides/progressive-enhancement.md +686 -0
- package/docs/pages/guides/tailwind.md +455 -0
- package/docs/pages/layout/app-shell.md +25 -0
- package/docs/pages/layout/center.md +29 -0
- package/docs/pages/layout/cluster.md +57 -0
- package/docs/pages/layout/frame.md +30 -0
- package/docs/pages/layout/grid.md +142 -0
- package/docs/pages/layout/list.md +41 -0
- package/docs/pages/layout/media.md +21 -0
- package/docs/pages/layout/overview.md +37 -0
- package/docs/pages/layout/scroll-snap.md +54 -0
- package/docs/pages/layout/sidebar-layout.md +27 -0
- package/docs/pages/layout/stack.md +18 -0
- package/docs/pages/layout/switcher.md +36 -0
- package/docs/pages/layout/topbar.md +23 -0
- package/docs/pages/patterns/actions.md +52 -0
- package/docs/pages/patterns/code-block.md +36 -0
- package/docs/pages/patterns/exclusive-accordion.md +16 -0
- package/docs/pages/patterns/hierarchical-nav.md +26 -0
- package/docs/pages/patterns/icon-input.md +25 -0
- package/docs/pages/patterns/intent-nesting.md +3 -0
- package/docs/pages/patterns/navigation-list.md +235 -0
- package/docs/pages/patterns/overview.md +58 -0
- package/docs/pages/patterns/structured-lists.md +47 -0
- package/docs/pages/utilities/accessibility.md +34 -0
- package/docs/pages/utilities/flex.md +105 -0
- package/docs/pages/utilities/links.md +18 -0
- package/docs/pages/utilities/list.md +31 -0
- package/docs/pages/utilities/overflow.md +43 -0
- package/docs/pages/utilities/overview.md +18 -0
- package/docs/pages/utilities/shape.md +25 -0
- package/docs/pages/utilities/sizing-wrapping.md +115 -0
- package/docs/pages/utilities/spacing.md +79 -0
- package/docs/pages/utilities/text.md +43 -0
- package/llms.txt +10 -4
- package/package.json +30 -16
- package/src/css/actual.css +12 -1
- package/src/css/base.css +3 -9
- package/src/css/components/accordion.css +18 -30
- package/src/css/components/actions.css +4 -1
- package/src/css/components/alert.css +162 -49
- package/src/css/components/avatar.css +16 -10
- package/src/css/components/badge.css +82 -39
- package/src/css/components/breadcrumb.css +7 -15
- package/src/css/components/busy.css +7 -0
- package/src/css/components/button.css +82 -38
- package/src/css/components/card.css +17 -37
- package/src/css/components/drawer.css +30 -13
- package/src/css/components/flyout.css +39 -110
- package/src/css/components/index.css +1 -0
- package/src/css/components/join.css +14 -3
- package/src/css/components/key.css +2 -0
- package/src/css/components/menu.css +125 -0
- package/src/css/components/meter.css +0 -23
- package/src/css/components/modal.css +162 -7
- package/src/css/components/navbar.css +17 -18
- package/src/css/components/overline.css +0 -7
- package/src/css/components/pagination.css +1 -1
- package/src/css/components/progress.css +8 -26
- package/src/css/components/scrollspy.css +2 -2
- package/src/css/components/skeleton.css +7 -0
- package/src/css/components/spinner.css +10 -11
- package/src/css/components/status-bar.css +18 -28
- package/src/css/components/surface.css +2 -8
- package/src/css/components/tab.css +20 -48
- package/src/css/components/table.css +7 -5
- package/src/css/components/tooltip.css +14 -7
- package/src/css/focus.css +16 -3
- package/src/css/forms/choice-card.css +13 -15
- package/src/css/forms/choice.css +21 -28
- package/src/css/forms/control.css +16 -26
- package/src/css/forms/custom-select.css +9 -11
- package/src/css/forms/form-actions.css +14 -3
- package/src/css/forms/form.css +7 -4
- package/src/css/forms/index.css +5 -4
- package/src/css/forms/input-icon.css +30 -12
- package/src/css/forms/native.css +48 -33
- package/src/css/forms/range.css +103 -0
- package/src/css/forms/select.css +8 -8
- package/src/css/forms/switch.css +14 -13
- package/src/css/forms/validation.css +32 -5
- package/src/css/grid.css +19 -18
- package/src/css/intents.css +2 -2
- package/src/css/layout.css +29 -1
- package/src/css/optional/aura.css +93 -0
- package/src/css/optional/chat.css +105 -0
- package/src/css/optional/fab.css +104 -0
- package/src/css/optional/floating-field.css +87 -0
- package/src/css/optional/index.css +5 -0
- package/src/css/optional/layout-extra.css +7 -4
- package/src/css/optional/otp.css +115 -0
- package/src/css/optional/scroll-snap.css +6 -0
- package/src/css/optional/scroller.css +19 -7
- package/src/css/optional/typography-fluid.css +5 -0
- package/src/css/optional/utilities-extra.css +17 -2
- package/src/css/prose.css +18 -8
- package/src/css/reset.css +0 -10
- package/src/css/theme.css +29 -13
- package/src/css/themes/cyberpunk.css +1 -1
- package/src/css/themes/dim.css +3 -3
- package/src/css/themes/edge.css +11 -37
- package/src/css/themes/index.css +3 -3
- package/src/css/themes/{dark.css → indigo.css} +5 -4
- package/src/css/themes/neon.css +5 -5
- package/src/css/themes/square.css +0 -3
- package/src/css/tokens.css +81 -21
- package/src/css/utilities.css +8 -10
- package/src/css/variants.css +37 -65
- package/src/js/command.js +1 -3
- package/src/js/context-menu.js +72 -53
- package/src/js/dialog.js +68 -79
- package/src/js/dismiss.js +15 -0
- package/src/js/enhance.js +76 -19
- package/src/js/enhancement-loader.js +301 -0
- package/src/js/events.js +3 -0
- package/src/js/filter.js +3 -3
- package/src/js/floating.js +101 -131
- package/src/js/flyout.js +106 -96
- package/src/js/focus-group.js +116 -0
- package/src/js/focus.js +6 -1
- package/src/js/index.js +4 -2
- package/src/js/input.js +1 -1
- package/src/js/keys.js +27 -0
- package/src/js/mask.js +7 -6
- package/src/js/menu.js +89 -35
- package/src/js/parse-config.js +47 -0
- package/src/js/password.js +9 -1
- package/src/js/scrollspy.js +133 -62
- package/src/js/selectors.js +14 -31
- package/src/js/status.js +16 -14
- package/src/js/surface.js +219 -125
- package/src/js/tab.js +46 -66
- package/src/js/tooltip.js +53 -31
- package/src/js/validation.js +45 -51
- package/dist/actual.js.map +0 -31
- package/docs/README.md +0 -26
- package/docs/components.md +0 -860
- package/docs/design-notes/previous-work.md +0 -5
- package/docs/forms.md +0 -1265
- package/docs/javascript.md +0 -426
- package/docs/layout.md +0 -480
- package/docs/patterns.md +0 -415
- package/docs/reserved.md +0 -7
- package/docs/tokens.md +0 -455
- package/docs/ui.md +0 -937
- package/docs/utilities.md +0 -384
- package/src/css/dialog-fallback.css +0 -56
- package/src/js/dialog-fallback.js +0 -163
|
@@ -9,19 +9,35 @@
|
|
|
9
9
|
* Disabled state uses the native disabled attribute for buttons and inputs.
|
|
10
10
|
* Anchors have no native disabled state, so a.btn uses aria-disabled="true"
|
|
11
11
|
* for disabled styling and activation guards.
|
|
12
|
+
*
|
|
13
|
+
* Public hooks:
|
|
14
|
+
* --btn-font-size
|
|
15
|
+
* --btn-min-size
|
|
16
|
+
* --btn-pad-x
|
|
17
|
+
* --btn-radius
|
|
18
|
+
* --btn-focus-color
|
|
19
|
+
* --btn-gap
|
|
20
|
+
* --btn-hover-overlay
|
|
21
|
+
*
|
|
22
|
+
* Internal:
|
|
23
|
+
* --btn-bg
|
|
24
|
+
* --btn-fg
|
|
25
|
+
* --btn-border
|
|
26
|
+
* --btn-focus-ring-color
|
|
27
|
+
* --btn-border-block-end-color
|
|
28
|
+
* --btn-border-block-end-width
|
|
29
|
+
* --spinner-width
|
|
12
30
|
*/
|
|
13
31
|
|
|
14
32
|
/* Intent boundary — inherited intents do not tint this component.
|
|
15
33
|
Local intent classes still win because :where() has zero specificity. */
|
|
16
34
|
:where(.btn) {
|
|
17
|
-
/* @sync intent-boundary */
|
|
18
35
|
--intent: initial;
|
|
19
36
|
--intent-fg: initial;
|
|
20
37
|
--ui-bg: initial;
|
|
21
38
|
--ui-fg: initial;
|
|
22
39
|
--ui-border: initial;
|
|
23
40
|
--ui-hover-bg: initial;
|
|
24
|
-
/* @sync intent-boundary */
|
|
25
41
|
}
|
|
26
42
|
|
|
27
43
|
.btn {
|
|
@@ -33,18 +49,17 @@
|
|
|
33
49
|
--btn-border: var(--ui-border, var(--btn-default-border, transparent));
|
|
34
50
|
--btn-radius: var(--radius);
|
|
35
51
|
--btn-focus-color: var(--intent, var(--focus));
|
|
36
|
-
--btn-focus-outline-width: calc(var(--border-width) * 2);
|
|
37
|
-
--btn-hover-bg: var(--ui-hover-bg, var(--btn-bg));
|
|
38
52
|
--btn-hover-overlay: var(--hover-overlay, rgb(0 0 0 / 0.08));
|
|
39
53
|
|
|
54
|
+
/* Positioning context for indicators, overlays, and grouped states. */
|
|
40
55
|
position: relative;
|
|
41
56
|
display: inline-flex;
|
|
42
57
|
align-items: center;
|
|
43
58
|
justify-content: center;
|
|
44
|
-
gap: 0.
|
|
59
|
+
gap: var(--btn-gap, 0.375em);
|
|
45
60
|
min-block-size: var(--btn-min-size);
|
|
46
|
-
padding-block: var(--space-
|
|
47
|
-
padding-block: max(var(--space-
|
|
61
|
+
padding-block: var(--space-20);
|
|
62
|
+
padding-block: max(var(--space-10), calc((var(--btn-min-size) - 1lh) / 2));
|
|
48
63
|
padding-inline: var(--btn-pad-x);
|
|
49
64
|
border: var(--border-width) solid var(--btn-border-color, var(--btn-border));
|
|
50
65
|
border-block-end-color: var(
|
|
@@ -57,7 +72,7 @@
|
|
|
57
72
|
color: var(--btn-fg);
|
|
58
73
|
font: inherit;
|
|
59
74
|
font-size: var(--btn-font-size);
|
|
60
|
-
font-weight: var(--font-weight-
|
|
75
|
+
font-weight: var(--font-weight-medium);
|
|
61
76
|
line-height: 1;
|
|
62
77
|
text-decoration: none;
|
|
63
78
|
cursor: pointer;
|
|
@@ -69,6 +84,11 @@
|
|
|
69
84
|
transform var(--duration);
|
|
70
85
|
}
|
|
71
86
|
|
|
87
|
+
.btn.icon-only {
|
|
88
|
+
inline-size: var(--btn-min-size);
|
|
89
|
+
padding-inline: 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
72
92
|
@supports (color: color-mix(in oklch, red, white)) {
|
|
73
93
|
.btn {
|
|
74
94
|
--btn-focus-ring-color: color-mix(in oklch, var(--btn-focus-color) 28%, transparent);
|
|
@@ -93,13 +113,40 @@
|
|
|
93
113
|
--btn-hover-overlay: transparent;
|
|
94
114
|
}
|
|
95
115
|
|
|
96
|
-
/*
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
116
|
+
/* Shared hover recipe — sets --ui-hover-bg consumed by the hover rule below.
|
|
117
|
+
Declared outside :hover: the variables resolve only when the hover rule
|
|
118
|
+
reads them, so the values are inert until interaction. */
|
|
119
|
+
.btn:is(.outline, .ghost) {
|
|
120
|
+
--ui-hover-bg: var(--surface-subtle);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@supports (color: color-mix(in oklch, red, white)) {
|
|
124
|
+
.btn:not(:where(.soft, .outline, .ghost, .link)) {
|
|
125
|
+
--ui-hover-bg: color-mix(in oklch, var(--intent, var(--neutral)) 88%, black);
|
|
102
126
|
}
|
|
127
|
+
|
|
128
|
+
.btn.soft {
|
|
129
|
+
--ui-hover-bg: color-mix(
|
|
130
|
+
in oklch,
|
|
131
|
+
var(--surface) calc(var(--soft-bg-mix) - var(--soft-hover-alpha)),
|
|
132
|
+
var(--intent, var(--neutral))
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.btn.outline {
|
|
137
|
+
--ui-hover-bg: color-mix(in oklch, var(--surface-subtle) 92%, var(--intent, var(--neutral)));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.btn.ghost {
|
|
141
|
+
--ui-hover-bg: color-mix(in oklch, var(--intent, var(--text)) 8%, transparent);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* The .soft/.outline/.ghost hover recipe (--ui-hover-bg) is set locally above;
|
|
146
|
+
the overlay darkening for solid/soft is .btn-specific. */
|
|
147
|
+
.btn:not(:where(:disabled, [aria-disabled="true"])):hover {
|
|
148
|
+
background: var(--ui-hover-bg, var(--btn-bg));
|
|
149
|
+
box-shadow: inset 0 0 0 999px var(--btn-hover-overlay);
|
|
103
150
|
}
|
|
104
151
|
|
|
105
152
|
.btn:not(:where(:disabled, [aria-disabled="true"])):active {
|
|
@@ -124,23 +171,21 @@
|
|
|
124
171
|
/* .btn.circle needs no local rule: the .circle utility (utilities.css) loads
|
|
125
172
|
after components and overrides border-radius at equal specificity. */
|
|
126
173
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
text-decoration-thickness: 0.12em;
|
|
132
|
-
}
|
|
174
|
+
.btn.link:not(:where(:disabled, [aria-disabled="true"])):hover {
|
|
175
|
+
background: transparent;
|
|
176
|
+
color: var(--intent, var(--text));
|
|
177
|
+
text-decoration-thickness: 0.12em;
|
|
133
178
|
}
|
|
134
179
|
|
|
135
180
|
.btn:focus-visible {
|
|
136
|
-
outline:
|
|
137
|
-
|
|
138
|
-
box-shadow: 0 0 0 3px var(--btn-focus-ring-color, var(--focus-ring));
|
|
181
|
+
outline: 2px solid transparent;
|
|
182
|
+
box-shadow: 0 0 0 var(--focus-ring-width) var(--btn-focus-ring-color, var(--focus-ring));
|
|
139
183
|
}
|
|
140
184
|
|
|
141
185
|
.btn.link:focus-visible {
|
|
142
|
-
outline
|
|
186
|
+
outline: var(--focus-outline);
|
|
143
187
|
outline-offset: 0.2em;
|
|
188
|
+
box-shadow: none;
|
|
144
189
|
}
|
|
145
190
|
|
|
146
191
|
.btn:disabled {
|
|
@@ -164,17 +209,18 @@ a.btn[aria-disabled="true"] {
|
|
|
164
209
|
}
|
|
165
210
|
|
|
166
211
|
.btn[aria-busy="true"] > .spinner {
|
|
167
|
-
--spinner-size: 1em;
|
|
168
212
|
--spinner-width: 0.15em;
|
|
169
213
|
}
|
|
170
214
|
|
|
171
|
-
/* Toggle
|
|
172
|
-
|
|
173
|
-
button keeps its intent background and foreground while hovered.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
--btn-
|
|
215
|
+
/* Toggle and current state.
|
|
216
|
+
State must outrank the shared .outline/.ghost hover recipes: a pressed or
|
|
217
|
+
current button keeps its intent background and foreground while hovered.
|
|
218
|
+
aria-current="page" is the pagination current-page marker; aria-pressed
|
|
219
|
+
covers toggle buttons. */
|
|
220
|
+
.btn:is([aria-pressed="true"], [aria-current="page"]):not(.link) {
|
|
221
|
+
--btn-bg: var(--intent, var(--state-selected));
|
|
222
|
+
--btn-fg: var(--intent-fg, var(--state-selected-fg));
|
|
223
|
+
--btn-border: var(--intent, var(--state-selected));
|
|
178
224
|
--ui-hover-bg: var(--btn-bg);
|
|
179
225
|
}
|
|
180
226
|
|
|
@@ -192,18 +238,16 @@ a.btn[aria-disabled="true"] {
|
|
|
192
238
|
color: LinkText;
|
|
193
239
|
}
|
|
194
240
|
|
|
195
|
-
.btn:is([aria-pressed="true"], [aria-current
|
|
241
|
+
.btn:is([aria-pressed="true"], [aria-current="page"]):not(.link) {
|
|
196
242
|
border-color: Highlight;
|
|
197
243
|
background: Highlight;
|
|
198
244
|
color: HighlightText;
|
|
199
245
|
forced-color-adjust: none;
|
|
200
246
|
}
|
|
201
247
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
outline-offset: 2px;
|
|
206
|
-
}
|
|
248
|
+
.btn:hover:not(:where(:disabled, [aria-disabled="true"], .link)) {
|
|
249
|
+
outline: var(--border-width) solid ButtonText;
|
|
250
|
+
outline-offset: 2px;
|
|
207
251
|
}
|
|
208
252
|
|
|
209
253
|
.btn:disabled,
|
|
@@ -4,28 +4,36 @@
|
|
|
4
4
|
* Surface, border, radius, padding, density, and elevation stay local here.
|
|
5
5
|
* Direct header/footer children are structural slots. Page layout remains the
|
|
6
6
|
* job of markup and layout primitives outside the card.
|
|
7
|
+
*
|
|
8
|
+
* Public hooks:
|
|
9
|
+
* --card-pad
|
|
10
|
+
* --card-radius
|
|
11
|
+
* --card-max-inline-size
|
|
12
|
+
*
|
|
13
|
+
* Child contract:
|
|
14
|
+
* Direct .bleed children escape --card-pad (negative inset, wider media);
|
|
15
|
+
* edge children inherit the card corners. .bleed must be a direct child.
|
|
16
|
+
*
|
|
17
|
+
* Internal:
|
|
18
|
+
* --heading
|
|
19
|
+
* --busy-overlay-bg
|
|
7
20
|
*/
|
|
8
21
|
/* Intent boundary — inherited intents do not tint this component.
|
|
9
22
|
Local intent classes still win because :where() has zero specificity. */
|
|
10
23
|
:where(.card) {
|
|
11
|
-
/* @sync intent-boundary */
|
|
12
|
-
--intent: initial;
|
|
13
|
-
--intent-fg: initial;
|
|
14
24
|
--ui-bg: initial;
|
|
15
25
|
--ui-fg: initial;
|
|
16
26
|
--ui-border: initial;
|
|
17
|
-
--ui-hover-bg: initial;
|
|
18
|
-
/* @sync intent-boundary */
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
.card {
|
|
22
|
-
--card-pad: var(--space-
|
|
30
|
+
--card-pad: var(--space-40);
|
|
23
31
|
--card-radius: var(--radius-lg);
|
|
24
32
|
--card-max-inline-size: none;
|
|
25
33
|
|
|
26
34
|
max-inline-size: var(--card-max-inline-size);
|
|
27
35
|
padding: var(--card-pad);
|
|
28
|
-
background: var(--ui-bg, var(--surface));
|
|
36
|
+
background: var(--ui-bg, var(--surface-raised));
|
|
29
37
|
color: var(--ui-fg, var(--text));
|
|
30
38
|
border: var(--border-width) solid var(--ui-border, var(--border));
|
|
31
39
|
border-radius: var(--card-radius);
|
|
@@ -40,7 +48,7 @@
|
|
|
40
48
|
flex-wrap: wrap;
|
|
41
49
|
align-items: var(--items-align, center);
|
|
42
50
|
justify-content: space-between;
|
|
43
|
-
gap: var(--space-
|
|
51
|
+
gap: var(--space-30);
|
|
44
52
|
min-inline-size: 0;
|
|
45
53
|
}
|
|
46
54
|
|
|
@@ -67,16 +75,8 @@
|
|
|
67
75
|
.card.subtle {
|
|
68
76
|
background: var(--surface-subtle);
|
|
69
77
|
}
|
|
70
|
-
.card.inverted {
|
|
71
|
-
background: var(--surface-solid);
|
|
72
|
-
color: var(--surface);
|
|
73
|
-
border-color: transparent;
|
|
74
|
-
--heading: var(--surface);
|
|
75
|
-
--busy-overlay-bg: var(--surface-solid);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
78
|
.card.compact {
|
|
79
|
-
--card-pad: var(--space-
|
|
79
|
+
--card-pad: var(--space-20);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/* Full-bleed children */
|
|
@@ -118,23 +118,3 @@
|
|
|
118
118
|
.card > :where(header, footer, figure).bleed {
|
|
119
119
|
padding: var(--card-pad);
|
|
120
120
|
}
|
|
121
|
-
|
|
122
|
-
@media (forced-colors: active) {
|
|
123
|
-
.card {
|
|
124
|
-
border-color: ButtonText;
|
|
125
|
-
background: Canvas;
|
|
126
|
-
color: CanvasText;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.card.raised {
|
|
130
|
-
box-shadow: none;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.card.inverted {
|
|
134
|
-
--heading: CanvasText;
|
|
135
|
-
|
|
136
|
-
border-color: ButtonText;
|
|
137
|
-
background: Canvas;
|
|
138
|
-
color: CanvasText;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
@@ -6,16 +6,30 @@
|
|
|
6
6
|
* discrete display/overlay transitions. The drawer is a layout shell only —
|
|
7
7
|
* navigation content inside uses .nav-link and .accordion, which carry their
|
|
8
8
|
* own link/summary styling.
|
|
9
|
+
*
|
|
10
|
+
* Public hooks:
|
|
11
|
+
* --drawer-size
|
|
12
|
+
* --drawer-pad
|
|
13
|
+
*
|
|
14
|
+
* Internal:
|
|
15
|
+
* --drawer-closed-translate (side/RTL positioning state)
|
|
9
16
|
*/
|
|
10
17
|
dialog.drawer {
|
|
11
18
|
--drawer-size: 20rem;
|
|
12
|
-
--drawer-pad: var(--space-
|
|
19
|
+
--drawer-pad: var(--space-40);
|
|
13
20
|
--drawer-closed-translate: -100%;
|
|
14
21
|
|
|
22
|
+
/* Keep the surface anchored to the viewport in the top layer. This also
|
|
23
|
+
provides the containing block for the absolutely positioned close button.
|
|
24
|
+
A percentage height resolves against the fixed containing viewport, while
|
|
25
|
+
dynamic viewport units can be stale in embedded previews. */
|
|
26
|
+
position: fixed;
|
|
27
|
+
inset-block-start: 0;
|
|
28
|
+
|
|
15
29
|
inline-size: min(calc(var(--viewport-inline) * 0.9), var(--drawer-size));
|
|
16
|
-
block-size:
|
|
30
|
+
block-size: 100%;
|
|
17
31
|
max-inline-size: none;
|
|
18
|
-
max-block-size:
|
|
32
|
+
max-block-size: 100%;
|
|
19
33
|
margin: 0;
|
|
20
34
|
padding: var(--drawer-pad);
|
|
21
35
|
border: 0;
|
|
@@ -34,7 +48,7 @@ dialog.drawer {
|
|
|
34
48
|
dialog.drawer[open] {
|
|
35
49
|
display: grid;
|
|
36
50
|
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
37
|
-
gap: var(--space-
|
|
51
|
+
gap: var(--space-40);
|
|
38
52
|
opacity: 1;
|
|
39
53
|
transform: translateX(0);
|
|
40
54
|
}
|
|
@@ -105,18 +119,21 @@ dialog.drawer nav {
|
|
|
105
119
|
}
|
|
106
120
|
|
|
107
121
|
@media (forced-colors: active) {
|
|
108
|
-
dialog.drawer {
|
|
109
|
-
border-inline-end-color: ButtonText;
|
|
122
|
+
dialog.drawer::backdrop {
|
|
110
123
|
background: Canvas;
|
|
111
|
-
color: CanvasText;
|
|
112
|
-
box-shadow: none;
|
|
113
124
|
}
|
|
125
|
+
}
|
|
114
126
|
|
|
115
|
-
|
|
116
|
-
|
|
127
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
128
|
+
dialog.drawer.is-static {
|
|
129
|
+
animation: actual-dialog-static var(--duration-slow) var(--ease);
|
|
117
130
|
}
|
|
131
|
+
}
|
|
118
132
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
133
|
+
/* The close button shares the modal's interior placement (modal.css): absolute
|
|
134
|
+
at the panel's top inline-end, out of the content flow. The header reserves
|
|
135
|
+
inline room so the title never runs under it. */
|
|
136
|
+
dialog.drawer > header,
|
|
137
|
+
dialog.drawer > form > header {
|
|
138
|
+
padding-inline-end: calc(var(--control-size) + var(--space-30));
|
|
122
139
|
}
|
|
@@ -9,7 +9,16 @@
|
|
|
9
9
|
* .is-sheet marks "auto" resolved to bottom-sheet presentation on coarse
|
|
10
10
|
* pointers. Authors opt into mobile behavior with
|
|
11
11
|
* [data-flyout-mobile="sheet|auto|none|anchored"].
|
|
12
|
-
* --
|
|
12
|
+
* --surface-anchor-width is set by surface.js while an open flyout is positioned.
|
|
13
|
+
*
|
|
14
|
+
* Public hooks:
|
|
15
|
+
* --flyout-inline-size
|
|
16
|
+
* --flyout-max-inline-size
|
|
17
|
+
*
|
|
18
|
+
* Internal:
|
|
19
|
+
* --menu-item-size (derived from --control-size for menu rows)
|
|
20
|
+
* --available-height (measured by floating.js)
|
|
21
|
+
* --surface-anchor-width (measured by surface.js)
|
|
13
22
|
*/
|
|
14
23
|
|
|
15
24
|
.flyout-trigger {
|
|
@@ -32,28 +41,32 @@
|
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
.flyout {
|
|
44
|
+
--menu-item-size: var(--control-size);
|
|
35
45
|
z-index: var(--z-menu);
|
|
36
46
|
/* No-JS fallback: below the trigger inside the relative .flyout-trigger.
|
|
37
47
|
surface.js switches an open flyout to position: fixed with measured
|
|
38
48
|
coordinates; this only covers a flyout revealed without the runtime. */
|
|
39
49
|
position: absolute;
|
|
40
|
-
inset-block-start: calc(100% + var(--space-
|
|
50
|
+
inset-block-start: calc(100% + var(--space-10));
|
|
41
51
|
inset-inline-start: 0;
|
|
42
52
|
display: grid;
|
|
43
|
-
gap: var(--space-
|
|
53
|
+
gap: var(--space-10);
|
|
44
54
|
inline-size: var(--flyout-inline-size, max-content);
|
|
45
55
|
min-inline-size: min(
|
|
46
|
-
var(--
|
|
47
|
-
min(var(--flyout-max-inline-size, 20rem), calc(var(--viewport-inline) - var(--space-
|
|
56
|
+
var(--surface-anchor-width, 0px),
|
|
57
|
+
min(var(--flyout-max-inline-size, 20rem), calc(var(--viewport-inline) - var(--space-60)))
|
|
48
58
|
);
|
|
49
59
|
max-inline-size: min(
|
|
50
60
|
var(--flyout-max-inline-size, 20rem),
|
|
51
|
-
calc(var(--viewport-inline) - var(--space-
|
|
61
|
+
calc(var(--viewport-inline) - var(--space-60))
|
|
62
|
+
);
|
|
63
|
+
max-block-size: min(
|
|
64
|
+
24rem,
|
|
65
|
+
var(--available-height, calc(var(--viewport-block) - var(--space-60)))
|
|
52
66
|
);
|
|
53
|
-
max-block-size: min(24rem, var(--available-height, calc(var(--viewport-block) - var(--space-6))));
|
|
54
67
|
overflow: auto;
|
|
55
68
|
margin: 0;
|
|
56
|
-
padding: var(--space-
|
|
69
|
+
padding: var(--space-10);
|
|
57
70
|
border: var(--border-width) solid var(--border);
|
|
58
71
|
border-radius: var(--radius);
|
|
59
72
|
background: var(--surface-raised);
|
|
@@ -62,9 +75,9 @@
|
|
|
62
75
|
opacity: 1;
|
|
63
76
|
scale: 1;
|
|
64
77
|
transition:
|
|
65
|
-
opacity var(--duration-fast
|
|
66
|
-
scale var(--duration-fast
|
|
67
|
-
translate var(--duration-fast
|
|
78
|
+
opacity var(--duration-fast) var(--ease),
|
|
79
|
+
scale var(--duration-fast) var(--ease),
|
|
80
|
+
translate var(--duration-fast) var(--ease);
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
.flyout.is-open:not(.is-sheet) {
|
|
@@ -81,6 +94,7 @@
|
|
|
81
94
|
/* Bottom-sheet presentation. surface.js toggles .is-sheet when the flyout is
|
|
82
95
|
opened on coarse pointer / narrow viewports. */
|
|
83
96
|
.flyout.is-sheet {
|
|
97
|
+
--menu-item-size: var(--control-size-lg);
|
|
84
98
|
position: fixed;
|
|
85
99
|
inset-inline: 0;
|
|
86
100
|
inset-block-start: auto;
|
|
@@ -91,8 +105,8 @@
|
|
|
91
105
|
max-block-size: min(calc(var(--viewport-block) * 0.75), 32rem);
|
|
92
106
|
overflow: auto;
|
|
93
107
|
grid-template-columns: 1fr;
|
|
94
|
-
padding: max(var(--space-
|
|
95
|
-
max(var(--space-
|
|
108
|
+
padding: max(var(--space-30), env(safe-area-inset-top)) var(--space-30)
|
|
109
|
+
max(var(--space-30), env(safe-area-inset-bottom));
|
|
96
110
|
border-end-start-radius: 0;
|
|
97
111
|
border-end-end-radius: 0;
|
|
98
112
|
}
|
|
@@ -105,23 +119,23 @@
|
|
|
105
119
|
|
|
106
120
|
.flyout.is-sheet[hidden] {
|
|
107
121
|
scale: 1;
|
|
108
|
-
translate: 0 var(--space-
|
|
122
|
+
translate: 0 var(--space-30);
|
|
109
123
|
}
|
|
110
124
|
|
|
111
125
|
@starting-style {
|
|
112
126
|
.flyout.is-sheet.is-open {
|
|
113
127
|
scale: 1;
|
|
114
|
-
translate: 0 var(--space-
|
|
128
|
+
translate: 0 var(--space-30);
|
|
115
129
|
}
|
|
116
130
|
}
|
|
117
131
|
|
|
118
132
|
@supports (transition-behavior: allow-discrete) {
|
|
119
133
|
.flyout {
|
|
120
134
|
transition:
|
|
121
|
-
opacity var(--duration-fast
|
|
122
|
-
scale var(--duration-fast
|
|
123
|
-
translate var(--duration-fast
|
|
124
|
-
display var(--duration-fast
|
|
135
|
+
opacity var(--duration-fast) var(--ease),
|
|
136
|
+
scale var(--duration-fast) var(--ease),
|
|
137
|
+
translate var(--duration-fast) var(--ease),
|
|
138
|
+
display var(--duration-fast) allow-discrete;
|
|
125
139
|
}
|
|
126
140
|
}
|
|
127
141
|
|
|
@@ -131,7 +145,7 @@
|
|
|
131
145
|
|
|
132
146
|
.flyout > :where(section, footer) {
|
|
133
147
|
min-inline-size: 0;
|
|
134
|
-
padding: var(--space-
|
|
148
|
+
padding: var(--space-20);
|
|
135
149
|
}
|
|
136
150
|
|
|
137
151
|
.flyout > section > :where(h1, h2, h3, h4, h5, h6) {
|
|
@@ -143,8 +157,8 @@
|
|
|
143
157
|
|
|
144
158
|
.flyout > section > ul {
|
|
145
159
|
display: grid;
|
|
146
|
-
gap: var(--space-
|
|
147
|
-
margin: var(--space-
|
|
160
|
+
gap: var(--space-10);
|
|
161
|
+
margin: var(--space-10) 0 0;
|
|
148
162
|
padding: 0;
|
|
149
163
|
list-style: none;
|
|
150
164
|
}
|
|
@@ -153,91 +167,6 @@
|
|
|
153
167
|
margin: 0;
|
|
154
168
|
}
|
|
155
169
|
|
|
156
|
-
/*
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
:where(li) keeps specificity at a single class (0,1,0) so consumer
|
|
160
|
-
overrides behave the same as a plain .flyout > rule. */
|
|
161
|
-
:is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]) {
|
|
162
|
-
display: flex;
|
|
163
|
-
align-items: center;
|
|
164
|
-
justify-content: flex-start;
|
|
165
|
-
gap: var(--space-2);
|
|
166
|
-
inline-size: 100%;
|
|
167
|
-
min-block-size: var(--control-size);
|
|
168
|
-
padding-inline: var(--space-2);
|
|
169
|
-
border: 0;
|
|
170
|
-
border-radius: var(--radius-sm);
|
|
171
|
-
background: none;
|
|
172
|
-
color: var(--text);
|
|
173
|
-
font: inherit;
|
|
174
|
-
font-weight: var(--font-weight);
|
|
175
|
-
text-decoration: none;
|
|
176
|
-
text-align: start;
|
|
177
|
-
white-space: nowrap;
|
|
178
|
-
cursor: pointer;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
:is(.flyout.is-sheet, .flyout.is-sheet :where(li)) > :where(button, a, [role="menuitem"]) {
|
|
182
|
-
min-block-size: var(--control-size-lg);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
:is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):focus-visible {
|
|
186
|
-
background: var(--surface-subtle);
|
|
187
|
-
outline: var(--focus-outline);
|
|
188
|
-
outline-offset: var(--focus-outline-offset);
|
|
189
|
-
box-shadow: var(--focus-ring-shadow);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
:is(.flyout, .flyout :where(li))
|
|
193
|
-
> :where(button, a, [role="menuitem"]):is(:disabled, [aria-disabled="true"]) {
|
|
194
|
-
cursor: not-allowed;
|
|
195
|
-
opacity: var(--disabled-opacity);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
:is(.flyout, .flyout :where(li)) > :where(a, [role="menuitem"])[aria-disabled="true"] {
|
|
199
|
-
pointer-events: none;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
@media (hover: hover) {
|
|
203
|
-
:is(.flyout, .flyout :where(li))
|
|
204
|
-
> :where(button, a, [role="menuitem"]):hover:not(
|
|
205
|
-
:where(:focus-visible, :disabled, [aria-disabled="true"])
|
|
206
|
-
) {
|
|
207
|
-
background: var(--surface-subtle);
|
|
208
|
-
outline: none;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
.flyout > hr,
|
|
213
|
-
.flyout > li > hr {
|
|
214
|
-
inline-size: 100%;
|
|
215
|
-
margin: 0;
|
|
216
|
-
margin-block: var(--space-1);
|
|
217
|
-
border: 0;
|
|
218
|
-
border-block-start: var(--border-width) solid var(--border);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
@media (forced-colors: active) {
|
|
222
|
-
.flyout {
|
|
223
|
-
border-color: ButtonText;
|
|
224
|
-
background: Canvas;
|
|
225
|
-
color: CanvasText;
|
|
226
|
-
box-shadow: none;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
:is(.flyout, .flyout :where(li)) > :where(button, a, [role="menuitem"]):focus-visible {
|
|
230
|
-
background: Canvas;
|
|
231
|
-
color: CanvasText;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
@media (hover: hover) {
|
|
235
|
-
:is(.flyout, .flyout :where(li))
|
|
236
|
-
> :where(button, a, [role="menuitem"]):hover:not(:where(:disabled, [aria-disabled="true"])) {
|
|
237
|
-
outline: var(--border-width) solid ButtonText;
|
|
238
|
-
outline-offset: -1px;
|
|
239
|
-
background: Canvas;
|
|
240
|
-
color: CanvasText;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
170
|
+
/* Vertical dividers — .menu-separator (menu.css) is the canonical way to
|
|
171
|
+
separate menu items. Flyout panels that are not menus use auto grid gap
|
|
172
|
+
declared on .flyout itself. */
|
|
@@ -7,6 +7,18 @@
|
|
|
7
7
|
* Cascade note: .join writes border-radius longhands on its direct children.
|
|
8
8
|
* Keep this file loaded after control/component styles so those corners win at
|
|
9
9
|
* equal specificity.
|
|
10
|
+
*
|
|
11
|
+
* Public hooks:
|
|
12
|
+
* --join-radius
|
|
13
|
+
*
|
|
14
|
+
* Internal:
|
|
15
|
+
* --join-ss
|
|
16
|
+
* --join-se
|
|
17
|
+
* --join-es
|
|
18
|
+
* --join-ee
|
|
19
|
+
* --control-border
|
|
20
|
+
* --control-bg
|
|
21
|
+
* --control-fg
|
|
10
22
|
*/
|
|
11
23
|
.join {
|
|
12
24
|
--join-radius: var(--radius);
|
|
@@ -34,7 +46,7 @@
|
|
|
34
46
|
display: inline-flex;
|
|
35
47
|
justify-content: center;
|
|
36
48
|
min-block-size: var(--control-size);
|
|
37
|
-
padding-inline: var(--space-
|
|
49
|
+
padding-inline: var(--space-30);
|
|
38
50
|
border: var(--border-width) solid var(--control-border);
|
|
39
51
|
border-radius: var(--radius);
|
|
40
52
|
background: var(--control-bg);
|
|
@@ -95,8 +107,7 @@
|
|
|
95
107
|
focus, and unsupported :has() browsers retain the control's normal ring. */
|
|
96
108
|
.join:has(> :is(.input, .textarea, .select):focus-visible) {
|
|
97
109
|
border-radius: var(--join-radius);
|
|
98
|
-
outline:
|
|
99
|
-
outline-offset: var(--focus-outline-offset);
|
|
110
|
+
outline: 2px solid transparent;
|
|
100
111
|
box-shadow: var(--focus-ring-shadow);
|
|
101
112
|
}
|
|
102
113
|
|