actual-css 0.4.2 → 0.6.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 +66 -3
- package/README.md +2 -2
- package/dist/actual.css +54 -14
- package/dist/actual.full.css +744 -185
- 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/browser-support.md +14 -14
- package/docs/design-notes/enhancement-contract.md +30 -13
- package/docs/design-notes/forced-colors.md +11 -7
- package/docs/design-notes/grid.md +4 -4
- package/docs/design-notes/naming.md +15 -9
- package/docs/design-notes/platform-alignment.md +9 -0
- package/docs/design-notes/references.md +4 -0
- package/docs/design-notes/spacing-units.md +286 -0
- package/docs/design-notes/steps.md +748 -0
- package/docs/design-notes/widget-primitives.md +32 -15
- package/docs/navigation.json +2 -0
- package/docs/pages/components/alert.md +14 -9
- package/docs/pages/components/app-navigation.md +2 -0
- package/docs/pages/components/aura.md +102 -6
- package/docs/pages/components/avatar.md +9 -6
- package/docs/pages/components/badge.md +27 -9
- package/docs/pages/components/button.md +25 -18
- package/docs/pages/components/card.md +27 -7
- package/docs/pages/components/chat.md +1 -1
- package/docs/pages/components/data-list.md +72 -0
- package/docs/pages/components/dialog.md +12 -7
- package/docs/pages/components/drawer.md +3 -1
- package/docs/pages/components/fab.md +14 -10
- package/docs/pages/components/indicator.md +6 -6
- package/docs/pages/components/list.md +11 -2
- package/docs/pages/components/meter.md +56 -1
- package/docs/pages/components/navbar.md +1 -1
- package/docs/pages/components/pagination.md +1 -1
- package/docs/pages/components/progress.md +10 -0
- package/docs/pages/components/rating.md +4 -4
- package/docs/pages/components/skeleton.md +3 -1
- package/docs/pages/components/spinner.md +1 -1
- package/docs/pages/components/steps.md +379 -47
- package/docs/pages/components/table.md +6 -5
- package/docs/pages/enhancements/flyout.md +14 -10
- package/docs/pages/enhancements/overview.md +2 -2
- package/docs/pages/enhancements/scrollspy.md +1 -1
- package/docs/pages/enhancements/status-bar.md +10 -1
- package/docs/pages/enhancements/tabs.md +1 -1
- package/docs/pages/examples/overview.md +4 -1
- package/docs/pages/forms/choice-cards.md +4 -4
- package/docs/pages/forms/combobox.md +87 -0
- package/docs/pages/forms/floating-field.md +5 -3
- package/docs/pages/forms/joined-controls.md +6 -4
- package/docs/pages/forms/labels.md +8 -5
- package/docs/pages/forms/overview.md +26 -19
- package/docs/pages/forms/password.md +3 -2
- package/docs/pages/forms/range.md +15 -2
- package/docs/pages/forms/states-and-sizes.md +7 -5
- package/docs/pages/forms/validation.md +15 -9
- package/docs/pages/foundations/philosophy.md +11 -1
- package/docs/pages/foundations/tokens.md +16 -9
- package/docs/pages/foundations/typography.md +11 -3
- package/docs/pages/guides/bootstrap.md +3 -3
- package/docs/pages/guides/introduction.md +2 -2
- package/docs/pages/guides/modular-import.md +21 -10
- package/docs/pages/guides/progressive-enhancement.md +75 -54
- package/docs/pages/guides/tailwind.md +2 -2
- package/docs/pages/layout/app-shell.md +4 -4
- package/docs/pages/layout/choosing.md +10 -6
- package/docs/pages/layout/grid.md +11 -10
- package/docs/pages/layout/scroll-snap.md +2 -0
- package/docs/pages/layout/sidebar-layout.md +2 -0
- package/docs/pages/layout/stack.md +10 -6
- package/docs/pages/layout/topbar.md +2 -0
- package/docs/pages/patterns/structured-lists.md +7 -7
- package/docs/pages/utilities/accessibility.md +19 -1
- package/docs/pages/utilities/flex.md +20 -13
- package/docs/pages/utilities/links.md +1 -1
- package/docs/pages/utilities/list.md +1 -1
- package/docs/pages/utilities/overflow.md +14 -7
- package/docs/pages/utilities/overview.md +22 -0
- package/docs/pages/utilities/shape.md +1 -1
- package/docs/pages/utilities/sizing-wrapping.md +10 -8
- package/docs/pages/utilities/spacing.md +26 -19
- package/docs/pages/utilities/text.md +1 -1
- package/llms.txt +27 -4
- package/package.json +3 -2
- package/scripts/reserved-classes.json +8 -1
- package/src/css/components/data-list.css +27 -0
- package/src/css/components/drawer.css +30 -11
- package/src/css/components/fab.css +44 -8
- package/src/css/components/flyout.css +17 -12
- package/src/css/components/index.css +1 -0
- package/src/css/components/list.css +3 -1
- package/src/css/components/meter.css +28 -1
- package/src/css/components/modal.css +28 -11
- package/src/css/components/progress.css +5 -0
- package/src/css/components/status-bar.css +31 -15
- package/src/css/components/steps.css +289 -55
- package/src/css/components/surface.css +5 -3
- 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 +24 -9
- package/src/css/core/variants.css +17 -4
- package/src/css/effects/aura.css +101 -11
- package/src/css/forms/custom-select.css +1 -1
- package/src/css/forms/floating-field.css +8 -6
- package/src/css/forms/form.css +4 -4
- package/src/css/layout/container-query.css +37 -13
- package/src/css/layout/grid.css +7 -7
- package/src/css/layout/index.css +1 -1
- package/src/css/typography/prose.css +2 -3
- package/src/css/utilities/base.css +16 -0
- package/src/js/password.js +1 -1
- 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
|
@@ -4,25 +4,32 @@ Semantic step helpers for gap, padding, and margin — the most common inline-st
|
|
|
4
4
|
|
|
5
5
|
## Class reference
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
| `.
|
|
12
|
-
| `.
|
|
13
|
-
| `.
|
|
14
|
-
| `.
|
|
15
|
-
| `.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
| `.
|
|
22
|
-
| `.
|
|
23
|
-
| `.
|
|
24
|
-
| `.
|
|
25
|
-
| `.
|
|
7
|
+
Base utilities:
|
|
8
|
+
|
|
9
|
+
| Class | Description |
|
|
10
|
+
| ----------- | -------------------------------------------------------- |
|
|
11
|
+
| `.gap-none` | `gap: 0` on the element itself. |
|
|
12
|
+
| `.py` | Block (vertical) padding at the current density step. |
|
|
13
|
+
| `.px` | Inline (horizontal) padding at the current density step. |
|
|
14
|
+
| `.mbs` | Block-start margin at the current density step. |
|
|
15
|
+
| `.mbe` | Block-end margin at the current density step. |
|
|
16
|
+
|
|
17
|
+
Extra utilities:
|
|
18
|
+
|
|
19
|
+
| Class | Description |
|
|
20
|
+
| --------------------------- | --------------------------------------------- |
|
|
21
|
+
| `.gap-sm` | `gap: var(--space-20)` — denser row rhythm. |
|
|
22
|
+
| `.gap-md` | `gap: var(--space-40)` — default row rhythm. |
|
|
23
|
+
| `.gap-lg` | `gap: var(--space-50)` — roomier row rhythm. |
|
|
24
|
+
| `.padding-context` | All-side padding at the current density step. |
|
|
25
|
+
| `.gap-context` | `gap: var(--gap)`. |
|
|
26
|
+
| `.row-gap-context` | `row-gap: var(--gap)`. |
|
|
27
|
+
| `.column-gap-context` | `column-gap: var(--gap)`. |
|
|
28
|
+
| `.margin-inline-auto` | Horizontally centers a block. |
|
|
29
|
+
| `.margin-inline-start-auto` | Pushes a block toward the inline end. |
|
|
30
|
+
| `.margin-inline-end-auto` | Pushes a block toward the inline start. |
|
|
31
|
+
| `.margin-block-start-auto` | Pushes content toward the block end. |
|
|
32
|
+
| `.margin-block-end-auto` | Pushes content toward the block start. |
|
|
26
33
|
|
|
27
34
|
Spacing helpers follow the density context. The default step is
|
|
28
35
|
`--space-40` (1rem); the `.sm` context tightens it to `--space-20` (0.5rem)
|
|
@@ -5,7 +5,7 @@ Lightweight helpers for muted or secondary text without a full color scale.
|
|
|
5
5
|
## Class reference
|
|
6
6
|
|
|
7
7
|
| Class | Kind | Description |
|
|
8
|
-
|
|
8
|
+
| --------------- | ------- | -------------------------------------------------------- |
|
|
9
9
|
| `.muted` | Utility | Secondary text color. |
|
|
10
10
|
| `.text-start` | Utility | Logical start-aligned text; sets `--text-align`. |
|
|
11
11
|
| `.text-center` | Utility | Centered text; sets `--text-align`. |
|
package/llms.txt
CHANGED
|
@@ -16,19 +16,37 @@ Actual CSS uses a small public grammar: `.component [intent] [variant] [size] [m
|
|
|
16
16
|
- `actual-css/full` — the complete framework: core plus every component, form, layout, typography, effect, and utility family.
|
|
17
17
|
- `actual-css/js` — the enhancement loader only; it discovers `data-enhance` markers and loads enhancers on demand.
|
|
18
18
|
- `actual-css/js/full` — the complete runtime with all built-in enhancers pre-registered.
|
|
19
|
-
- `actual-css/reserved-classes.json` — machine-readable list of
|
|
19
|
+
- `actual-css/reserved-classes.json` — machine-readable list of the framework-owned class namespace. Use it to check whether a class belongs to Actual CSS and to validate claimed framework classes; application-specific classes are expected to exist outside this manifest.
|
|
20
20
|
- Individual families and modules are importable separately (`actual-css/css/components`, `actual-css/css/layout/grid`, `actual-css/js/dialog`, …); see [README](README.md) and [Modular imports](docs/pages/guides/modular-import.md).
|
|
21
21
|
|
|
22
|
+
Forms are the one family with two aggregate entrypoints:
|
|
23
|
+
`actual-css/css/forms` is the native-control baseline; use
|
|
24
|
+
`actual-css/css/forms/all` for the complete forms family.
|
|
25
|
+
|
|
22
26
|
The composition guides in [README](README.md) and [Progressive Enhancements](docs/pages/enhancements/overview.md)
|
|
23
27
|
show supported CSS modules and individual enhancer imports without duplicating
|
|
24
28
|
the full export list here.
|
|
25
29
|
|
|
26
30
|
Presentation (`class`) and behavior (`data-enhance`) are separate layers.
|
|
27
|
-
Behaviour primitives
|
|
28
|
-
`
|
|
29
|
-
|
|
31
|
+
Behaviour primitives are independently importable for building custom widgets,
|
|
32
|
+
including `enhance`, `surface`, `floating`, `focus-group`, `keys`, `input`,
|
|
33
|
+
`command`, `menu`, `focus`, `escape`, and `events`. See
|
|
34
|
+
[enhancement contract](docs/design-notes/enhancement-contract.md) and
|
|
30
35
|
[widget primitives](docs/design-notes/widget-primitives.md).
|
|
31
36
|
|
|
37
|
+
## Choosing a page shell
|
|
38
|
+
|
|
39
|
+
Before choosing a content layout, choose the page shell:
|
|
40
|
+
|
|
41
|
+
- Normal scrolling page, marketing/editorial site, or ordinary application page
|
|
42
|
+
→ semantic landmarks; optionally `.app-shell` and `.navbar`.
|
|
43
|
+
- Persistent topbar + independently scrolling main + adaptive bottom/side
|
|
44
|
+
primary navigation → `.app-layout`.
|
|
45
|
+
|
|
46
|
+
Do not choose `.app-layout` merely because the product is an application. Its
|
|
47
|
+
viewport-sized shell, internal scrolling, and adaptive navigation are one
|
|
48
|
+
combined contract. See [layout choices](docs/pages/layout/choosing.md).
|
|
49
|
+
|
|
32
50
|
## Choosing a layout primitive
|
|
33
51
|
|
|
34
52
|
Pick from the relationship between children, not the number of children in one mockup:
|
|
@@ -41,6 +59,11 @@ Pick from the relationship between children, not the number of children in one m
|
|
|
41
59
|
- Explicit region placement on a shared 12-column canvas → `.column-layout`
|
|
42
60
|
- Vertical flow → `.stack`; wrapping inline items → `.cluster`
|
|
43
61
|
|
|
62
|
+
`.container-query` establishes the framework's shared
|
|
63
|
+
`actual-container / inline-size` container for components that explicitly
|
|
64
|
+
respond to allocated space; it is not a general prerequisite for responsive
|
|
65
|
+
layouts.
|
|
66
|
+
|
|
44
67
|
Use `--grid-columns` on `.grid` for exact track templates that do not match a
|
|
45
68
|
built-in layout contract: arbitrary structural counts (seven calendar days),
|
|
46
69
|
asymmetric fractional tracks, or mixed intrinsic/flexible tracks. See
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "actual-css",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Plain CSS component framework with semantic classes, universal variants, small tokens, theme hooks, and progressive enhancements.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "bun@1.4.0",
|
|
@@ -115,6 +115,7 @@
|
|
|
115
115
|
"build:docs": "bun run build:themes && bun scripts/build-docs.js",
|
|
116
116
|
"watch:docs": "bun run build:themes && bun scripts/build-docs.js --watch",
|
|
117
117
|
"check:docs": "bun scripts/check-docs.js",
|
|
118
|
+
"format:docs": "bun scripts/format-doc-tables.js",
|
|
118
119
|
"check:doc-classes": "bun scripts/check-doc-classes.js",
|
|
119
120
|
"check:compat": "bun scripts/check-compat.js",
|
|
120
121
|
"check:css-api": "bun scripts/check-css-api.js",
|
|
@@ -136,7 +137,7 @@
|
|
|
136
137
|
"check:sync": "bun scripts/check-sync.js",
|
|
137
138
|
"test": "bun test",
|
|
138
139
|
"test:changed": "bun test --changed=master",
|
|
139
|
-
"build:all": "bun run lint && bun run build:dist && bun run build:js && bun run build:docs && bun run check:docs && bun run check:doc-classes && bun run check:compat && bun run check:css-api && bun run check:color-space && bun run check:architecture && bun run check:enhance && bun run generate:reserved && bun run check:reserved && bun run check:sync && bun run check:links && bun run check:templates && bun run test && bun run build:size",
|
|
140
|
+
"build:all": "bun run lint && bun run build:dist && bun run build:js && bun run format:docs && bun run build:docs && bun run check:docs && bun run check:doc-classes && bun run check:compat && bun run check:css-api && bun run check:color-space && bun run check:architecture && bun run check:enhance && bun run generate:reserved && bun run check:reserved && bun run check:sync && bun run check:links && bun run check:templates && bun run test && bun run build:size",
|
|
140
141
|
"prepublishOnly": "bun run build:all"
|
|
141
142
|
},
|
|
142
143
|
"devDependencies": {
|
|
@@ -75,10 +75,10 @@
|
|
|
75
75
|
"column-start-8",
|
|
76
76
|
"column-start-9",
|
|
77
77
|
"compact",
|
|
78
|
-
"complete",
|
|
79
78
|
"container-query",
|
|
80
79
|
"cursor-pointer",
|
|
81
80
|
"danger",
|
|
81
|
+
"data-list",
|
|
82
82
|
"dialog-close",
|
|
83
83
|
"dialog-confirmation",
|
|
84
84
|
"dialog-icon",
|
|
@@ -134,6 +134,7 @@
|
|
|
134
134
|
"inline-size-full",
|
|
135
135
|
"input",
|
|
136
136
|
"input-icon",
|
|
137
|
+
"intent-color",
|
|
137
138
|
"inverted",
|
|
138
139
|
"is-open",
|
|
139
140
|
"is-sheet",
|
|
@@ -241,11 +242,16 @@
|
|
|
241
242
|
"stack",
|
|
242
243
|
"start",
|
|
243
244
|
"status-bar",
|
|
245
|
+
"step-complete",
|
|
246
|
+
"step-label",
|
|
244
247
|
"steps",
|
|
248
|
+
"steps-horizontal",
|
|
249
|
+
"steps-vertical",
|
|
245
250
|
"sticky",
|
|
246
251
|
"stretch",
|
|
247
252
|
"subtle",
|
|
248
253
|
"success",
|
|
254
|
+
"surface",
|
|
249
255
|
"surface-backdrop",
|
|
250
256
|
"switch",
|
|
251
257
|
"switcher",
|
|
@@ -269,6 +275,7 @@
|
|
|
269
275
|
"textarea",
|
|
270
276
|
"tooltip",
|
|
271
277
|
"topbar",
|
|
278
|
+
"touch-target",
|
|
272
279
|
"truncate",
|
|
273
280
|
"user-select-none",
|
|
274
281
|
"visibility-hidden",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Data list — term/value pairs for the properties of a single object.
|
|
3
|
+
*
|
|
4
|
+
* Expects alternating <dt>/<dd> children: one term, one value per property.
|
|
5
|
+
* A plain <dl> handles richer relationships (several terms or descriptions)
|
|
6
|
+
* and stays untouched by this component.
|
|
7
|
+
*
|
|
8
|
+
* Why margin resets: neutralizes .prose list margins if .data-list appears
|
|
9
|
+
* inside an authored rich-text scope; the grid owns row/column rhythm.
|
|
10
|
+
*/
|
|
11
|
+
.data-list {
|
|
12
|
+
display: grid;
|
|
13
|
+
grid-template-columns: max-content minmax(0, 1fr);
|
|
14
|
+
align-items: baseline;
|
|
15
|
+
gap: var(--space-20) var(--space-40);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.data-list > dt {
|
|
19
|
+
min-inline-size: 0;
|
|
20
|
+
margin-block-start: 0;
|
|
21
|
+
font-weight: var(--font-weight-strong);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.data-list > dd {
|
|
25
|
+
min-inline-size: 0;
|
|
26
|
+
margin: 0;
|
|
27
|
+
}
|
|
@@ -13,11 +13,16 @@
|
|
|
13
13
|
*
|
|
14
14
|
* Internal:
|
|
15
15
|
* --drawer-closed-translate (side/RTL positioning state)
|
|
16
|
+
* --drawer-motion-duration (shared by panel and ::backdrop so exit duration
|
|
17
|
+
* changes in one place; entry state redefines it longer)
|
|
16
18
|
*/
|
|
17
19
|
dialog.drawer {
|
|
18
20
|
--drawer-size: 20rem;
|
|
19
21
|
--drawer-pad: var(--space-40);
|
|
20
22
|
--drawer-closed-translate: -100%;
|
|
23
|
+
/* Exit is shorter than entry so the panel clears quickly; the scrim reads
|
|
24
|
+
the same variable through inheritance and never lags the panel. */
|
|
25
|
+
--drawer-motion-duration: var(--duration);
|
|
21
26
|
|
|
22
27
|
/* Keep the surface anchored to the viewport in the top layer. This also
|
|
23
28
|
provides the containing block for the absolutely positioned close button.
|
|
@@ -41,16 +46,20 @@ dialog.drawer {
|
|
|
41
46
|
opacity: 0;
|
|
42
47
|
transform: translateX(var(--drawer-closed-translate));
|
|
43
48
|
transition:
|
|
44
|
-
opacity var(--duration-
|
|
45
|
-
transform var(--duration-
|
|
49
|
+
opacity var(--drawer-motion-duration) var(--ease-exit),
|
|
50
|
+
transform var(--drawer-motion-duration) var(--ease-exit);
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
dialog.drawer[open] {
|
|
54
|
+
--drawer-motion-duration: var(--duration-slow);
|
|
49
55
|
display: grid;
|
|
50
56
|
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
51
57
|
gap: var(--space-40);
|
|
52
58
|
opacity: 1;
|
|
53
59
|
transform: translateX(0);
|
|
60
|
+
transition:
|
|
61
|
+
opacity var(--drawer-motion-duration) var(--ease-enter),
|
|
62
|
+
transform var(--drawer-motion-duration) var(--ease-enter);
|
|
54
63
|
}
|
|
55
64
|
|
|
56
65
|
/* Backdrop color sourced from components/surface.css so it matches .modal
|
|
@@ -58,7 +67,9 @@ dialog.drawer[open] {
|
|
|
58
67
|
dialog.drawer::backdrop {
|
|
59
68
|
background: var(--backdrop-fill);
|
|
60
69
|
opacity: 0;
|
|
61
|
-
|
|
70
|
+
/* Scrim curve stays neutral `ease`; only the panel's character curves
|
|
71
|
+
apply. Duration follows --drawer-motion-duration through inheritance. */
|
|
72
|
+
transition: opacity var(--drawer-motion-duration) ease;
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
dialog.drawer[data-side="end"] {
|
|
@@ -94,17 +105,25 @@ dialog.drawer nav {
|
|
|
94
105
|
@supports (transition-behavior: allow-discrete) {
|
|
95
106
|
dialog.drawer {
|
|
96
107
|
transition:
|
|
97
|
-
opacity var(--duration-
|
|
98
|
-
transform var(--duration-
|
|
99
|
-
overlay var(--duration
|
|
100
|
-
display var(--duration
|
|
108
|
+
opacity var(--drawer-motion-duration) var(--ease-exit),
|
|
109
|
+
transform var(--drawer-motion-duration) var(--ease-exit),
|
|
110
|
+
overlay var(--drawer-motion-duration) allow-discrete,
|
|
111
|
+
display var(--drawer-motion-duration) allow-discrete;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
dialog.drawer[open] {
|
|
115
|
+
transition:
|
|
116
|
+
opacity var(--drawer-motion-duration) var(--ease-enter),
|
|
117
|
+
transform var(--drawer-motion-duration) var(--ease-enter),
|
|
118
|
+
overlay var(--drawer-motion-duration) allow-discrete,
|
|
119
|
+
display var(--drawer-motion-duration) allow-discrete;
|
|
101
120
|
}
|
|
102
121
|
|
|
103
122
|
dialog.drawer::backdrop {
|
|
104
123
|
transition:
|
|
105
|
-
opacity var(--duration
|
|
106
|
-
overlay var(--duration
|
|
107
|
-
display var(--duration
|
|
124
|
+
opacity var(--drawer-motion-duration) ease,
|
|
125
|
+
overlay var(--drawer-motion-duration) allow-discrete,
|
|
126
|
+
display var(--drawer-motion-duration) allow-discrete;
|
|
108
127
|
}
|
|
109
128
|
}
|
|
110
129
|
|
|
@@ -140,7 +159,7 @@ dialog.drawer nav {
|
|
|
140
159
|
|
|
141
160
|
@media (prefers-reduced-motion: no-preference) {
|
|
142
161
|
dialog.drawer.is-static {
|
|
143
|
-
animation: actual-dialog-static var(--duration-slow)
|
|
162
|
+
animation: actual-dialog-static var(--duration-slow) ease;
|
|
144
163
|
}
|
|
145
164
|
}
|
|
146
165
|
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Fixed floating action placement and a native-details speed dial.
|
|
3
|
-
* Button owns the
|
|
3
|
+
* Button owns the trigger's size, shape, and intent; FAB owns placement and
|
|
4
|
+
* the speed dial's structural open/close markers (--icon-plus / --icon-close).
|
|
4
5
|
*
|
|
5
6
|
* Public hooks:
|
|
6
7
|
* --fab-offset
|
|
7
8
|
* --fab-gap
|
|
9
|
+
* --fab-icon-size
|
|
8
10
|
*/
|
|
9
11
|
.fab {
|
|
10
12
|
--fab-offset: var(--space-40);
|
|
11
13
|
--fab-gap: var(--space-20);
|
|
14
|
+
--fab-icon-size: 1.5rem;
|
|
12
15
|
|
|
13
16
|
position: fixed;
|
|
14
17
|
z-index: var(--z-menu);
|
|
@@ -17,6 +20,9 @@
|
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
.fab > summary {
|
|
23
|
+
/* Centers the toggle markers: the summary is the markers' positioned
|
|
24
|
+
context, not just the app-button class. */
|
|
25
|
+
position: relative;
|
|
20
26
|
list-style: none;
|
|
21
27
|
cursor: pointer;
|
|
22
28
|
}
|
|
@@ -25,11 +31,35 @@
|
|
|
25
31
|
display: none;
|
|
26
32
|
}
|
|
27
33
|
|
|
28
|
-
/*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
/* The speed dial trigger is an icon-only toggle. FAB owns both structural
|
|
35
|
+
markers: masked pseudo-elements swap the shared plus (closed) and close
|
|
36
|
+
(open) glyphs at the same size, so the two states never drift apart. */
|
|
37
|
+
.fab > summary::before,
|
|
38
|
+
.fab > summary::after {
|
|
39
|
+
content: "";
|
|
40
|
+
position: absolute;
|
|
41
|
+
inset: 0;
|
|
42
|
+
margin: auto;
|
|
43
|
+
inline-size: var(--fab-icon-size);
|
|
44
|
+
block-size: var(--fab-icon-size);
|
|
45
|
+
background: currentColor;
|
|
46
|
+
opacity: 0;
|
|
47
|
+
transform: scale(0.8);
|
|
48
|
+
transition:
|
|
49
|
+
opacity var(--duration),
|
|
50
|
+
transform var(--duration);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.fab > summary::before {
|
|
54
|
+
-webkit-mask: var(--icon-plus) center / contain no-repeat;
|
|
55
|
+
mask: var(--icon-plus) center / contain no-repeat;
|
|
56
|
+
opacity: 1;
|
|
57
|
+
transform: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.fab > summary::after {
|
|
61
|
+
-webkit-mask: var(--icon-close) center / contain no-repeat;
|
|
62
|
+
mask: var(--icon-close) center / contain no-repeat;
|
|
33
63
|
}
|
|
34
64
|
|
|
35
65
|
.fab-actions {
|
|
@@ -87,8 +117,14 @@
|
|
|
87
117
|
transition-delay: 0s;
|
|
88
118
|
}
|
|
89
119
|
|
|
90
|
-
.fab[open] > summary
|
|
91
|
-
|
|
120
|
+
.fab[open] > summary::before {
|
|
121
|
+
opacity: 0;
|
|
122
|
+
transform: scale(0.8);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.fab[open] > summary::after {
|
|
126
|
+
opacity: 1;
|
|
127
|
+
transform: none;
|
|
92
128
|
}
|
|
93
129
|
|
|
94
130
|
@media print {
|
|
@@ -73,11 +73,10 @@
|
|
|
73
73
|
box-shadow: var(--shadow-popout);
|
|
74
74
|
list-style: none;
|
|
75
75
|
opacity: 1;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
translate var(--duration-fast) var(--ease);
|
|
76
|
+
/* Anchored flyouts fade in and out; scaling around the center would detach
|
|
77
|
+
the anchored edge from its trigger on wide panels. The sheet presentation
|
|
78
|
+
below adds its own translate motion. */
|
|
79
|
+
transition: opacity var(--duration-fast) ease;
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
.flyout.is-open:not(.is-sheet) {
|
|
@@ -87,7 +86,6 @@
|
|
|
87
86
|
@starting-style {
|
|
88
87
|
.flyout.is-open {
|
|
89
88
|
opacity: 0;
|
|
90
|
-
scale: 0.98;
|
|
91
89
|
}
|
|
92
90
|
}
|
|
93
91
|
|
|
@@ -109,22 +107,24 @@
|
|
|
109
107
|
max(var(--space-30), env(safe-area-inset-bottom));
|
|
110
108
|
border-end-start-radius: 0;
|
|
111
109
|
border-end-end-radius: 0;
|
|
110
|
+
/* Sheet motion is a directional slide from the viewport edge; it replaces
|
|
111
|
+
the base fade-only recipe. */
|
|
112
|
+
transition:
|
|
113
|
+
opacity var(--duration-fast) ease,
|
|
114
|
+
translate var(--duration-fast) ease;
|
|
112
115
|
}
|
|
113
116
|
|
|
114
117
|
.flyout[hidden] {
|
|
115
118
|
display: none;
|
|
116
119
|
opacity: 0;
|
|
117
|
-
scale: 0.98;
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
.flyout.is-sheet[hidden] {
|
|
121
|
-
scale: 1;
|
|
122
123
|
translate: 0 var(--space-30);
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
@starting-style {
|
|
126
127
|
.flyout.is-sheet.is-open {
|
|
127
|
-
scale: 1;
|
|
128
128
|
translate: 0 var(--space-30);
|
|
129
129
|
}
|
|
130
130
|
}
|
|
@@ -132,9 +132,14 @@
|
|
|
132
132
|
@supports (transition-behavior: allow-discrete) {
|
|
133
133
|
.flyout {
|
|
134
134
|
transition:
|
|
135
|
-
opacity var(--duration-fast)
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
opacity var(--duration-fast) ease,
|
|
136
|
+
display var(--duration-fast) allow-discrete;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.flyout.is-sheet {
|
|
140
|
+
transition:
|
|
141
|
+
opacity var(--duration-fast) ease,
|
|
142
|
+
translate var(--duration-fast) ease,
|
|
138
143
|
display var(--duration-fast) allow-discrete;
|
|
139
144
|
}
|
|
140
145
|
}
|
|
@@ -33,7 +33,9 @@
|
|
|
33
33
|
.list > li > .list-item {
|
|
34
34
|
display: grid;
|
|
35
35
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
36
|
-
align
|
|
36
|
+
/* Regions align to the first line, so leading, title, and trailing controls
|
|
37
|
+
share one horizontal line while supporting text wraps beneath. */
|
|
38
|
+
align-items: start;
|
|
37
39
|
gap: var(--list-item-gap);
|
|
38
40
|
min-block-size: var(--list-item-min-size);
|
|
39
41
|
padding-block: var(--list-item-pad-block);
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Meter — native
|
|
2
|
+
* Meter — native and segmented gauges for known-range values.
|
|
3
3
|
*
|
|
4
4
|
* Maps the three standard meter zones (optimum / suboptimum / even-less-good)
|
|
5
5
|
* to the shared success / warning / danger intent colors.
|
|
6
|
+
*
|
|
7
|
+
* Thickness is a dimension, not a density step: the bar always spans its
|
|
8
|
+
* container and only gets thinner or thicker, so --bar-height is the API and
|
|
9
|
+
* .sm/.lg are deliberately not supported.
|
|
10
|
+
*
|
|
11
|
+
* Public hooks:
|
|
12
|
+
* --meter-value
|
|
13
|
+
* --bar-height
|
|
6
14
|
*/
|
|
7
15
|
|
|
8
16
|
.meter {
|
|
@@ -17,6 +25,25 @@
|
|
|
17
25
|
background: var(--surface-subtle);
|
|
18
26
|
}
|
|
19
27
|
|
|
28
|
+
/* A non-native meter is a weighted flex container. The element type keeps the
|
|
29
|
+
native <meter> API and the composed segmented API distinct without another
|
|
30
|
+
public variant class. */
|
|
31
|
+
.meter:not(meter) {
|
|
32
|
+
--intent: initial;
|
|
33
|
+
|
|
34
|
+
display: flex;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.meter:not(meter) > * {
|
|
38
|
+
flex: var(--meter-value, 1) 1 0;
|
|
39
|
+
min-inline-size: 0;
|
|
40
|
+
background: var(--intent);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.meter:not(meter) > * + * {
|
|
44
|
+
border-inline-start: var(--border-width) solid var(--surface);
|
|
45
|
+
}
|
|
46
|
+
|
|
20
47
|
.meter::-webkit-meter-bar {
|
|
21
48
|
-webkit-appearance: none;
|
|
22
49
|
block-size: var(--bar-height);
|
|
@@ -39,12 +39,14 @@ dialog.modal {
|
|
|
39
39
|
* Keep the open dialog root untransformed. Fixed overlays mounted inside a
|
|
40
40
|
* modal dialog use viewport coordinates; transform/translate/scale on this
|
|
41
41
|
* element would make them position against the dialog instead. The closed
|
|
42
|
-
* state can still carry a small transform for enter/exit motion.
|
|
42
|
+
* state can still carry a small transform for enter/exit motion. The lift
|
|
43
|
+
* is a pure vertical offset: scaling a wide panel around its center drags
|
|
44
|
+
* both edges, which reads as horizontal movement.
|
|
43
45
|
*/
|
|
44
|
-
transform: translateY(0.35rem)
|
|
46
|
+
transform: translateY(0.35rem);
|
|
45
47
|
transition:
|
|
46
|
-
opacity var(--duration),
|
|
47
|
-
transform var(--duration);
|
|
48
|
+
opacity var(--duration) var(--ease-exit),
|
|
49
|
+
transform var(--duration) var(--ease-exit);
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
dialog.modal > form,
|
|
@@ -163,33 +165,46 @@ dialog.modal.dialog-confirmation > form > footer {
|
|
|
163
165
|
dialog.modal[open] {
|
|
164
166
|
opacity: 1;
|
|
165
167
|
transform: none;
|
|
168
|
+
transition:
|
|
169
|
+
opacity var(--duration) var(--ease-enter),
|
|
170
|
+
transform var(--duration) var(--ease-enter);
|
|
166
171
|
}
|
|
167
172
|
|
|
168
173
|
@starting-style {
|
|
169
174
|
dialog.modal[open] {
|
|
170
175
|
opacity: 0;
|
|
171
|
-
transform: translateY(0.35rem)
|
|
176
|
+
transform: translateY(0.35rem);
|
|
172
177
|
}
|
|
173
178
|
}
|
|
174
179
|
|
|
175
180
|
dialog.modal::backdrop {
|
|
176
181
|
background: var(--backdrop-fill);
|
|
177
182
|
opacity: 0;
|
|
178
|
-
|
|
183
|
+
/* Scrim curve stays neutral `ease`; only the panel carries the character
|
|
184
|
+
curves. */
|
|
185
|
+
transition: opacity var(--duration) ease;
|
|
179
186
|
}
|
|
180
187
|
|
|
181
188
|
@supports (transition-behavior: allow-discrete) {
|
|
182
189
|
dialog.modal {
|
|
183
190
|
transition:
|
|
184
|
-
opacity var(--duration),
|
|
185
|
-
transform var(--duration),
|
|
191
|
+
opacity var(--duration) var(--ease-exit),
|
|
192
|
+
transform var(--duration) var(--ease-exit),
|
|
193
|
+
overlay var(--duration) allow-discrete,
|
|
194
|
+
display var(--duration) allow-discrete;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
dialog.modal[open] {
|
|
198
|
+
transition:
|
|
199
|
+
opacity var(--duration) var(--ease-enter),
|
|
200
|
+
transform var(--duration) var(--ease-enter),
|
|
186
201
|
overlay var(--duration) allow-discrete,
|
|
187
202
|
display var(--duration) allow-discrete;
|
|
188
203
|
}
|
|
189
204
|
|
|
190
205
|
dialog.modal::backdrop {
|
|
191
206
|
transition:
|
|
192
|
-
opacity var(--duration),
|
|
207
|
+
opacity var(--duration) ease,
|
|
193
208
|
overlay var(--duration) allow-discrete,
|
|
194
209
|
display var(--duration) allow-discrete;
|
|
195
210
|
}
|
|
@@ -214,13 +229,15 @@ html.has-modal-open.had-scrollbar {
|
|
|
214
229
|
}
|
|
215
230
|
|
|
216
231
|
@media (prefers-reduced-motion: no-preference) {
|
|
232
|
+
/* Wrong-close feedback and view-transition transport are motion quirks, not
|
|
233
|
+
presence enter/exit, so they stay on the plain CSS default easing. */
|
|
217
234
|
dialog.modal.is-static {
|
|
218
|
-
animation: actual-dialog-static var(--duration-slow)
|
|
235
|
+
animation: actual-dialog-static var(--duration-slow) ease;
|
|
219
236
|
}
|
|
220
237
|
|
|
221
238
|
::view-transition-group(actual-dialog) {
|
|
222
239
|
animation-duration: var(--duration);
|
|
223
|
-
animation-timing-function:
|
|
240
|
+
animation-timing-function: ease;
|
|
224
241
|
}
|
|
225
242
|
}
|
|
226
243
|
|
|
@@ -4,9 +4,14 @@
|
|
|
4
4
|
* Consumes the shared --intent/--primary for the value bar and --bar-height
|
|
5
5
|
* for thickness. Indeterminate state animates a shimmer using --duration-shimmer.
|
|
6
6
|
*
|
|
7
|
+
* Thickness is a dimension, not a density step: the bar always spans its
|
|
8
|
+
* container and only gets thinner or thicker, so --bar-height is the API and
|
|
9
|
+
* .sm/.lg are deliberately not supported.
|
|
10
|
+
*
|
|
7
11
|
* Public hooks:
|
|
8
12
|
* --progress-track
|
|
9
13
|
* --progress-value
|
|
14
|
+
* --bar-height
|
|
10
15
|
*/
|
|
11
16
|
/* Intent boundary — inherited intents do not tint this component.
|
|
12
17
|
Local intent classes still win because :where() has zero specificity. */
|