actual-css 0.4.1 → 0.5.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 +54 -0
- package/README.md +2 -2
- package/dist/actual.css +53 -14
- package/dist/actual.full.css +300 -91
- package/dist/actual.full.js +1 -1
- package/dist/actual.full.min.css +1 -1
- package/dist/actual.min.css +1 -1
- package/docs/design-notes/spacing-units.md +286 -0
- package/docs/navigation.json +1 -0
- package/docs/pages/components/alert.md +1 -1
- package/docs/pages/components/app-navigation.md +2 -0
- package/docs/pages/components/badge.md +17 -3
- package/docs/pages/components/button.md +9 -2
- package/docs/pages/components/card.md +13 -0
- package/docs/pages/components/data-list.md +72 -0
- package/docs/pages/components/dialog.md +2 -0
- package/docs/pages/components/drawer.md +2 -0
- package/docs/pages/components/fab.md +2 -0
- package/docs/pages/components/meter.md +56 -1
- package/docs/pages/components/progress.md +10 -0
- package/docs/pages/components/skeleton.md +2 -0
- package/docs/pages/components/steps.md +10 -2
- package/docs/pages/components/table.md +1 -0
- package/docs/pages/enhancements/flyout.md +2 -0
- package/docs/pages/enhancements/status-bar.md +10 -1
- package/docs/pages/examples/overview.md +2 -1
- package/docs/pages/forms/joined-controls.md +2 -0
- package/docs/pages/forms/overview.md +1 -1
- package/docs/pages/forms/range.md +2 -0
- package/docs/pages/forms/states-and-sizes.md +1 -1
- package/docs/pages/forms/validation.md +2 -0
- package/docs/pages/foundations/philosophy.md +11 -1
- package/docs/pages/foundations/tokens.md +7 -3
- package/docs/pages/foundations/typography.md +10 -2
- package/docs/pages/guides/introduction.md +1 -1
- package/docs/pages/layout/scroll-snap.md +2 -0
- package/docs/pages/layout/sidebar-layout.md +2 -0
- package/docs/pages/layout/topbar.md +2 -0
- package/docs/pages/utilities/accessibility.md +18 -0
- package/package.json +1 -1
- package/scripts/reserved-classes.json +4 -0
- package/src/css/components/actions.css +1 -0
- package/src/css/components/breadcrumb.css +1 -0
- package/src/css/components/data-list.css +27 -0
- package/src/css/components/drawer.css +30 -11
- package/src/css/components/flyout.css +17 -12
- package/src/css/components/index.css +1 -0
- package/src/css/components/meter.css +28 -1
- package/src/css/components/modal.css +28 -11
- package/src/css/components/navbar.css +2 -0
- package/src/css/components/pagination.css +1 -0
- package/src/css/components/progress.css +5 -0
- package/src/css/components/status-bar.css +31 -15
- package/src/css/components/steps.css +36 -9
- package/src/css/components/surface.css +5 -3
- package/src/css/components/tab.css +1 -0
- package/src/css/components/tooltip.css +5 -8
- package/src/css/core/base.css +7 -1
- package/src/css/core/intents.css +6 -0
- package/src/css/core/tokens.css +23 -9
- package/src/css/core/variants.css +17 -4
- package/src/css/forms/form-actions.css +1 -0
- package/src/css/forms/form.css +4 -4
- package/src/css/layout/cluster.css +1 -0
- package/src/css/layout/scroll-snap.css +1 -0
- package/src/css/layout/sidebar-layout.css +1 -0
- package/src/css/layout/switcher.css +1 -0
- package/src/css/layout/topbar.css +1 -0
- package/src/css/typography/prose.css +2 -3
- package/src/css/utilities/base.css +16 -0
- package/src/js/selectors.js +1 -0
- package/src/js/status.js +88 -7
- package/src/js/surface.js +2 -11
- package/src/js/transition.js +20 -0
package/dist/actual.full.css
CHANGED
|
@@ -60,8 +60,8 @@ select {
|
|
|
60
60
|
*
|
|
61
61
|
* Derived: "Theme-derived aliases" and "State tokens" reference intent and
|
|
62
62
|
* surface tokens and follow the theme; do not hard-code values into them.
|
|
63
|
-
* Internal: indicator offsets, --
|
|
64
|
-
*
|
|
63
|
+
* Internal: indicator offsets, --disabled-opacity and the like are
|
|
64
|
+
* consumed by components, not authored.
|
|
65
65
|
*
|
|
66
66
|
* Component-local hooks and internal state relays live with their
|
|
67
67
|
* components. See docs/pages/foundations/tokens.md for the public/internal
|
|
@@ -85,9 +85,10 @@ select {
|
|
|
85
85
|
--font-size-md: 1rem;
|
|
86
86
|
--font-size-lg: 1.125rem;
|
|
87
87
|
|
|
88
|
-
/* Spacing — official steps are named in tens so the scale stays open
|
|
89
|
-
|
|
90
|
-
--space-45…)
|
|
88
|
+
/* Spacing — official steps are named in tens so the scale stays open.
|
|
89
|
+
Actual CSS will never define a --space-* that is not a multiple of 10:
|
|
90
|
+
the intermediate names (--space-15, --space-45…) are reserved for
|
|
91
|
+
applications, and no future framework step can collide with them. */
|
|
91
92
|
--gap: 0.75rem;
|
|
92
93
|
--density-space: var(--space-40);
|
|
93
94
|
--density-compact-size: 1.5rem;
|
|
@@ -105,14 +106,25 @@ select {
|
|
|
105
106
|
--shadow-popout: 0 0.25rem 0.75rem rgb(0 0 0 / 0.15);
|
|
106
107
|
|
|
107
108
|
/* Motion — see reset.css for the prefers-reduced-motion hard reset.
|
|
108
|
-
--duration
|
|
109
|
-
animation rates below tune one-shot open/close and decorative loops.
|
|
109
|
+
--duration scales component transitions (hover/focus); the dedicated
|
|
110
|
+
animation rates below tune one-shot open/close and decorative loops.
|
|
111
|
+
Generic state/interaction motion uses the CSS default `ease` directly
|
|
112
|
+
(registered nowhere). --ease-enter/--ease-exit express the character of
|
|
113
|
+
one-shot presence changes, owned by the open/closed state rules that
|
|
114
|
+
separate them (status-bar, drawer, modal). The pair follows the standard
|
|
115
|
+
M3 rhythm; the more aggressive emphasized-decelerate entrance is
|
|
116
|
+
deliberately not offered because it only pays off on 250–400ms motions,
|
|
117
|
+
beyond this vocabulary. Toggles that share one transition list at
|
|
118
|
+
--duration-fast (flyout, tooltip) and pure-opacity backdrops stay on
|
|
119
|
+
`ease`: at 100ms the curve has almost no resolving time, and a scrim is
|
|
120
|
+
not traveling anywhere. */
|
|
110
121
|
--duration: 150ms;
|
|
111
122
|
--duration-fast: 100ms;
|
|
112
123
|
--duration-slow: 200ms;
|
|
113
124
|
--duration-spin: 0.75s;
|
|
114
125
|
--duration-shimmer: 1.2s;
|
|
115
|
-
--ease:
|
|
126
|
+
--ease-enter: cubic-bezier(0.2, 0, 0, 1);
|
|
127
|
+
--ease-exit: cubic-bezier(0.4, 0, 1, 1);
|
|
116
128
|
|
|
117
129
|
/* Focus ring — shared by every interactive component's :focus-visible */
|
|
118
130
|
--focus-outline-color: currentColor;
|
|
@@ -130,7 +142,9 @@ select {
|
|
|
130
142
|
--backdrop-opacity: 0.45;
|
|
131
143
|
--backdrop-fill: rgb(0 0 0 / var(--backdrop-opacity));
|
|
132
144
|
|
|
133
|
-
/*
|
|
145
|
+
/* Bar thickness shared by .progress and .meter — two conceptual variants of
|
|
146
|
+
the same geometry. Public: set it on the element or on an application
|
|
147
|
+
class rather than reaching for a size variant. */
|
|
134
148
|
--bar-height: 0.65rem;
|
|
135
149
|
|
|
136
150
|
/* Controls — inputs and buttons share --control-size so heights always match.
|
|
@@ -453,6 +467,9 @@ select {
|
|
|
453
467
|
*
|
|
454
468
|
* Sits between reset (browser defaults) and prose (rich content scope).
|
|
455
469
|
* These styles apply everywhere — cards, dialogs, heroes — not only in prose.
|
|
470
|
+
*
|
|
471
|
+
* Public hooks:
|
|
472
|
+
* --link
|
|
456
473
|
*/
|
|
457
474
|
|
|
458
475
|
body {
|
|
@@ -462,8 +479,11 @@ body {
|
|
|
462
479
|
line-height: var(--line-height);
|
|
463
480
|
}
|
|
464
481
|
|
|
482
|
+
/* Bare links inherit their ink by default, so nothing changes unless a theme
|
|
483
|
+
opts in by setting --link. Because this is an element selector, any component
|
|
484
|
+
rule that colors its own anchors still wins. */
|
|
465
485
|
a {
|
|
466
|
-
color: inherit;
|
|
486
|
+
color: var(--link, inherit);
|
|
467
487
|
text-underline-offset: 0.18em;
|
|
468
488
|
}
|
|
469
489
|
|
|
@@ -547,11 +567,17 @@ small {
|
|
|
547
567
|
--intent-fg: var(--neutral-fg);
|
|
548
568
|
}
|
|
549
569
|
|
|
570
|
+
/* Paint an inherited or local intent on a simple foreground element without
|
|
571
|
+
turning the intent classes into general-purpose color utilities. */
|
|
572
|
+
.intent-color {
|
|
573
|
+
color: var(--intent);
|
|
574
|
+
}
|
|
575
|
+
|
|
550
576
|
/*
|
|
551
577
|
* Cross-cutting variant token mapping.
|
|
552
578
|
*
|
|
553
|
-
* Variant scope: .solid/.soft/.outline set --ui-* for components that
|
|
554
|
-
* shared variants. .inverted is a surface modifier, not a variant: it paints
|
|
579
|
+
* Variant scope: .solid/.soft/.outline/.surface set --ui-* for components that
|
|
580
|
+
* opt into shared variants. .inverted is a surface modifier, not a variant: it paints
|
|
555
581
|
* the element directly (background/color/border-color) so it works on any bare
|
|
556
582
|
* block, and remaps the shared --ui-* tokens so participating components
|
|
557
583
|
* (.card, .navbar, .alert, .badge) invert through their own rules. Loaded
|
|
@@ -570,8 +596,10 @@ small {
|
|
|
570
596
|
* components may consume --density-* when the density context should affect
|
|
571
597
|
* their local rhythm. Compact components may consume --density-compact-size.
|
|
572
598
|
* Components with bespoke sizing (spinner, avatar) define local .sm/.lg;
|
|
573
|
-
* applying .sm/.lg to card, dialog, accordion, navbar, table
|
|
574
|
-
* a no-op.
|
|
599
|
+
* applying .sm/.lg to card, dialog, accordion, navbar, table, progress, meter
|
|
600
|
+
* is a no-op. Progress and meter are deliberate: a bar keeps its inline size
|
|
601
|
+
* and only changes thickness, which --bar-height expresses better than a
|
|
602
|
+
* three-step scale.
|
|
575
603
|
*
|
|
576
604
|
* Intent list source of truth: intents.css. Components consume --intent* tokens
|
|
577
605
|
* instead of re-listing intent classes.
|
|
@@ -594,6 +622,17 @@ small {
|
|
|
594
622
|
--ui-border: var(--intent, currentColor);
|
|
595
623
|
}
|
|
596
624
|
|
|
625
|
+
/* Neutral chrome, intent only in the ink: the page surface with the theme
|
|
626
|
+
border. .soft is the intent-tinted treatment (its baseline fallback uses
|
|
627
|
+
--surface-subtle) and .outline has no fill at all, so neither can express
|
|
628
|
+
it. Deliberately literal — no color-mix enhancement — so this stays the one
|
|
629
|
+
variant that reads exactly as the theme's own surface. */
|
|
630
|
+
.surface {
|
|
631
|
+
--ui-bg: var(--surface);
|
|
632
|
+
--ui-fg: var(--intent, var(--text));
|
|
633
|
+
--ui-border: var(--border);
|
|
634
|
+
}
|
|
635
|
+
|
|
597
636
|
/* Inverse surface treatment. Paints the element directly (so it works on any
|
|
598
637
|
bare block) and remaps the shared --ui-* tokens so opt-in components
|
|
599
638
|
(.card, .navbar) invert through their own rules. Because this loads before
|
|
@@ -776,9 +815,8 @@ small {
|
|
|
776
815
|
font-size: var(--prose-h4);
|
|
777
816
|
}
|
|
778
817
|
|
|
779
|
-
/*
|
|
780
|
-
|
|
781
|
-
it without having to restate the rule. */
|
|
818
|
+
/* --link is a theme-level token (core/base.css also reads it for bare links);
|
|
819
|
+
prose falls back to --primary so a theme that never sets it is unaffected. */
|
|
782
820
|
.prose :where(a) {
|
|
783
821
|
color: var(--link, var(--primary));
|
|
784
822
|
text-decoration-line: underline;
|
|
@@ -1096,6 +1134,7 @@ small {
|
|
|
1096
1134
|
*/
|
|
1097
1135
|
.cluster {
|
|
1098
1136
|
display: flex;
|
|
1137
|
+
flex-direction: row;
|
|
1099
1138
|
flex-wrap: var(--cluster-wrap, wrap);
|
|
1100
1139
|
align-items: var(--cluster-align, center);
|
|
1101
1140
|
justify-content: var(--cluster-justify, flex-start);
|
|
@@ -1276,6 +1315,7 @@ small {
|
|
|
1276
1315
|
*/
|
|
1277
1316
|
.switcher {
|
|
1278
1317
|
display: flex;
|
|
1318
|
+
flex-direction: row;
|
|
1279
1319
|
flex-wrap: wrap;
|
|
1280
1320
|
gap: var(--gap);
|
|
1281
1321
|
}
|
|
@@ -1305,6 +1345,7 @@ small {
|
|
|
1305
1345
|
*/
|
|
1306
1346
|
.sidebar-layout {
|
|
1307
1347
|
display: flex;
|
|
1348
|
+
flex-direction: row;
|
|
1308
1349
|
flex-wrap: wrap;
|
|
1309
1350
|
gap: var(--gap);
|
|
1310
1351
|
align-items: flex-start;
|
|
@@ -1702,6 +1743,7 @@ small {
|
|
|
1702
1743
|
--scroll-snap-item-size: auto;
|
|
1703
1744
|
|
|
1704
1745
|
display: flex;
|
|
1746
|
+
flex-direction: row;
|
|
1705
1747
|
gap: var(--scroll-snap-gap);
|
|
1706
1748
|
overflow-x: auto;
|
|
1707
1749
|
}
|
|
@@ -1773,6 +1815,7 @@ small {
|
|
|
1773
1815
|
z-index: var(--z-sticky);
|
|
1774
1816
|
isolation: isolate;
|
|
1775
1817
|
display: flex;
|
|
1818
|
+
flex-direction: row;
|
|
1776
1819
|
align-items: center;
|
|
1777
1820
|
gap: var(--gap);
|
|
1778
1821
|
padding-block: var(--space-30);
|
|
@@ -1817,6 +1860,10 @@ small {
|
|
|
1817
1860
|
* Individual controls keep their own files; .choice label layout lives in
|
|
1818
1861
|
* choice.css; .form-actions lives in form-actions.css.
|
|
1819
1862
|
*
|
|
1863
|
+
* .field-group owns its own box only. Distance between sibling groups is a
|
|
1864
|
+
* composition concern (.stack on the form), never a sibling margin here: the
|
|
1865
|
+
* component cannot know whether its siblings are stacked or gridded.
|
|
1866
|
+
*
|
|
1820
1867
|
* Public API: .field, .field-label, .field-help, .field-error, .field-group,
|
|
1821
1868
|
* .required-mark.
|
|
1822
1869
|
*
|
|
@@ -1837,10 +1884,6 @@ small {
|
|
|
1837
1884
|
border-radius: var(--radius);
|
|
1838
1885
|
}
|
|
1839
1886
|
|
|
1840
|
-
.field-group + .field-group {
|
|
1841
|
-
margin-block-start: var(--space-40);
|
|
1842
|
-
}
|
|
1843
|
-
|
|
1844
1887
|
.field-label,
|
|
1845
1888
|
.field-group > legend {
|
|
1846
1889
|
color: var(--text);
|
|
@@ -2420,6 +2463,7 @@ small {
|
|
|
2420
2463
|
*/
|
|
2421
2464
|
.form-actions {
|
|
2422
2465
|
display: flex;
|
|
2466
|
+
flex-direction: row;
|
|
2423
2467
|
flex-wrap: wrap;
|
|
2424
2468
|
gap: var(--gap);
|
|
2425
2469
|
align-items: var(--form-actions-align, center);
|
|
@@ -3965,6 +4009,7 @@ a.badge[aria-disabled="true"] {
|
|
|
3965
4009
|
--gap: var(--space-20);
|
|
3966
4010
|
|
|
3967
4011
|
display: flex;
|
|
4012
|
+
flex-direction: row;
|
|
3968
4013
|
flex-wrap: wrap;
|
|
3969
4014
|
align-items: center;
|
|
3970
4015
|
gap: var(--gap);
|
|
@@ -4154,7 +4199,9 @@ a.badge[aria-disabled="true"] {
|
|
|
4154
4199
|
z-index: calc(var(--z-menu) - 1);
|
|
4155
4200
|
background: var(--backdrop-fill);
|
|
4156
4201
|
opacity: 1;
|
|
4157
|
-
|
|
4202
|
+
/* A scrim never travels; it fades on the neutral `ease`. Duration matches
|
|
4203
|
+
the flyout sheet it accompanies so it never lags the panel. */
|
|
4204
|
+
transition: opacity var(--duration-fast) ease;
|
|
4158
4205
|
}
|
|
4159
4206
|
|
|
4160
4207
|
.surface-backdrop[hidden] {
|
|
@@ -4171,8 +4218,8 @@ a.badge[aria-disabled="true"] {
|
|
|
4171
4218
|
@supports (transition-behavior: allow-discrete) {
|
|
4172
4219
|
.surface-backdrop {
|
|
4173
4220
|
transition:
|
|
4174
|
-
opacity var(--duration)
|
|
4175
|
-
display var(--duration) allow-discrete;
|
|
4221
|
+
opacity var(--duration-fast) ease,
|
|
4222
|
+
display var(--duration-fast) allow-discrete;
|
|
4176
4223
|
}
|
|
4177
4224
|
}
|
|
4178
4225
|
@media print {
|
|
@@ -4222,12 +4269,14 @@ dialog.modal {
|
|
|
4222
4269
|
* Keep the open dialog root untransformed. Fixed overlays mounted inside a
|
|
4223
4270
|
* modal dialog use viewport coordinates; transform/translate/scale on this
|
|
4224
4271
|
* element would make them position against the dialog instead. The closed
|
|
4225
|
-
* state can still carry a small transform for enter/exit motion.
|
|
4272
|
+
* state can still carry a small transform for enter/exit motion. The lift
|
|
4273
|
+
* is a pure vertical offset: scaling a wide panel around its center drags
|
|
4274
|
+
* both edges, which reads as horizontal movement.
|
|
4226
4275
|
*/
|
|
4227
|
-
transform: translateY(0.35rem)
|
|
4276
|
+
transform: translateY(0.35rem);
|
|
4228
4277
|
transition:
|
|
4229
|
-
opacity var(--duration),
|
|
4230
|
-
transform var(--duration);
|
|
4278
|
+
opacity var(--duration) var(--ease-exit),
|
|
4279
|
+
transform var(--duration) var(--ease-exit);
|
|
4231
4280
|
}
|
|
4232
4281
|
|
|
4233
4282
|
dialog.modal > form,
|
|
@@ -4346,33 +4395,46 @@ dialog.modal.dialog-confirmation > form > footer {
|
|
|
4346
4395
|
dialog.modal[open] {
|
|
4347
4396
|
opacity: 1;
|
|
4348
4397
|
transform: none;
|
|
4398
|
+
transition:
|
|
4399
|
+
opacity var(--duration) var(--ease-enter),
|
|
4400
|
+
transform var(--duration) var(--ease-enter);
|
|
4349
4401
|
}
|
|
4350
4402
|
|
|
4351
4403
|
@starting-style {
|
|
4352
4404
|
dialog.modal[open] {
|
|
4353
4405
|
opacity: 0;
|
|
4354
|
-
transform: translateY(0.35rem)
|
|
4406
|
+
transform: translateY(0.35rem);
|
|
4355
4407
|
}
|
|
4356
4408
|
}
|
|
4357
4409
|
|
|
4358
4410
|
dialog.modal::backdrop {
|
|
4359
4411
|
background: var(--backdrop-fill);
|
|
4360
4412
|
opacity: 0;
|
|
4361
|
-
|
|
4413
|
+
/* Scrim curve stays neutral `ease`; only the panel carries the character
|
|
4414
|
+
curves. */
|
|
4415
|
+
transition: opacity var(--duration) ease;
|
|
4362
4416
|
}
|
|
4363
4417
|
|
|
4364
4418
|
@supports (transition-behavior: allow-discrete) {
|
|
4365
4419
|
dialog.modal {
|
|
4366
4420
|
transition:
|
|
4367
|
-
opacity var(--duration),
|
|
4368
|
-
transform var(--duration),
|
|
4421
|
+
opacity var(--duration) var(--ease-exit),
|
|
4422
|
+
transform var(--duration) var(--ease-exit),
|
|
4423
|
+
overlay var(--duration) allow-discrete,
|
|
4424
|
+
display var(--duration) allow-discrete;
|
|
4425
|
+
}
|
|
4426
|
+
|
|
4427
|
+
dialog.modal[open] {
|
|
4428
|
+
transition:
|
|
4429
|
+
opacity var(--duration) var(--ease-enter),
|
|
4430
|
+
transform var(--duration) var(--ease-enter),
|
|
4369
4431
|
overlay var(--duration) allow-discrete,
|
|
4370
4432
|
display var(--duration) allow-discrete;
|
|
4371
4433
|
}
|
|
4372
4434
|
|
|
4373
4435
|
dialog.modal::backdrop {
|
|
4374
4436
|
transition:
|
|
4375
|
-
opacity var(--duration),
|
|
4437
|
+
opacity var(--duration) ease,
|
|
4376
4438
|
overlay var(--duration) allow-discrete,
|
|
4377
4439
|
display var(--duration) allow-discrete;
|
|
4378
4440
|
}
|
|
@@ -4397,13 +4459,15 @@ html.has-modal-open.had-scrollbar {
|
|
|
4397
4459
|
}
|
|
4398
4460
|
|
|
4399
4461
|
@media (prefers-reduced-motion: no-preference) {
|
|
4462
|
+
/* Wrong-close feedback and view-transition transport are motion quirks, not
|
|
4463
|
+
presence enter/exit, so they stay on the plain CSS default easing. */
|
|
4400
4464
|
dialog.modal.is-static {
|
|
4401
|
-
animation: actual-dialog-static var(--duration-slow)
|
|
4465
|
+
animation: actual-dialog-static var(--duration-slow) ease;
|
|
4402
4466
|
}
|
|
4403
4467
|
|
|
4404
4468
|
::view-transition-group(actual-dialog) {
|
|
4405
4469
|
animation-duration: var(--duration);
|
|
4406
|
-
animation-timing-function:
|
|
4470
|
+
animation-timing-function: ease;
|
|
4407
4471
|
}
|
|
4408
4472
|
}
|
|
4409
4473
|
|
|
@@ -4502,11 +4566,16 @@ html.has-modal-open.had-scrollbar {
|
|
|
4502
4566
|
*
|
|
4503
4567
|
* Internal:
|
|
4504
4568
|
* --drawer-closed-translate (side/RTL positioning state)
|
|
4569
|
+
* --drawer-motion-duration (shared by panel and ::backdrop so exit duration
|
|
4570
|
+
* changes in one place; entry state redefines it longer)
|
|
4505
4571
|
*/
|
|
4506
4572
|
dialog.drawer {
|
|
4507
4573
|
--drawer-size: 20rem;
|
|
4508
4574
|
--drawer-pad: var(--space-40);
|
|
4509
4575
|
--drawer-closed-translate: -100%;
|
|
4576
|
+
/* Exit is shorter than entry so the panel clears quickly; the scrim reads
|
|
4577
|
+
the same variable through inheritance and never lags the panel. */
|
|
4578
|
+
--drawer-motion-duration: var(--duration);
|
|
4510
4579
|
|
|
4511
4580
|
/* Keep the surface anchored to the viewport in the top layer. This also
|
|
4512
4581
|
provides the containing block for the absolutely positioned close button.
|
|
@@ -4530,16 +4599,20 @@ dialog.drawer {
|
|
|
4530
4599
|
opacity: 0;
|
|
4531
4600
|
transform: translateX(var(--drawer-closed-translate));
|
|
4532
4601
|
transition:
|
|
4533
|
-
opacity var(--duration-
|
|
4534
|
-
transform var(--duration-
|
|
4602
|
+
opacity var(--drawer-motion-duration) var(--ease-exit),
|
|
4603
|
+
transform var(--drawer-motion-duration) var(--ease-exit);
|
|
4535
4604
|
}
|
|
4536
4605
|
|
|
4537
4606
|
dialog.drawer[open] {
|
|
4607
|
+
--drawer-motion-duration: var(--duration-slow);
|
|
4538
4608
|
display: grid;
|
|
4539
4609
|
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
4540
4610
|
gap: var(--space-40);
|
|
4541
4611
|
opacity: 1;
|
|
4542
4612
|
transform: translateX(0);
|
|
4613
|
+
transition:
|
|
4614
|
+
opacity var(--drawer-motion-duration) var(--ease-enter),
|
|
4615
|
+
transform var(--drawer-motion-duration) var(--ease-enter);
|
|
4543
4616
|
}
|
|
4544
4617
|
|
|
4545
4618
|
/* Backdrop color sourced from components/surface.css so it matches .modal
|
|
@@ -4547,7 +4620,9 @@ dialog.drawer[open] {
|
|
|
4547
4620
|
dialog.drawer::backdrop {
|
|
4548
4621
|
background: var(--backdrop-fill);
|
|
4549
4622
|
opacity: 0;
|
|
4550
|
-
|
|
4623
|
+
/* Scrim curve stays neutral `ease`; only the panel's character curves
|
|
4624
|
+
apply. Duration follows --drawer-motion-duration through inheritance. */
|
|
4625
|
+
transition: opacity var(--drawer-motion-duration) ease;
|
|
4551
4626
|
}
|
|
4552
4627
|
|
|
4553
4628
|
dialog.drawer[data-side="end"] {
|
|
@@ -4583,17 +4658,25 @@ dialog.drawer nav {
|
|
|
4583
4658
|
@supports (transition-behavior: allow-discrete) {
|
|
4584
4659
|
dialog.drawer {
|
|
4585
4660
|
transition:
|
|
4586
|
-
opacity var(--duration-
|
|
4587
|
-
transform var(--duration-
|
|
4588
|
-
overlay var(--duration
|
|
4589
|
-
display var(--duration
|
|
4661
|
+
opacity var(--drawer-motion-duration) var(--ease-exit),
|
|
4662
|
+
transform var(--drawer-motion-duration) var(--ease-exit),
|
|
4663
|
+
overlay var(--drawer-motion-duration) allow-discrete,
|
|
4664
|
+
display var(--drawer-motion-duration) allow-discrete;
|
|
4665
|
+
}
|
|
4666
|
+
|
|
4667
|
+
dialog.drawer[open] {
|
|
4668
|
+
transition:
|
|
4669
|
+
opacity var(--drawer-motion-duration) var(--ease-enter),
|
|
4670
|
+
transform var(--drawer-motion-duration) var(--ease-enter),
|
|
4671
|
+
overlay var(--drawer-motion-duration) allow-discrete,
|
|
4672
|
+
display var(--drawer-motion-duration) allow-discrete;
|
|
4590
4673
|
}
|
|
4591
4674
|
|
|
4592
4675
|
dialog.drawer::backdrop {
|
|
4593
4676
|
transition:
|
|
4594
|
-
opacity var(--duration
|
|
4595
|
-
overlay var(--duration
|
|
4596
|
-
display var(--duration
|
|
4677
|
+
opacity var(--drawer-motion-duration) ease,
|
|
4678
|
+
overlay var(--drawer-motion-duration) allow-discrete,
|
|
4679
|
+
display var(--drawer-motion-duration) allow-discrete;
|
|
4597
4680
|
}
|
|
4598
4681
|
}
|
|
4599
4682
|
|
|
@@ -4629,7 +4712,7 @@ dialog.drawer nav {
|
|
|
4629
4712
|
|
|
4630
4713
|
@media (prefers-reduced-motion: no-preference) {
|
|
4631
4714
|
dialog.drawer.is-static {
|
|
4632
|
-
animation: actual-dialog-static var(--duration-slow)
|
|
4715
|
+
animation: actual-dialog-static var(--duration-slow) ease;
|
|
4633
4716
|
}
|
|
4634
4717
|
}
|
|
4635
4718
|
|
|
@@ -4723,11 +4806,10 @@ dialog.drawer > form > header {
|
|
|
4723
4806
|
box-shadow: var(--shadow-popout);
|
|
4724
4807
|
list-style: none;
|
|
4725
4808
|
opacity: 1;
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
translate var(--duration-fast) var(--ease);
|
|
4809
|
+
/* Anchored flyouts fade in and out; scaling around the center would detach
|
|
4810
|
+
the anchored edge from its trigger on wide panels. The sheet presentation
|
|
4811
|
+
below adds its own translate motion. */
|
|
4812
|
+
transition: opacity var(--duration-fast) ease;
|
|
4731
4813
|
}
|
|
4732
4814
|
|
|
4733
4815
|
.flyout.is-open:not(.is-sheet) {
|
|
@@ -4737,7 +4819,6 @@ dialog.drawer > form > header {
|
|
|
4737
4819
|
@starting-style {
|
|
4738
4820
|
.flyout.is-open {
|
|
4739
4821
|
opacity: 0;
|
|
4740
|
-
scale: 0.98;
|
|
4741
4822
|
}
|
|
4742
4823
|
}
|
|
4743
4824
|
|
|
@@ -4759,22 +4840,24 @@ dialog.drawer > form > header {
|
|
|
4759
4840
|
max(var(--space-30), env(safe-area-inset-bottom));
|
|
4760
4841
|
border-end-start-radius: 0;
|
|
4761
4842
|
border-end-end-radius: 0;
|
|
4843
|
+
/* Sheet motion is a directional slide from the viewport edge; it replaces
|
|
4844
|
+
the base fade-only recipe. */
|
|
4845
|
+
transition:
|
|
4846
|
+
opacity var(--duration-fast) ease,
|
|
4847
|
+
translate var(--duration-fast) ease;
|
|
4762
4848
|
}
|
|
4763
4849
|
|
|
4764
4850
|
.flyout[hidden] {
|
|
4765
4851
|
display: none;
|
|
4766
4852
|
opacity: 0;
|
|
4767
|
-
scale: 0.98;
|
|
4768
4853
|
}
|
|
4769
4854
|
|
|
4770
4855
|
.flyout.is-sheet[hidden] {
|
|
4771
|
-
scale: 1;
|
|
4772
4856
|
translate: 0 var(--space-30);
|
|
4773
4857
|
}
|
|
4774
4858
|
|
|
4775
4859
|
@starting-style {
|
|
4776
4860
|
.flyout.is-sheet.is-open {
|
|
4777
|
-
scale: 1;
|
|
4778
4861
|
translate: 0 var(--space-30);
|
|
4779
4862
|
}
|
|
4780
4863
|
}
|
|
@@ -4782,9 +4865,14 @@ dialog.drawer > form > header {
|
|
|
4782
4865
|
@supports (transition-behavior: allow-discrete) {
|
|
4783
4866
|
.flyout {
|
|
4784
4867
|
transition:
|
|
4785
|
-
opacity var(--duration-fast)
|
|
4786
|
-
|
|
4787
|
-
|
|
4868
|
+
opacity var(--duration-fast) ease,
|
|
4869
|
+
display var(--duration-fast) allow-discrete;
|
|
4870
|
+
}
|
|
4871
|
+
|
|
4872
|
+
.flyout.is-sheet {
|
|
4873
|
+
transition:
|
|
4874
|
+
opacity var(--duration-fast) ease,
|
|
4875
|
+
translate var(--duration-fast) ease,
|
|
4788
4876
|
display var(--duration-fast) allow-discrete;
|
|
4789
4877
|
}
|
|
4790
4878
|
}
|
|
@@ -4989,31 +5077,28 @@ dialog.drawer > form > header {
|
|
|
4989
5077
|
overflow-wrap: anywhere;
|
|
4990
5078
|
pointer-events: auto;
|
|
4991
5079
|
user-select: none;
|
|
5080
|
+
/* Tooltips fade only: the anchor edge, marked by the arrow, must stay put
|
|
5081
|
+
during motion, and a 4% scale was perceptible on small text. Scaling moves
|
|
5082
|
+
the arrow tip away from its trigger on every placement. */
|
|
4992
5083
|
opacity: 1;
|
|
4993
|
-
|
|
4994
|
-
transition:
|
|
4995
|
-
opacity var(--duration-fast) var(--ease),
|
|
4996
|
-
scale var(--duration-fast) var(--ease);
|
|
5084
|
+
transition: opacity var(--duration-fast) ease;
|
|
4997
5085
|
}
|
|
4998
5086
|
|
|
4999
5087
|
.tooltip[hidden] {
|
|
5000
5088
|
display: none;
|
|
5001
5089
|
opacity: 0;
|
|
5002
|
-
scale: 0.96;
|
|
5003
5090
|
}
|
|
5004
5091
|
|
|
5005
5092
|
@starting-style {
|
|
5006
5093
|
.tooltip:not([hidden]) {
|
|
5007
5094
|
opacity: 0;
|
|
5008
|
-
scale: 0.96;
|
|
5009
5095
|
}
|
|
5010
5096
|
}
|
|
5011
5097
|
|
|
5012
5098
|
@supports (transition-behavior: allow-discrete) {
|
|
5013
5099
|
.tooltip {
|
|
5014
5100
|
transition:
|
|
5015
|
-
opacity var(--duration-fast)
|
|
5016
|
-
scale var(--duration-fast) var(--ease),
|
|
5101
|
+
opacity var(--duration-fast) ease,
|
|
5017
5102
|
display var(--duration-fast) allow-discrete;
|
|
5018
5103
|
}
|
|
5019
5104
|
}
|
|
@@ -5354,9 +5439,14 @@ dialog.drawer > form > header {
|
|
|
5354
5439
|
* Consumes the shared --intent/--primary for the value bar and --bar-height
|
|
5355
5440
|
* for thickness. Indeterminate state animates a shimmer using --duration-shimmer.
|
|
5356
5441
|
*
|
|
5442
|
+
* Thickness is a dimension, not a density step: the bar always spans its
|
|
5443
|
+
* container and only gets thinner or thicker, so --bar-height is the API and
|
|
5444
|
+
* .sm/.lg are deliberately not supported.
|
|
5445
|
+
*
|
|
5357
5446
|
* Public hooks:
|
|
5358
5447
|
* --progress-track
|
|
5359
5448
|
* --progress-value
|
|
5449
|
+
* --bar-height
|
|
5360
5450
|
*/
|
|
5361
5451
|
/* Intent boundary — inherited intents do not tint this component.
|
|
5362
5452
|
Local intent classes still win because :where() has zero specificity. */
|
|
@@ -5460,9 +5550,12 @@ dialog.drawer > form > header {
|
|
|
5460
5550
|
/*
|
|
5461
5551
|
* Status bar — singleton floating status area.
|
|
5462
5552
|
*
|
|
5463
|
-
* One element in the HTML, empty by default
|
|
5464
|
-
*
|
|
5465
|
-
*
|
|
5553
|
+
* One element in the HTML, empty by default. .is-open is the visual state, set
|
|
5554
|
+
* by status.js like any other surface: it lands after the message is written
|
|
5555
|
+
* and lifts before the bar is cleared, so the bar leaves in the exact state it
|
|
5556
|
+
* was shown in — same text, same width, same intent color — instead of snapping
|
|
5557
|
+
* to a neutral empty pill mid-exit. Emptying the text is the *end* of the exit,
|
|
5558
|
+
* not its trigger.
|
|
5466
5559
|
*
|
|
5467
5560
|
* Consumes intent like badge or alert. No need for status-bar-specific modifier
|
|
5468
5561
|
* classes — .danger / .success / .warning / .neutral from intents.css drive
|
|
@@ -5476,6 +5569,7 @@ dialog.drawer > form > header {
|
|
|
5476
5569
|
* Internal:
|
|
5477
5570
|
* --status-bg
|
|
5478
5571
|
* --status-fg
|
|
5572
|
+
* --status-viewport-offset (written by status.js while the bar is open)
|
|
5479
5573
|
*/
|
|
5480
5574
|
|
|
5481
5575
|
/* Intent boundary — inherited intents do not tint this component.
|
|
@@ -5490,7 +5584,9 @@ dialog.drawer > form > header {
|
|
|
5490
5584
|
--status-fg: var(--intent-fg, var(--surface));
|
|
5491
5585
|
|
|
5492
5586
|
position: fixed;
|
|
5493
|
-
|
|
5587
|
+
/* Fixed positioning tracks the layout viewport, which the mobile software
|
|
5588
|
+
keyboard covers. status.js writes the occluded band into the offset. */
|
|
5589
|
+
inset-block-end: calc(var(--space-40) + var(--status-viewport-offset, 0px));
|
|
5494
5590
|
inset-inline: var(--space-40);
|
|
5495
5591
|
z-index: var(--z-status);
|
|
5496
5592
|
|
|
@@ -5512,22 +5608,32 @@ dialog.drawer > form > header {
|
|
|
5512
5608
|
color: var(--status-fg);
|
|
5513
5609
|
box-shadow: var(--shadow-popout);
|
|
5514
5610
|
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5611
|
+
/* Closed by default. Opacity, not visibility or display: the bar has to stay
|
|
5612
|
+
in the accessibility tree to work as a live region. */
|
|
5613
|
+
opacity: 0;
|
|
5614
|
+
translate: 0 var(--space-30);
|
|
5518
5615
|
pointer-events: none;
|
|
5519
5616
|
|
|
5617
|
+
/* Exit is shorter than entry so dismissed feedback gets out of the way.
|
|
5618
|
+
background stays a shorthand so --status-bg still accepts gradients;
|
|
5619
|
+
solid colors expose an interpolable computed background-color. The
|
|
5620
|
+
intent color follows the state/interaction `ease`, not the presence
|
|
5621
|
+
curves. */
|
|
5520
5622
|
transition:
|
|
5521
|
-
opacity var(--duration-
|
|
5522
|
-
|
|
5523
|
-
|
|
5623
|
+
opacity var(--duration-fast) var(--ease-exit),
|
|
5624
|
+
translate var(--duration) var(--ease-exit),
|
|
5625
|
+
background-color var(--duration) ease;
|
|
5524
5626
|
}
|
|
5525
5627
|
|
|
5526
|
-
.status-bar
|
|
5527
|
-
opacity:
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5628
|
+
.status-bar.is-open {
|
|
5629
|
+
opacity: 1;
|
|
5630
|
+
translate: 0 0;
|
|
5631
|
+
/* Entry takes a little longer and decelerates, making the message legible
|
|
5632
|
+
before its motion settles. */
|
|
5633
|
+
transition:
|
|
5634
|
+
opacity var(--duration) var(--ease-enter),
|
|
5635
|
+
translate var(--duration-slow) var(--ease-enter),
|
|
5636
|
+
background-color var(--duration) ease;
|
|
5531
5637
|
}
|
|
5532
5638
|
@media print {
|
|
5533
5639
|
.status-bar {
|
|
@@ -6163,6 +6269,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6163
6269
|
|
|
6164
6270
|
counter-reset: actual-step;
|
|
6165
6271
|
display: flex;
|
|
6272
|
+
flex-direction: row;
|
|
6166
6273
|
inline-size: 100%;
|
|
6167
6274
|
margin: 0;
|
|
6168
6275
|
padding: 0;
|
|
@@ -6224,31 +6331,57 @@ a.avatar[aria-disabled="true"] {
|
|
|
6224
6331
|
content: none;
|
|
6225
6332
|
}
|
|
6226
6333
|
|
|
6227
|
-
|
|
6334
|
+
/* Three states must be readable without a check glyph: future stays neutral,
|
|
6335
|
+
complete is a filled marker, current is an outlined one. Filled reads as
|
|
6336
|
+
"done", outlined as "you are here" — the distinction survives a numbered
|
|
6337
|
+
stepper that never sets --step-complete-mark. */
|
|
6338
|
+
.steps > .complete {
|
|
6228
6339
|
--step-marker-bg: var(--state-selected);
|
|
6229
6340
|
--step-marker-border: var(--state-selected);
|
|
6230
6341
|
--step-marker-fg: var(--state-selected-fg);
|
|
6342
|
+
--step-line: var(--state-selected);
|
|
6231
6343
|
|
|
6232
6344
|
color: var(--text);
|
|
6233
6345
|
}
|
|
6234
6346
|
|
|
6235
|
-
/*
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6347
|
+
/* Declared after .complete at equal specificity, and it wins on every channel
|
|
6348
|
+
including the connector: the accented line means "already walked", so the
|
|
6349
|
+
segment leaving the current step must stay neutral. The line reaching the
|
|
6350
|
+
current step is owned by the previous step, which is complete. */
|
|
6351
|
+
.steps > [aria-current="step"] {
|
|
6352
|
+
--step-marker-bg: var(--surface);
|
|
6353
|
+
--step-marker-border: var(--state-selected);
|
|
6354
|
+
--step-marker-fg: var(--state-selected);
|
|
6355
|
+
--step-line: var(--border);
|
|
6356
|
+
|
|
6357
|
+
color: var(--text);
|
|
6239
6358
|
}
|
|
6240
6359
|
|
|
6241
|
-
|
|
6242
|
-
|
|
6360
|
+
/* Thicker border is the current affordance in every mode — structural, so it
|
|
6361
|
+
survives forced colors, and it never competes with the outline channel owned
|
|
6362
|
+
by focus. */
|
|
6363
|
+
.steps > [aria-current="step"]::before {
|
|
6364
|
+
border-width: calc(var(--border-width) * 2);
|
|
6243
6365
|
}
|
|
6244
6366
|
|
|
6245
6367
|
/* A finished step may replace its number with a mark (e.g. a check glyph):
|
|
6246
6368
|
--step-complete-mark accepts any content value and falls back to the
|
|
6247
|
-
counter, so existing numbered steppers are unchanged.
|
|
6248
|
-
|
|
6369
|
+
counter, so existing numbered steppers are unchanged. Excluded on the
|
|
6370
|
+
current step so "current wins" holds on the glyph too, not only on color. */
|
|
6371
|
+
.steps > .complete:not([aria-current="step"])::before {
|
|
6249
6372
|
content: var(--step-complete-mark, counter(actual-step));
|
|
6250
6373
|
}
|
|
6251
6374
|
|
|
6375
|
+
/* Forced colors drop the accent fill, which would leave complete and future
|
|
6376
|
+
markers identical — current keeps its thicker ring, complete needs a system
|
|
6377
|
+
color to stay filled. Same exclusion, for the same reason. */
|
|
6378
|
+
@media (forced-colors: active) {
|
|
6379
|
+
.steps > .complete:not([aria-current="step"])::before {
|
|
6380
|
+
background: Highlight;
|
|
6381
|
+
color: HighlightText;
|
|
6382
|
+
}
|
|
6383
|
+
}
|
|
6384
|
+
|
|
6252
6385
|
|
|
6253
6386
|
/* Navigation */
|
|
6254
6387
|
/*
|
|
@@ -6348,6 +6481,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6348
6481
|
|
|
6349
6482
|
.navbar {
|
|
6350
6483
|
display: flex;
|
|
6484
|
+
flex-direction: row;
|
|
6351
6485
|
flex-wrap: wrap;
|
|
6352
6486
|
align-items: center;
|
|
6353
6487
|
justify-content: space-between;
|
|
@@ -6375,6 +6509,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6375
6509
|
|
|
6376
6510
|
.navbar-nav {
|
|
6377
6511
|
display: flex;
|
|
6512
|
+
flex-direction: row;
|
|
6378
6513
|
flex-wrap: wrap;
|
|
6379
6514
|
align-items: center;
|
|
6380
6515
|
gap: var(--space-10);
|
|
@@ -6433,6 +6568,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6433
6568
|
*/
|
|
6434
6569
|
.breadcrumb {
|
|
6435
6570
|
display: flex;
|
|
6571
|
+
flex-direction: row;
|
|
6436
6572
|
flex-wrap: wrap;
|
|
6437
6573
|
align-items: center;
|
|
6438
6574
|
gap: var(--space-10);
|
|
@@ -6486,6 +6622,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6486
6622
|
*/
|
|
6487
6623
|
.pagination {
|
|
6488
6624
|
display: flex;
|
|
6625
|
+
flex-direction: row;
|
|
6489
6626
|
flex-wrap: wrap;
|
|
6490
6627
|
align-items: center;
|
|
6491
6628
|
gap: var(--space-10);
|
|
@@ -6534,6 +6671,7 @@ a.avatar[aria-disabled="true"] {
|
|
|
6534
6671
|
|
|
6535
6672
|
.tabs {
|
|
6536
6673
|
display: flex;
|
|
6674
|
+
flex-direction: row;
|
|
6537
6675
|
flex-wrap: wrap;
|
|
6538
6676
|
gap: var(--space-10);
|
|
6539
6677
|
margin: 0;
|
|
@@ -6645,6 +6783,34 @@ a.avatar[aria-disabled="true"] {
|
|
|
6645
6783
|
|
|
6646
6784
|
|
|
6647
6785
|
/* Data */
|
|
6786
|
+
/*
|
|
6787
|
+
* Data list — term/value pairs for the properties of a single object.
|
|
6788
|
+
*
|
|
6789
|
+
* Expects alternating <dt>/<dd> children: one term, one value per property.
|
|
6790
|
+
* A plain <dl> handles richer relationships (several terms or descriptions)
|
|
6791
|
+
* and stays untouched by this component.
|
|
6792
|
+
*
|
|
6793
|
+
* Why margin resets: neutralizes .prose list margins if .data-list appears
|
|
6794
|
+
* inside an authored rich-text scope; the grid owns row/column rhythm.
|
|
6795
|
+
*/
|
|
6796
|
+
.data-list {
|
|
6797
|
+
display: grid;
|
|
6798
|
+
grid-template-columns: max-content minmax(0, 1fr);
|
|
6799
|
+
align-items: baseline;
|
|
6800
|
+
gap: var(--space-20) var(--space-40);
|
|
6801
|
+
}
|
|
6802
|
+
|
|
6803
|
+
.data-list > dt {
|
|
6804
|
+
min-inline-size: 0;
|
|
6805
|
+
margin-block-start: 0;
|
|
6806
|
+
font-weight: var(--font-weight-strong);
|
|
6807
|
+
}
|
|
6808
|
+
|
|
6809
|
+
.data-list > dd {
|
|
6810
|
+
min-inline-size: 0;
|
|
6811
|
+
margin: 0;
|
|
6812
|
+
}
|
|
6813
|
+
|
|
6648
6814
|
/*
|
|
6649
6815
|
* Application list — repeated rows with optional leading and trailing regions.
|
|
6650
6816
|
* Content determines the number of lines; the component only owns the row
|
|
@@ -6803,10 +6969,18 @@ a.list-item:hover {
|
|
|
6803
6969
|
}
|
|
6804
6970
|
|
|
6805
6971
|
/*
|
|
6806
|
-
* Meter — native
|
|
6972
|
+
* Meter — native and segmented gauges for known-range values.
|
|
6807
6973
|
*
|
|
6808
6974
|
* Maps the three standard meter zones (optimum / suboptimum / even-less-good)
|
|
6809
6975
|
* to the shared success / warning / danger intent colors.
|
|
6976
|
+
*
|
|
6977
|
+
* Thickness is a dimension, not a density step: the bar always spans its
|
|
6978
|
+
* container and only gets thinner or thicker, so --bar-height is the API and
|
|
6979
|
+
* .sm/.lg are deliberately not supported.
|
|
6980
|
+
*
|
|
6981
|
+
* Public hooks:
|
|
6982
|
+
* --meter-value
|
|
6983
|
+
* --bar-height
|
|
6810
6984
|
*/
|
|
6811
6985
|
|
|
6812
6986
|
.meter {
|
|
@@ -6821,6 +6995,25 @@ a.list-item:hover {
|
|
|
6821
6995
|
background: var(--surface-subtle);
|
|
6822
6996
|
}
|
|
6823
6997
|
|
|
6998
|
+
/* A non-native meter is a weighted flex container. The element type keeps the
|
|
6999
|
+
native <meter> API and the composed segmented API distinct without another
|
|
7000
|
+
public variant class. */
|
|
7001
|
+
.meter:not(meter) {
|
|
7002
|
+
--intent: initial;
|
|
7003
|
+
|
|
7004
|
+
display: flex;
|
|
7005
|
+
}
|
|
7006
|
+
|
|
7007
|
+
.meter:not(meter) > * {
|
|
7008
|
+
flex: var(--meter-value, 1) 1 0;
|
|
7009
|
+
min-inline-size: 0;
|
|
7010
|
+
background: var(--intent);
|
|
7011
|
+
}
|
|
7012
|
+
|
|
7013
|
+
.meter:not(meter) > * + * {
|
|
7014
|
+
border-inline-start: var(--border-width) solid var(--surface);
|
|
7015
|
+
}
|
|
7016
|
+
|
|
6824
7017
|
.meter::-webkit-meter-bar {
|
|
6825
7018
|
-webkit-appearance: none;
|
|
6826
7019
|
block-size: var(--bar-height);
|
|
@@ -7099,6 +7292,22 @@ a.list-item:hover {
|
|
|
7099
7292
|
border: 0;
|
|
7100
7293
|
}
|
|
7101
7294
|
|
|
7295
|
+
/* Enlarge a small control's touch target on touch-primary devices without
|
|
7296
|
+
growing the visual. Opt-in — apply to genuinely small targets only. The
|
|
7297
|
+
::after exists only under (pointer: coarse), so on fine pointers the class
|
|
7298
|
+
is fully neutral. */
|
|
7299
|
+
@media (pointer: coarse) {
|
|
7300
|
+
.touch-target {
|
|
7301
|
+
position: relative;
|
|
7302
|
+
}
|
|
7303
|
+
|
|
7304
|
+
.touch-target::after {
|
|
7305
|
+
content: "";
|
|
7306
|
+
position: absolute;
|
|
7307
|
+
inset: calc(var(--space-20) * -1);
|
|
7308
|
+
}
|
|
7309
|
+
}
|
|
7310
|
+
|
|
7102
7311
|
.overflow-auto {
|
|
7103
7312
|
overflow: auto;
|
|
7104
7313
|
}
|