actual-css 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +109 -3
- package/README.md +35 -30
- package/dist/actual.css +66 -4958
- package/dist/actual.full.css +7548 -0
- package/dist/actual.full.js +1 -0
- package/dist/actual.full.min.css +1 -0
- package/dist/actual.js +1 -1
- package/dist/actual.min.css +1 -1
- package/docs/design-notes/app-ui.md +33 -0
- package/docs/design-notes/cascade-layer.md +34 -13
- package/docs/design-notes/column-layout.md +677 -0
- package/docs/design-notes/enhancement-contract.md +25 -0
- package/docs/design-notes/forced-colors.md +3 -0
- package/docs/design-notes/grid.md +785 -0
- package/docs/design-notes/naming.md +15 -0
- package/docs/design-notes/references.md +1 -1
- package/docs/design-notes/widget-primitives.md +1 -0
- package/docs/navigation.json +12 -2
- package/docs/pages/components/alert.md +21 -14
- package/docs/pages/components/app-navigation.md +34 -0
- package/docs/pages/components/aura.md +1 -1
- package/docs/pages/components/avatar.md +16 -6
- package/docs/pages/components/badge.md +9 -7
- package/docs/pages/components/button.md +46 -16
- package/docs/pages/components/card.md +17 -9
- package/docs/pages/components/chat.md +8 -8
- package/docs/pages/components/dialog.md +7 -7
- package/docs/pages/components/drawer.md +3 -3
- package/docs/pages/components/fab.md +9 -7
- package/docs/pages/components/indicator.md +52 -0
- package/docs/pages/components/list.md +62 -0
- package/docs/pages/components/navbar.md +15 -8
- package/docs/pages/components/pagination.md +4 -3
- package/docs/pages/components/rating.md +68 -0
- package/docs/pages/components/skeleton.md +4 -4
- package/docs/pages/components/spinner.md +5 -5
- package/docs/pages/components/steps.md +57 -0
- package/docs/pages/components/table.md +30 -5
- package/docs/pages/enhancements/flyout.md +15 -15
- package/docs/pages/enhancements/overview.md +1 -1
- package/docs/pages/enhancements/scrollspy.md +6 -6
- package/docs/pages/enhancements/status-bar.md +5 -1
- package/docs/pages/enhancements/tabs.md +7 -8
- package/docs/pages/enhancements/tooltip.md +1 -1
- package/docs/pages/examples/overview.md +47 -22
- package/docs/pages/forms/choice-cards.md +11 -6
- package/docs/pages/forms/controls.md +1 -1
- package/docs/pages/forms/detached-actions.md +1 -1
- package/docs/pages/forms/floating-field.md +10 -5
- package/docs/pages/forms/form-actions.md +1 -1
- package/docs/pages/forms/input-policy.md +1 -1
- package/docs/pages/forms/joined-controls.md +4 -4
- package/docs/pages/forms/labels.md +6 -6
- package/docs/pages/forms/otp.md +33 -1
- package/docs/pages/forms/overview.md +19 -19
- package/docs/pages/forms/password.md +1 -1
- package/docs/pages/forms/range.md +1 -1
- package/docs/pages/forms/states-and-sizes.md +44 -48
- package/docs/pages/forms/sticky-actions.md +3 -3
- package/docs/pages/forms/switch.md +110 -2
- package/docs/pages/forms/validation.md +9 -9
- package/docs/pages/foundations/philosophy.md +1 -1
- package/docs/pages/foundations/theming.md +17 -2
- package/docs/pages/foundations/tokens.md +22 -10
- package/docs/pages/foundations/typography.md +50 -20
- package/docs/pages/guides/bootstrap.md +11 -11
- package/docs/pages/guides/integrating-actual-css.md +192 -0
- package/docs/pages/guides/introduction.md +23 -26
- package/docs/pages/guides/modular-import.md +173 -0
- package/docs/pages/guides/progressive-enhancement.md +81 -78
- package/docs/pages/guides/tailwind.md +6 -8
- package/docs/pages/layout/app-layout.md +57 -0
- package/docs/pages/layout/app-shell.md +28 -7
- package/docs/pages/layout/center.md +12 -1
- package/docs/pages/layout/choosing.md +54 -0
- package/docs/pages/layout/column-layout.md +206 -0
- package/docs/pages/layout/frame.md +6 -1
- package/docs/pages/layout/grid.md +133 -102
- package/docs/pages/layout/media.md +1 -1
- package/docs/pages/layout/overview.md +15 -2
- package/docs/pages/layout/scroll-snap.md +2 -2
- package/docs/pages/layout/scroll-target.md +45 -0
- package/docs/pages/layout/sidebar-layout.md +38 -18
- package/docs/pages/layout/stack.md +70 -1
- package/docs/pages/layout/switcher.md +10 -26
- package/docs/pages/layout/topbar.md +2 -2
- package/docs/pages/patterns/actions.md +1 -1
- package/docs/pages/patterns/code-block.md +1 -1
- package/docs/pages/patterns/exclusive-accordion.md +1 -1
- package/docs/pages/patterns/hierarchical-nav.md +1 -1
- package/docs/pages/patterns/icon-input.md +1 -1
- package/docs/pages/patterns/icon-slot.md +61 -0
- package/docs/pages/patterns/intent-nesting.md +1 -1
- package/docs/pages/patterns/navigation-list.md +1 -1
- package/docs/pages/patterns/overview.md +1 -1
- package/docs/pages/patterns/structured-lists.md +38 -40
- package/docs/pages/utilities/accessibility.md +3 -3
- package/docs/pages/utilities/flex.md +15 -15
- package/docs/pages/utilities/links.md +4 -4
- package/docs/pages/utilities/list.md +8 -8
- package/docs/pages/utilities/overflow.md +8 -8
- package/docs/pages/utilities/overview.md +1 -1
- package/docs/pages/utilities/shape.md +3 -3
- package/docs/pages/utilities/sizing-wrapping.md +23 -16
- package/docs/pages/utilities/spacing.md +20 -20
- package/docs/pages/utilities/text.md +10 -10
- package/llms.txt +46 -4
- package/package.json +43 -13
- package/scripts/reserved-classes.json +278 -0
- package/src/cli/actual-css.js +133 -0
- package/src/css/actual.css +1 -31
- package/src/css/actual.full.css +11 -2
- package/src/css/components/alert.css +17 -4
- package/src/css/components/app-nav.css +76 -0
- package/src/css/components/avatar.css +4 -0
- package/src/css/components/badge.css +19 -19
- package/src/css/components/breadcrumb.css +1 -1
- package/src/css/components/button.css +20 -32
- package/src/css/components/card.css +34 -9
- package/src/css/{optional → components}/chat.css +0 -6
- package/src/css/components/drawer.css +24 -5
- package/src/css/{optional → components}/fab.css +1 -7
- package/src/css/components/flyout.css +5 -0
- package/src/css/components/index.css +37 -27
- package/src/css/components/indicator.css +47 -0
- package/src/css/components/join.css +8 -1
- package/src/css/components/key.css +2 -0
- package/src/css/components/list.css +83 -0
- package/src/css/components/menu.css +11 -8
- package/src/css/components/meter.css +4 -1
- package/src/css/components/modal.css +5 -17
- package/src/css/components/navbar.css +6 -15
- package/src/css/components/pagination.css +11 -0
- package/src/css/components/rating.css +101 -0
- package/src/css/components/spinner.css +5 -0
- package/src/css/components/status-bar.css +5 -0
- package/src/css/components/steps.css +122 -0
- package/src/css/components/surface.css +5 -0
- package/src/css/components/tab.css +20 -22
- package/src/css/components/table.css +6 -0
- package/src/css/components/tooltip.css +3 -7
- package/src/css/{focus.css → core/focus.css} +0 -8
- package/src/css/core/index.css +9 -0
- package/src/css/core/print.css +18 -0
- package/src/css/{theme.css → core/theme.css} +19 -19
- package/src/css/{tokens.css → core/tokens.css} +16 -4
- package/src/css/{variants.css → core/variants.css} +3 -2
- package/src/css/{optional → effects}/aura.css +1 -10
- package/src/css/effects/index.css +2 -0
- package/src/css/forms/base.css +8 -0
- package/src/css/forms/choice-card.css +7 -15
- package/src/css/forms/choice.css +49 -37
- package/src/css/forms/control.css +4 -1
- package/src/css/forms/custom-select.css +2 -0
- package/src/css/{optional → forms}/floating-field.css +25 -7
- package/src/css/forms/index.css +10 -13
- package/src/css/forms/native.css +15 -2
- package/src/css/{optional → forms}/otp.css +25 -16
- package/src/css/forms/range.css +14 -4
- package/src/css/forms/switch.css +31 -29
- package/src/css/layout/app-layout.css +102 -0
- package/src/css/layout/app-shell.css +6 -0
- package/src/css/layout/center.css +14 -0
- package/src/css/layout/cluster.css +21 -0
- package/src/css/layout/column-layout.css +144 -0
- package/src/css/layout/container-query.css +15 -0
- package/src/css/layout/frame.css +19 -0
- package/src/css/layout/grid.css +155 -0
- package/src/css/layout/index.css +44 -0
- package/src/css/layout/measure.css +9 -0
- package/src/css/layout/media.css +10 -0
- package/src/css/layout/scroll-target.css +15 -0
- package/src/css/layout/scroller.css +41 -0
- package/src/css/layout/sidebar-layout.css +52 -0
- package/src/css/layout/stack.css +21 -0
- package/src/css/layout/switcher.css +23 -0
- package/src/css/{optional/layout-extra.css → layout/topbar.css} +0 -20
- package/src/css/typography/index.css +5 -0
- package/src/css/typography/lead.css +7 -0
- package/src/css/{components → typography}/overline.css +2 -2
- package/src/css/{prose.css → typography/prose.css} +57 -38
- package/src/css/{utilities.css → utilities/base.css} +2 -0
- package/src/css/utilities/index.css +3 -0
- package/src/js/escape.js +36 -0
- package/src/js/flyout.js +22 -12
- package/src/js/full.js +26 -0
- package/src/js/index.js +5 -21
- package/src/js/surface.js +1 -31
- package/src/js/tooltip.js +48 -19
- package/src/js/validation.js +1 -1
- package/src/tooling/css-bundle.js +308 -0
- package/dist/actual-themes.min.css +0 -1
- package/dist/optional.css +0 -1048
- package/dist/optional.min.css +0 -1
- package/docs/pages/guides/optional-components.md +0 -33
- package/docs/pages/layout/list.md +0 -41
- package/src/css/grid.css +0 -109
- package/src/css/layout.css +0 -123
- package/src/css/optional/index.css +0 -10
- package/src/css/optional/scroller.css +0 -63
- package/src/css/print.css +0 -47
- package/src/css/themes/corporate.css +0 -60
- package/src/css/themes/cyberpunk.css +0 -60
- package/src/css/themes/dim.css +0 -33
- package/src/css/themes/edge.css +0 -117
- package/src/css/themes/forest.css +0 -65
- package/src/css/themes/gradient.css +0 -97
- package/src/css/themes/index.css +0 -47
- package/src/css/themes/indigo.css +0 -33
- package/src/css/themes/lavender.css +0 -66
- package/src/css/themes/mono.css +0 -60
- package/src/css/themes/neon.css +0 -66
- package/src/css/themes/ocean.css +0 -60
- package/src/css/themes/petrol.css +0 -64
- package/src/css/themes/spruce.css +0 -64
- package/src/css/themes/square.css +0 -65
- package/src/css/themes/sunset.css +0 -66
- /package/src/css/{base.css → core/base.css} +0 -0
- /package/src/css/{intents.css → core/intents.css} +0 -0
- /package/src/css/{reset.css → core/reset.css} +0 -0
- /package/src/css/{optional → layout}/scroll-snap.css +0 -0
- /package/src/css/{optional/typography-fluid.css → typography/fluid.css} +0 -0
- /package/src/css/{optional/utilities-extra.css → utilities/extra.css} +0 -0
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
/* Keep an active focus ring above an adjacent hovered control. This matters
|
|
92
92
|
on platforms where clicking a button does not move focus from the input. */
|
|
93
93
|
.join > :is(:focus, :focus-within) {
|
|
94
|
-
z-index:
|
|
94
|
+
z-index: 4;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/* An input's border must read as the "primary" edge against an attached
|
|
@@ -115,3 +115,10 @@
|
|
|
115
115
|
outline: none;
|
|
116
116
|
box-shadow: none;
|
|
117
117
|
}
|
|
118
|
+
|
|
119
|
+
/* A default outline action belongs to the composite field border. An explicit
|
|
120
|
+
intent still provides its own outline color — --intent is guaranteed-invalid
|
|
121
|
+
for a neutral button (the :where(.btn) boundary), so the fallback applies. */
|
|
122
|
+
.join:has(> :is(.input, .textarea, .select)) > .btn.outline {
|
|
123
|
+
--btn-border-color: var(--intent, var(--border));
|
|
124
|
+
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Visual twin of .prose kbd (prose.css) — keep the two recipes in sync.
|
|
8
8
|
*/
|
|
9
|
+
/* @sync key-recipe */
|
|
9
10
|
.key {
|
|
10
11
|
display: inline-flex;
|
|
11
12
|
align-items: center;
|
|
@@ -25,3 +26,4 @@
|
|
|
25
26
|
white-space: nowrap;
|
|
26
27
|
vertical-align: 0.08em;
|
|
27
28
|
}
|
|
29
|
+
/* @sync key-recipe */
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Application list — repeated rows with optional leading and trailing regions.
|
|
3
|
+
* Content determines the number of lines; the component only owns the row
|
|
4
|
+
* geometry, dividers, and supporting-text treatment.
|
|
5
|
+
*
|
|
6
|
+
* Public hooks:
|
|
7
|
+
* --list-item-min-size
|
|
8
|
+
* --list-item-pad-block
|
|
9
|
+
* --list-item-pad-inline
|
|
10
|
+
* --list-item-gap
|
|
11
|
+
* --list-divider
|
|
12
|
+
*/
|
|
13
|
+
.list {
|
|
14
|
+
--list-item-min-size: var(--control-size-lg);
|
|
15
|
+
--list-item-pad-block: var(--space-30);
|
|
16
|
+
--list-item-pad-inline: 0;
|
|
17
|
+
--list-item-gap: var(--gap);
|
|
18
|
+
--list-divider: var(--border-width) solid var(--border);
|
|
19
|
+
|
|
20
|
+
display: grid;
|
|
21
|
+
gap: 0;
|
|
22
|
+
margin: 0;
|
|
23
|
+
padding: 0;
|
|
24
|
+
border-block-start: var(--list-divider);
|
|
25
|
+
list-style: none;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.list > li {
|
|
29
|
+
margin: 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.list > :where(.list-item),
|
|
33
|
+
.list > li > .list-item {
|
|
34
|
+
display: grid;
|
|
35
|
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
36
|
+
align-items: center;
|
|
37
|
+
gap: var(--list-item-gap);
|
|
38
|
+
min-block-size: var(--list-item-min-size);
|
|
39
|
+
padding-block: var(--list-item-pad-block);
|
|
40
|
+
padding-inline: var(--list-item-pad-inline);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.list > .list-item + .list-item,
|
|
44
|
+
.list > li + li {
|
|
45
|
+
border-block-start: var(--list-divider);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
a.list-item {
|
|
49
|
+
color: inherit;
|
|
50
|
+
text-decoration: none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
a.list-item:hover {
|
|
54
|
+
background: var(--surface-subtle);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.list-item-content {
|
|
58
|
+
min-inline-size: 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.list-item-title,
|
|
62
|
+
.list-item-text {
|
|
63
|
+
display: block;
|
|
64
|
+
margin: 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.list-item-text {
|
|
68
|
+
color: var(--text-muted);
|
|
69
|
+
font-size: var(--font-size-sm);
|
|
70
|
+
overflow-wrap: anywhere;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.list-item-trailing {
|
|
74
|
+
justify-self: end;
|
|
75
|
+
min-inline-size: 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@media print {
|
|
79
|
+
.list > :where(.list-item),
|
|
80
|
+
.list > li > .list-item {
|
|
81
|
+
break-inside: avoid;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Public hooks:
|
|
8
8
|
* --menu-item-icon-size
|
|
9
|
+
*
|
|
10
|
+
* Intent: .menu-item consumes --intent as its text color, so intent classes
|
|
11
|
+
* (.danger, .success, …) tint an item without a per-intent variant.
|
|
9
12
|
*/
|
|
10
13
|
|
|
11
14
|
.menu {
|
|
@@ -20,6 +23,13 @@
|
|
|
20
23
|
margin: 0;
|
|
21
24
|
}
|
|
22
25
|
|
|
26
|
+
/* Intent boundary — inherited intents do not tint this component.
|
|
27
|
+
Local intent classes still win because :where() has zero specificity. */
|
|
28
|
+
:where(.menu-item) {
|
|
29
|
+
--intent: initial;
|
|
30
|
+
--intent-fg: initial;
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
.menu-item {
|
|
24
34
|
--menu-item-icon-size: 1.25em;
|
|
25
35
|
|
|
@@ -32,7 +42,7 @@
|
|
|
32
42
|
border: 0;
|
|
33
43
|
border-radius: var(--radius-sm);
|
|
34
44
|
background: transparent;
|
|
35
|
-
color: var(--text);
|
|
45
|
+
color: var(--intent, var(--text));
|
|
36
46
|
font: inherit;
|
|
37
47
|
text-align: start;
|
|
38
48
|
text-decoration: none;
|
|
@@ -116,10 +126,3 @@
|
|
|
116
126
|
border: 0;
|
|
117
127
|
border-block-start: var(--border-width) solid var(--border);
|
|
118
128
|
}
|
|
119
|
-
|
|
120
|
-
@media (forced-colors: active) {
|
|
121
|
-
.menu-item:focus-visible {
|
|
122
|
-
outline: var(--border-width) solid ButtonText;
|
|
123
|
-
outline-offset: -1px;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
@@ -51,7 +51,10 @@
|
|
|
51
51
|
@media (forced-colors: active) {
|
|
52
52
|
.meter::-webkit-meter-optimum-value,
|
|
53
53
|
.meter::-webkit-meter-suboptimum-value,
|
|
54
|
-
.meter::-webkit-meter-even-less-good-value
|
|
54
|
+
.meter::-webkit-meter-even-less-good-value {
|
|
55
|
+
background: Highlight;
|
|
56
|
+
}
|
|
57
|
+
|
|
55
58
|
.meter::-moz-meter-bar {
|
|
56
59
|
background: Highlight;
|
|
57
60
|
}
|
|
@@ -239,23 +239,6 @@ html.has-modal-open.had-scrollbar {
|
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
-
@media (forced-colors: active) {
|
|
243
|
-
dialog.modal {
|
|
244
|
-
border-color: ButtonText;
|
|
245
|
-
background: Canvas;
|
|
246
|
-
color: CanvasText;
|
|
247
|
-
box-shadow: none;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
dialog.modal::backdrop {
|
|
251
|
-
background: Canvas;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
.dialog-icon {
|
|
255
|
-
border: var(--border-width) solid CanvasText;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
242
|
/* Close controls. A close button is an action attached to a surface, so it
|
|
260
243
|
never participates in the content flow. The modal and the drawer share the
|
|
261
244
|
same simple placement — absolute at the panel's top inline-end, inside the
|
|
@@ -315,3 +298,8 @@ html.has-modal-open.had-scrollbar {
|
|
|
315
298
|
outline: 2px solid transparent;
|
|
316
299
|
box-shadow: var(--focus-ring-shadow);
|
|
317
300
|
}
|
|
301
|
+
@media print {
|
|
302
|
+
dialog.modal[open] {
|
|
303
|
+
display: none !important;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
.nav-link:where([aria-current]:not([aria-current="false"])) {
|
|
68
68
|
background: var(--surface-subtle);
|
|
69
69
|
color: var(--text);
|
|
70
|
+
font-weight: var(--font-weight-bold);
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
.nav-link:hover {
|
|
@@ -74,7 +75,9 @@
|
|
|
74
75
|
color: var(--text);
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
/* Nav list — a vertical navigation list. Used by .drawer for stacked links.
|
|
78
|
+
/* Nav list — a vertical navigation list. Used by .drawer for stacked links.
|
|
79
|
+
Links fill each row so the whole line is an interactive target; the
|
|
80
|
+
horizontal .navbar-nav links keep their intrinsic size. */
|
|
78
81
|
.nav-list {
|
|
79
82
|
display: grid;
|
|
80
83
|
--gap: var(--space-20);
|
|
@@ -88,18 +91,6 @@
|
|
|
88
91
|
margin: 0;
|
|
89
92
|
}
|
|
90
93
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
outline: var(--border-width) solid Highlight;
|
|
94
|
-
background: Highlight;
|
|
95
|
-
color: HighlightText;
|
|
96
|
-
forced-color-adjust: none;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.nav-link:hover:not(:where([aria-current]:not([aria-current="false"]))) {
|
|
100
|
-
outline: var(--border-width) solid ButtonText;
|
|
101
|
-
outline-offset: 2px;
|
|
102
|
-
background: Canvas;
|
|
103
|
-
color: CanvasText;
|
|
104
|
-
}
|
|
94
|
+
.nav-list .nav-link {
|
|
95
|
+
inline-size: 100%;
|
|
105
96
|
}
|
|
@@ -16,9 +16,20 @@
|
|
|
16
16
|
margin: 0;
|
|
17
17
|
padding: 0;
|
|
18
18
|
list-style: none;
|
|
19
|
+
|
|
20
|
+
/* Arrows, page numbers, and truncation ellipses share one geometric
|
|
21
|
+
system: equal digit widths keep the row from re-flowing as numbers grow
|
|
22
|
+
(98 → 99 → 100). */
|
|
23
|
+
font-variant-numeric: tabular-nums;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
.pagination .btn {
|
|
27
|
+
/* Every item gets the same min footprint; wider content (100, 1000,
|
|
28
|
+
text labels) grows past it naturally. The default 1em control padding
|
|
29
|
+
would let an icon-only arrow exceed the numbered items' footprint, so
|
|
30
|
+
the horizontal padding tightens here and the min size does the work. */
|
|
31
|
+
--btn-pad-x: var(--space-20);
|
|
32
|
+
|
|
22
33
|
min-inline-size: var(--control-size);
|
|
23
34
|
}
|
|
24
35
|
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rating — integer star rating drawn on native radio inputs.
|
|
3
|
+
*
|
|
4
|
+
* The checked radio remains the functional baseline. :has() progressively
|
|
5
|
+
* fills preceding stars without reversing DOM or keyboard order. Forced
|
|
6
|
+
* colors restores the platform radio presentation.
|
|
7
|
+
*
|
|
8
|
+
* Public hooks:
|
|
9
|
+
* --rating-size
|
|
10
|
+
* --rating-gap
|
|
11
|
+
* --rating-color
|
|
12
|
+
* --rating-empty
|
|
13
|
+
* --rating-star
|
|
14
|
+
*/
|
|
15
|
+
:where(.rating) {
|
|
16
|
+
--intent: initial;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.rating {
|
|
20
|
+
--rating-size: 1.25rem;
|
|
21
|
+
--rating-gap: 0.1rem;
|
|
22
|
+
--rating-color: var(--intent, var(--warning));
|
|
23
|
+
--rating-empty: var(--border);
|
|
24
|
+
--rating-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='2 2 16 16'%3E%3Cpath d='M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 0 0 .95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 0 0-.364 1.118l1.07 3.292c.3.922-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 0 0-1.175 0l-2.8 2.034c-.783.57-1.838-.196-1.539-1.118l1.07-3.292a1 1 0 0 0-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 0 0 .951-.69l1.07-3.292Z'/%3E%3C/svg%3E");
|
|
25
|
+
|
|
26
|
+
display: inline-flex;
|
|
27
|
+
gap: 0;
|
|
28
|
+
color: var(--rating-color);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.rating > input[type="radio"] {
|
|
32
|
+
appearance: none;
|
|
33
|
+
flex: 0 0 auto;
|
|
34
|
+
inline-size: calc(var(--rating-size) + var(--rating-gap));
|
|
35
|
+
block-size: var(--rating-size);
|
|
36
|
+
margin: 0;
|
|
37
|
+
border: 0;
|
|
38
|
+
background: var(--rating-empty);
|
|
39
|
+
/* Contiguous radio boxes own hit-testing; the centered mask preserves the
|
|
40
|
+
star's proportions while leaving a purely visual gap between values. */
|
|
41
|
+
-webkit-mask: var(--rating-star) center / var(--rating-size) var(--rating-size) no-repeat;
|
|
42
|
+
mask: var(--rating-star) center / var(--rating-size) var(--rating-size) no-repeat;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
transition: background-color var(--duration);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.rating > input[type="radio"]:checked {
|
|
48
|
+
background: var(--rating-color);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.rating > input[type="radio"]:disabled {
|
|
52
|
+
cursor: not-allowed;
|
|
53
|
+
opacity: var(--disabled-opacity);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.rating > input[type="radio"]:focus-visible {
|
|
57
|
+
outline: var(--focus-outline);
|
|
58
|
+
outline-offset: var(--focus-outline-offset);
|
|
59
|
+
background: var(--rating-color);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* Browsers without :has() still show the selected native radio as one filled
|
|
63
|
+
star. The enhancement only adds cumulative checked and hover previews. */
|
|
64
|
+
@supports selector(:has(*)) {
|
|
65
|
+
.rating > input[type="radio"]:has(~ input[type="radio"]:checked) {
|
|
66
|
+
background: var(--rating-color);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@media (hover: hover) {
|
|
70
|
+
.rating > input[type="radio"]:not(:disabled):hover,
|
|
71
|
+
.rating > input[type="radio"]:has(~ input[type="radio"]:not(:disabled):hover) {
|
|
72
|
+
background: var(--rating-color);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* A hovered value previews exactly that value: later stars are emptied,
|
|
76
|
+
including a previously checked star beyond the pointer. */
|
|
77
|
+
.rating > input[type="radio"]:not(:disabled):hover ~ input[type="radio"] {
|
|
78
|
+
background: var(--rating-empty);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.rating.sm {
|
|
84
|
+
--rating-size: 1rem;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.rating.lg {
|
|
88
|
+
--rating-size: 1.75rem;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@media (forced-colors: active) {
|
|
92
|
+
.rating > input[type="radio"] {
|
|
93
|
+
appearance: auto;
|
|
94
|
+
inline-size: auto;
|
|
95
|
+
block-size: auto;
|
|
96
|
+
background: Canvas;
|
|
97
|
+
-webkit-mask: none;
|
|
98
|
+
mask: none;
|
|
99
|
+
opacity: 1;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Steps — semantic ordered-list progression. One intrinsic layout: items fill
|
|
3
|
+
* the row when they fit and hold a minimum width otherwise, so the sequence
|
|
4
|
+
* scrolls horizontally only when it genuinely cannot fit. No breakpoint decides
|
|
5
|
+
* this — the item minimum tracks the real content, not an arbitrary width.
|
|
6
|
+
*
|
|
7
|
+
* Markers come from the list counter; state stays in .complete and
|
|
8
|
+
* aria-current="step", so the component needs no runtime.
|
|
9
|
+
*
|
|
10
|
+
* Public hooks:
|
|
11
|
+
* --step-size
|
|
12
|
+
* --step-min
|
|
13
|
+
* --step-gap
|
|
14
|
+
* --step-line-size
|
|
15
|
+
* --step-marker-radius
|
|
16
|
+
* --step-complete-mark
|
|
17
|
+
* --step-connector
|
|
18
|
+
*
|
|
19
|
+
* Internal:
|
|
20
|
+
* --step-marker-bg
|
|
21
|
+
* --step-marker-border
|
|
22
|
+
* --step-marker-fg
|
|
23
|
+
* --step-line
|
|
24
|
+
*/
|
|
25
|
+
.steps {
|
|
26
|
+
--step-size: 1.75rem;
|
|
27
|
+
--step-min: 7rem;
|
|
28
|
+
--step-gap: var(--space-20);
|
|
29
|
+
--step-line-size: var(--border-width);
|
|
30
|
+
--step-marker-bg: var(--surface);
|
|
31
|
+
--step-marker-border: var(--border);
|
|
32
|
+
--step-marker-fg: var(--text-muted);
|
|
33
|
+
--step-marker-radius: var(--radius-full);
|
|
34
|
+
--step-line: var(--border);
|
|
35
|
+
|
|
36
|
+
counter-reset: actual-step;
|
|
37
|
+
display: flex;
|
|
38
|
+
inline-size: 100%;
|
|
39
|
+
margin: 0;
|
|
40
|
+
padding: 0;
|
|
41
|
+
list-style: none;
|
|
42
|
+
/* Fill when it fits, scroll when it cannot: items never shrink below
|
|
43
|
+
--step-min, so labels keep a readable width and the sequence scrolls
|
|
44
|
+
horizontally instead of squishing. overscroll-behavior keeps the scroll
|
|
45
|
+
from chaining to the page. */
|
|
46
|
+
overflow-x: auto;
|
|
47
|
+
overscroll-behavior-inline: contain;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.steps > li {
|
|
51
|
+
position: relative;
|
|
52
|
+
display: grid;
|
|
53
|
+
flex: 1 0 var(--step-min);
|
|
54
|
+
grid-template-rows: var(--step-size) auto;
|
|
55
|
+
gap: var(--step-gap);
|
|
56
|
+
justify-items: center;
|
|
57
|
+
min-inline-size: max(var(--step-size), var(--step-min));
|
|
58
|
+
color: var(--text-muted);
|
|
59
|
+
text-align: center;
|
|
60
|
+
counter-increment: actual-step;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.steps > li::before {
|
|
64
|
+
content: counter(actual-step);
|
|
65
|
+
position: relative;
|
|
66
|
+
z-index: 1;
|
|
67
|
+
display: inline-grid;
|
|
68
|
+
place-items: center;
|
|
69
|
+
inline-size: var(--step-size);
|
|
70
|
+
block-size: var(--step-size);
|
|
71
|
+
border: var(--border-width) solid var(--step-marker-border);
|
|
72
|
+
border-radius: var(--step-marker-radius);
|
|
73
|
+
background: var(--step-marker-bg);
|
|
74
|
+
color: var(--step-marker-fg);
|
|
75
|
+
font-size: var(--font-size-sm);
|
|
76
|
+
font-weight: var(--font-weight-strong);
|
|
77
|
+
line-height: 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.steps > li::after {
|
|
81
|
+
content: "";
|
|
82
|
+
position: absolute;
|
|
83
|
+
inset-block-start: calc((var(--step-size) - var(--step-line-size)) / 2);
|
|
84
|
+
inset-inline-start: calc(50% + var(--step-size) / 2);
|
|
85
|
+
inline-size: calc(100% - var(--step-size));
|
|
86
|
+
block-size: var(--step-line-size);
|
|
87
|
+
/* A custom property resolves its var() before inheritance, so a default
|
|
88
|
+
--step-connector: var(--step-line) on .steps would freeze the parent line
|
|
89
|
+
color and a .complete child's connector would never follow its own line.
|
|
90
|
+
Falling back to the local --step-line here keeps each connector in sync;
|
|
91
|
+
an explicit --step-connector still wins when the author sets one. */
|
|
92
|
+
background: var(--step-connector, var(--step-line));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.steps > li:last-child::after {
|
|
96
|
+
content: none;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.steps > :is(.complete, [aria-current="step"]) {
|
|
100
|
+
--step-marker-bg: var(--state-selected);
|
|
101
|
+
--step-marker-border: var(--state-selected);
|
|
102
|
+
--step-marker-fg: var(--state-selected-fg);
|
|
103
|
+
|
|
104
|
+
color: var(--text);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Thicker border is the selected affordance in every mode — structural, and it
|
|
108
|
+
never competes with the outline channel owned by focus. */
|
|
109
|
+
.steps > :is(.complete, [aria-current="step"])::before {
|
|
110
|
+
border-width: calc(var(--border-width) * 2);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.steps > .complete {
|
|
114
|
+
--step-line: var(--state-selected);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* A finished step may replace its number with a mark (e.g. a check glyph):
|
|
118
|
+
--step-complete-mark accepts any content value and falls back to the
|
|
119
|
+
counter, so existing numbered steppers are unchanged. */
|
|
120
|
+
.steps > .complete::before {
|
|
121
|
+
content: var(--step-complete-mark, counter(actual-step));
|
|
122
|
+
}
|
|
@@ -33,13 +33,14 @@
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
.tab {
|
|
36
|
+
/* Positioning context for the selected indicator pseudo. */
|
|
37
|
+
position: relative;
|
|
36
38
|
display: inline-flex;
|
|
37
39
|
align-items: center;
|
|
38
40
|
gap: var(--tab-gap, 0.375em);
|
|
39
41
|
min-block-size: var(--control-size);
|
|
40
42
|
padding-inline: var(--space-30);
|
|
41
43
|
border: 0;
|
|
42
|
-
border-block-end: 2px solid transparent;
|
|
43
44
|
border-radius: 0;
|
|
44
45
|
background: transparent;
|
|
45
46
|
color: var(--text-muted);
|
|
@@ -51,8 +52,6 @@
|
|
|
51
52
|
|
|
52
53
|
.tabs[aria-orientation="vertical"] .tab {
|
|
53
54
|
justify-content: flex-start;
|
|
54
|
-
border-block-end: 0;
|
|
55
|
-
border-inline-end: 2px solid transparent;
|
|
56
55
|
padding-inline-end: var(--space-40);
|
|
57
56
|
}
|
|
58
57
|
|
|
@@ -73,28 +72,27 @@
|
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
.tab[aria-selected="true"] {
|
|
76
|
-
border-block-end-color: var(--intent, var(--state-selected));
|
|
77
75
|
color: var(--intent, var(--state-selected));
|
|
76
|
+
/* Second, layout-free selected cue — the underline alone is color-only in
|
|
77
|
+
forced colors. */
|
|
78
|
+
font-weight: var(--font-weight-bold);
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
/* The selected indicator lives on a positioned pseudo so that only the active
|
|
82
|
+
tab owns an underline: a transparent border on every tab would surface in
|
|
83
|
+
forced colors and erase the distinction. currentColor follows the palette the
|
|
84
|
+
UA forces, so no forced-colors block is needed. */
|
|
85
|
+
.tab[aria-selected="true"]::after {
|
|
86
|
+
content: "";
|
|
87
|
+
position: absolute;
|
|
88
|
+
inset-inline: 0;
|
|
89
|
+
inset-block-end: 0;
|
|
90
|
+
border-block-end: 2px solid currentColor;
|
|
83
91
|
}
|
|
84
92
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
.tab[aria-selected="true"] {
|
|
92
|
-
border-block-end-color: Highlight;
|
|
93
|
-
color: Highlight;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.tabs[aria-orientation="vertical"] .tab[aria-selected="true"] {
|
|
97
|
-
border-block-end-color: transparent;
|
|
98
|
-
border-inline-end-color: Highlight;
|
|
99
|
-
}
|
|
93
|
+
.tabs[aria-orientation="vertical"] .tab[aria-selected="true"]::after {
|
|
94
|
+
inset-block: 0;
|
|
95
|
+
inset-inline: auto 0;
|
|
96
|
+
border-block-end: 0;
|
|
97
|
+
border-inline-end: 2px solid currentColor;
|
|
100
98
|
}
|
|
@@ -64,3 +64,9 @@
|
|
|
64
64
|
.table > :last-child > tr:last-child > * {
|
|
65
65
|
border-block-end: 0;
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
/* Same compact vocabulary as .card.compact: one hook change, no selector
|
|
69
|
+
duplication. Density is padding only — typography never changes. */
|
|
70
|
+
.table.compact {
|
|
71
|
+
--table-cell-pad: var(--space-20);
|
|
72
|
+
}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
max-inline-size: min(24rem, calc(var(--viewport-inline) - 2rem));
|
|
25
25
|
padding: 0.25em 0.6em;
|
|
26
26
|
border-radius: var(--radius-sm);
|
|
27
|
+
border: var(--border-width) solid transparent;
|
|
27
28
|
background: var(--tooltip-bg);
|
|
28
29
|
color: var(--tooltip-fg);
|
|
29
30
|
font-size: var(--font-size-xs);
|
|
@@ -102,13 +103,8 @@
|
|
|
102
103
|
clip-path: polygon(0 50%, 100% 0, 100% 100%);
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
@media
|
|
106
|
+
@media print {
|
|
106
107
|
.tooltip {
|
|
107
|
-
|
|
108
|
-
--tooltip-fg: CanvasText;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.tooltip::before {
|
|
112
|
-
display: none;
|
|
108
|
+
display: none !important;
|
|
113
109
|
}
|
|
114
110
|
}
|
|
@@ -15,12 +15,4 @@
|
|
|
15
15
|
:focus:not(:focus-visible) {
|
|
16
16
|
outline: none;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
/* Pointer focus must still signal in high-contrast mode, where the shared
|
|
20
|
-
box-shadow rings are disabled (--focus-ring-shadow: none). */
|
|
21
|
-
@media (forced-colors: active) {
|
|
22
|
-
:focus:not(:focus-visible) {
|
|
23
|
-
outline: var(--focus-outline);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
18
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* Core — the minimal Actual language. Every module depends on this order. */
|
|
2
|
+
@import "./reset.css";
|
|
3
|
+
@import "./tokens.css";
|
|
4
|
+
@import "./theme.css";
|
|
5
|
+
@import "./base.css";
|
|
6
|
+
@import "./intents.css";
|
|
7
|
+
@import "./variants.css";
|
|
8
|
+
@import "./focus.css";
|
|
9
|
+
@import "./print.css";
|