actual-css 0.3.1 → 0.4.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 +67 -3
- package/README.md +35 -30
- package/dist/actual.css +73 -4946
- package/dist/actual.full.css +7090 -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/cascade-layer.md +34 -13
- package/docs/design-notes/column-layout.md +677 -0
- package/docs/design-notes/forced-colors.md +3 -0
- package/docs/design-notes/grid.md +612 -0
- package/docs/design-notes/naming.md +15 -0
- package/docs/design-notes/widget-primitives.md +1 -0
- package/docs/navigation.json +5 -1
- package/docs/pages/components/alert.md +16 -14
- package/docs/pages/components/aura.md +1 -1
- package/docs/pages/components/avatar.md +6 -6
- package/docs/pages/components/badge.md +7 -7
- package/docs/pages/components/button.md +16 -16
- package/docs/pages/components/card.md +13 -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 +7 -7
- package/docs/pages/components/navbar.md +9 -8
- package/docs/pages/components/pagination.md +4 -3
- package/docs/pages/components/skeleton.md +4 -4
- package/docs/pages/components/spinner.md +5 -5
- package/docs/pages/components/table.md +30 -5
- package/docs/pages/enhancements/flyout.md +13 -13
- 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 +6 -6
- package/docs/pages/enhancements/tooltip.md +1 -1
- package/docs/pages/examples/overview.md +39 -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 +1 -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 +41 -45
- 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 +186 -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-shell.md +1 -1
- package/docs/pages/layout/center.md +1 -1
- package/docs/pages/layout/choosing.md +39 -0
- package/docs/pages/layout/column-layout.md +206 -0
- package/docs/pages/layout/frame.md +6 -1
- package/docs/pages/layout/grid.md +100 -102
- package/docs/pages/layout/list.md +1 -1
- 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 +20 -19
- package/docs/pages/layout/stack.md +53 -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/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 +1 -1
- 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 +42 -13
- package/scripts/reserved-classes.json +261 -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/badge.css +18 -6
- package/src/css/components/breadcrumb.css +1 -1
- package/src/css/components/button.css +19 -1
- package/src/css/components/card.css +27 -2
- package/src/css/components/drawer.css +27 -2
- package/src/css/components/flyout.css +5 -0
- package/src/css/components/index.css +32 -27
- package/src/css/components/join.css +8 -1
- package/src/css/components/key.css +2 -0
- package/src/css/components/menu.css +11 -1
- package/src/css/components/meter.css +4 -1
- package/src/css/components/modal.css +5 -0
- package/src/css/components/pagination.css +11 -0
- package/src/css/components/spinner.css +5 -0
- package/src/css/components/status-bar.css +5 -0
- package/src/css/components/surface.css +5 -0
- package/src/css/components/table.css +6 -0
- package/src/css/components/tooltip.css +5 -0
- package/src/css/core/index.css +9 -0
- package/src/css/core/print.css +18 -0
- package/src/css/{theme.css → core/theme.css} +20 -10
- package/src/css/{tokens.css → core/tokens.css} +15 -2
- package/src/css/{variants.css → core/variants.css} +3 -2
- package/src/css/effects/index.css +2 -0
- package/src/css/forms/base.css +8 -0
- package/src/css/forms/choice-card.css +5 -4
- 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 +20 -16
- package/src/css/forms/switch.css +31 -29
- package/src/css/layout/app-shell.css +6 -0
- package/src/css/layout/center.css +13 -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 +13 -0
- package/src/css/layout/frame.css +19 -0
- package/src/css/layout/grid.css +141 -0
- package/src/css/layout/index.css +42 -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 +31 -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} +53 -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 +46 -18
- 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/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/{optional → components}/chat.css +0 -0
- /package/src/css/{optional → components}/fab.css +0 -0
- /package/src/css/{base.css → core/base.css} +0 -0
- /package/src/css/{focus.css → core/focus.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 → effects}/aura.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
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
border-radius: var(--radius-sm);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
.breadcrumb :where(a, span):where([aria-current]:not([aria-current="false"])) {
|
|
45
|
+
.breadcrumb :where(li, a, span):where([aria-current]:not([aria-current="false"])) {
|
|
46
46
|
color: var(--text);
|
|
47
47
|
font-weight: var(--font-weight-medium);
|
|
48
48
|
}
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
|
|
134
134
|
.btn.soft {
|
|
135
135
|
--ui-hover-bg: color-mix(
|
|
136
|
-
in
|
|
136
|
+
in oklab,
|
|
137
137
|
var(--surface) calc(var(--soft-bg-mix) - var(--soft-hover-alpha)),
|
|
138
138
|
var(--intent, var(--neutral))
|
|
139
139
|
);
|
|
@@ -149,6 +149,9 @@
|
|
|
149
149
|
the overlay darkening for solid/soft is .btn-specific. */
|
|
150
150
|
.btn:not(:where(:disabled, [aria-disabled="true"])):hover {
|
|
151
151
|
background: var(--ui-hover-bg, var(--btn-default-hover-bg));
|
|
152
|
+
/* Huge inset spread paints the overlay over any border-radius without a
|
|
153
|
+
pseudo-element; a plain background would replace the fill instead of
|
|
154
|
+
darkening it. */
|
|
152
155
|
box-shadow: inset 0 0 0 999px var(--btn-hover-overlay);
|
|
153
156
|
}
|
|
154
157
|
|
|
@@ -249,6 +252,11 @@ a.btn[aria-disabled="true"] {
|
|
|
249
252
|
forced-color-adjust: none;
|
|
250
253
|
}
|
|
251
254
|
|
|
255
|
+
.btn:is([aria-pressed="true"], [aria-current="page"]):not(.link):focus-visible {
|
|
256
|
+
outline: var(--focus-outline);
|
|
257
|
+
box-shadow: none;
|
|
258
|
+
}
|
|
259
|
+
|
|
252
260
|
.btn:hover:not(:where(:disabled, [aria-disabled="true"], .link)) {
|
|
253
261
|
outline: var(--border-width) solid ButtonText;
|
|
254
262
|
outline-offset: 2px;
|
|
@@ -262,3 +270,13 @@ a.btn[aria-disabled="true"] {
|
|
|
262
270
|
forced-color-adjust: auto;
|
|
263
271
|
}
|
|
264
272
|
}
|
|
273
|
+
@media print {
|
|
274
|
+
:is(button, input[type="button"], input[type="submit"], input[type="reset"]).btn {
|
|
275
|
+
display: none !important;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
a.btn[href^="http"]::after {
|
|
279
|
+
content: " (" attr(href) ")";
|
|
280
|
+
font-size: 0.875em;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
* Cards provide a neutral raised surface for grouped content.
|
|
3
3
|
*
|
|
4
4
|
* Surface, border, radius, padding, density, and elevation stay local here.
|
|
5
|
-
* Direct header/footer children are structural slots
|
|
6
|
-
*
|
|
5
|
+
* Direct header/footer children are structural slots; a direct footer is
|
|
6
|
+
* anchored to the card's bottom edge when extra block space is available (so
|
|
7
|
+
* price/action rows align across equal-height cards in a grid). Page layout
|
|
8
|
+
* remains the job of markup and layout primitives outside the card.
|
|
7
9
|
*
|
|
8
10
|
* Public hooks:
|
|
9
11
|
* --card-pad
|
|
@@ -47,6 +49,17 @@
|
|
|
47
49
|
border-radius: var(--card-radius);
|
|
48
50
|
}
|
|
49
51
|
|
|
52
|
+
/* The box lives at zero specificity so a layout primitive applied to the same
|
|
53
|
+
element owns it. components/ is imported after layout/, so a plain .card
|
|
54
|
+
declaration would beat .media (and any other non-column primitive) on source
|
|
55
|
+
order alone and silently flatten `class="card media"` into a column. The
|
|
56
|
+
column is still the default a bare .card gets, and > footer's margin-auto
|
|
57
|
+
bottom-anchoring depends on it. */
|
|
58
|
+
:where(.card) {
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
}
|
|
62
|
+
|
|
50
63
|
.card > * {
|
|
51
64
|
min-inline-size: 0;
|
|
52
65
|
}
|
|
@@ -69,6 +82,12 @@
|
|
|
69
82
|
align-items: var(--items-align, flex-start);
|
|
70
83
|
}
|
|
71
84
|
|
|
85
|
+
/* A direct footer is pinned to the bottom when the card has free space.
|
|
86
|
+
Specificity beats .stack > * so a .card.stack keeps this contract. */
|
|
87
|
+
.card > footer {
|
|
88
|
+
margin-block-start: auto;
|
|
89
|
+
}
|
|
90
|
+
|
|
72
91
|
.card > :first-child {
|
|
73
92
|
margin-block-start: 0;
|
|
74
93
|
}
|
|
@@ -126,3 +145,9 @@
|
|
|
126
145
|
.card > :where(header, footer, figure).bleed {
|
|
127
146
|
padding: var(--card-pad);
|
|
128
147
|
}
|
|
148
|
+
@media print {
|
|
149
|
+
.card {
|
|
150
|
+
border: var(--border-width) solid CanvasText;
|
|
151
|
+
break-inside: avoid;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -108,8 +108,8 @@ dialog.drawer nav {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
/*
|
|
112
|
-
|
|
111
|
+
/* Safari before 16.4 does not support :dir(); keep the ancestor-attribute
|
|
112
|
+
path as the Minimal-tier fallback. */
|
|
113
113
|
[dir="rtl"] dialog.drawer {
|
|
114
114
|
--drawer-closed-translate: 100%;
|
|
115
115
|
}
|
|
@@ -118,6 +118,26 @@ dialog.drawer nav {
|
|
|
118
118
|
--drawer-closed-translate: -100%;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
/* :dir() follows inherited HTML directionality and handles nested direction
|
|
122
|
+
changes. Explicit ltr rules neutralize an outer RTL fallback selector. */
|
|
123
|
+
@supports selector(:dir(rtl)) {
|
|
124
|
+
dialog.drawer:dir(ltr) {
|
|
125
|
+
--drawer-closed-translate: -100%;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
dialog.drawer[data-side="end"]:dir(ltr) {
|
|
129
|
+
--drawer-closed-translate: 100%;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
dialog.drawer:dir(rtl) {
|
|
133
|
+
--drawer-closed-translate: 100%;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
dialog.drawer[data-side="end"]:dir(rtl) {
|
|
137
|
+
--drawer-closed-translate: -100%;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
121
141
|
@media (forced-colors: active) {
|
|
122
142
|
dialog.drawer::backdrop {
|
|
123
143
|
background: Canvas;
|
|
@@ -137,3 +157,8 @@ dialog.drawer > header,
|
|
|
137
157
|
dialog.drawer > form > header {
|
|
138
158
|
padding-inline-end: calc(var(--control-size) + var(--space-30));
|
|
139
159
|
}
|
|
160
|
+
@media print {
|
|
161
|
+
dialog.drawer[open] {
|
|
162
|
+
display: none !important;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -170,3 +170,8 @@
|
|
|
170
170
|
/* Vertical dividers — .menu-separator (menu.css) is the canonical way to
|
|
171
171
|
separate menu items. Flyout panels that are not menus use auto grid gap
|
|
172
172
|
declared on .flyout itself. */
|
|
173
|
+
@media print {
|
|
174
|
+
.flyout {
|
|
175
|
+
display: none !important;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -1,42 +1,47 @@
|
|
|
1
1
|
/* Controls */
|
|
2
|
-
@import "button.css";
|
|
3
|
-
@import "badge.css";
|
|
4
|
-
@import "alert.css";
|
|
5
|
-
@import "actions.css";
|
|
2
|
+
@import "./button.css";
|
|
3
|
+
@import "./badge.css";
|
|
4
|
+
@import "./alert.css";
|
|
5
|
+
@import "./actions.css";
|
|
6
6
|
|
|
7
7
|
/* Surfaces */
|
|
8
|
-
@import "card.css";
|
|
9
|
-
@import "surface.css";
|
|
10
|
-
@import "modal.css";
|
|
11
|
-
@import "drawer.css";
|
|
8
|
+
@import "./card.css";
|
|
9
|
+
@import "./surface.css";
|
|
10
|
+
@import "./modal.css";
|
|
11
|
+
@import "./drawer.css";
|
|
12
12
|
|
|
13
13
|
/* Overlays */
|
|
14
|
-
@import "flyout.css";
|
|
15
|
-
@import "menu.css";
|
|
16
|
-
@import "tooltip.css";
|
|
14
|
+
@import "./flyout.css";
|
|
15
|
+
@import "./menu.css";
|
|
16
|
+
@import "./tooltip.css";
|
|
17
17
|
|
|
18
18
|
/* Disclosure */
|
|
19
|
-
@import "accordion.css";
|
|
19
|
+
@import "./accordion.css";
|
|
20
20
|
|
|
21
21
|
/* Feedback */
|
|
22
|
-
@import "spinner.css";
|
|
23
|
-
@import "skeleton.css";
|
|
24
|
-
@import "busy.css";
|
|
25
|
-
@import "progress.css";
|
|
26
|
-
@import "status-bar.css";
|
|
22
|
+
@import "./spinner.css";
|
|
23
|
+
@import "./skeleton.css";
|
|
24
|
+
@import "./busy.css";
|
|
25
|
+
@import "./progress.css";
|
|
26
|
+
@import "./status-bar.css";
|
|
27
27
|
|
|
28
28
|
/* Display */
|
|
29
|
-
@import "avatar.css";
|
|
30
|
-
@import "key.css";
|
|
31
|
-
@import "
|
|
29
|
+
@import "./avatar.css";
|
|
30
|
+
@import "./key.css";
|
|
31
|
+
@import "./chat.css";
|
|
32
|
+
@import "./fab.css";
|
|
32
33
|
|
|
33
34
|
/* Navigation */
|
|
34
|
-
@import "navbar.css";
|
|
35
|
-
@import "breadcrumb.css";
|
|
36
|
-
@import "pagination.css";
|
|
37
|
-
@import "tab.css";
|
|
38
|
-
@import "scrollspy.css";
|
|
35
|
+
@import "./navbar.css";
|
|
36
|
+
@import "./breadcrumb.css";
|
|
37
|
+
@import "./pagination.css";
|
|
38
|
+
@import "./tab.css";
|
|
39
|
+
@import "./scrollspy.css";
|
|
39
40
|
|
|
40
41
|
/* Data */
|
|
41
|
-
@import "table.css";
|
|
42
|
-
@import "meter.css";
|
|
42
|
+
@import "./table.css";
|
|
43
|
+
@import "./meter.css";
|
|
44
|
+
|
|
45
|
+
/* Composed controls — imported last so equal-specificity corner rules remain
|
|
46
|
+
later than the controls they group. */
|
|
47
|
+
@import "./join.css";
|
|
@@ -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 */
|
|
@@ -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;
|
|
@@ -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
|
}
|
|
@@ -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
|
|
|
@@ -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
|
+
}
|
|
@@ -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";
|
|
@@ -101,6 +101,16 @@
|
|
|
101
101
|
--focus-ring-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
/* Native platform controls (checkbox, radio, range, progress) that are not
|
|
105
|
+
restyled by a component class still follow the theme accent. Declared on
|
|
106
|
+
every island: accent-color inherits as a computed value, so islands must
|
|
107
|
+
recompute it from their own --primary (same resolution rule as above).
|
|
108
|
+
Unsupported browsers ignore it; forced-colors keeps browser control. */
|
|
109
|
+
:root,
|
|
110
|
+
[data-theme] {
|
|
111
|
+
accent-color: var(--primary);
|
|
112
|
+
}
|
|
113
|
+
|
|
104
114
|
/* Tone subsystem — fixed-backdrop foreground for components placed over media
|
|
105
115
|
or other surfaces outside the theme token stack. Use data-theme islands for
|
|
106
116
|
full dark/light subtree inversion. */
|
|
@@ -115,13 +125,13 @@
|
|
|
115
125
|
/* Focus ring derivation — color-mix tier. Runs whether or not light-dark()
|
|
116
126
|
is also supported, so it covers the color-mix-without-light-dark browser
|
|
117
127
|
tier on its own; the light-dark block below refines it further with the
|
|
118
|
-
light/dark alpha split once both features are available.
|
|
119
|
-
|
|
120
|
-
|
|
128
|
+
light/dark alpha split once both features are available. Declared on every
|
|
129
|
+
[data-theme] island (not just the built-in light/dark pair) so custom
|
|
130
|
+
islands recolor the ring for free; a preset that re-declares --focus-ring
|
|
131
|
+
later in source order intentionally pins its own ring instead. */
|
|
121
132
|
@supports (color: color-mix(in oklch, red, white)) {
|
|
122
133
|
:root,
|
|
123
|
-
[data-theme
|
|
124
|
-
[data-theme="dark"] {
|
|
134
|
+
[data-theme] {
|
|
125
135
|
--focus-ring: color-mix(in oklch, var(--focus) 30%, transparent);
|
|
126
136
|
}
|
|
127
137
|
}
|
|
@@ -170,7 +180,7 @@
|
|
|
170
180
|
|
|
171
181
|
@supports (color: color-mix(in oklch, red, white)) and (color: light-dark(red, blue)) {
|
|
172
182
|
:root,
|
|
173
|
-
[data-theme
|
|
183
|
+
[data-theme] {
|
|
174
184
|
--focus-ring: light-dark(
|
|
175
185
|
color-mix(in oklch, var(--focus) 30%, transparent),
|
|
176
186
|
color-mix(in oklch, var(--focus) 28%, transparent)
|
|
@@ -180,8 +190,7 @@
|
|
|
180
190
|
|
|
181
191
|
@media (forced-colors: active) {
|
|
182
192
|
:root,
|
|
183
|
-
[data-theme
|
|
184
|
-
[data-theme="dark"] {
|
|
193
|
+
[data-theme] {
|
|
185
194
|
--focus-outline-color: Highlight;
|
|
186
195
|
--focus-ring-shadow: none;
|
|
187
196
|
|
|
@@ -191,8 +200,9 @@
|
|
|
191
200
|
|
|
192
201
|
@media (prefers-contrast: more) {
|
|
193
202
|
:root,
|
|
194
|
-
|
|
195
|
-
|
|
203
|
+
/* The repeated attribute intentionally outranks single-attribute preset
|
|
204
|
+
palettes, including a preset stylesheet loaded after the core. */
|
|
205
|
+
[data-theme][data-theme] {
|
|
196
206
|
--border-width: 2px;
|
|
197
207
|
--focus-outline-offset: 3px;
|
|
198
208
|
--focus-ring-width: 4px;
|
|
@@ -83,13 +83,21 @@
|
|
|
83
83
|
|
|
84
84
|
/* Controls — inputs and buttons share --control-size so heights always match.
|
|
85
85
|
.sm/.lg (variants.css) switch --control-size; --control-font-size stays
|
|
86
|
-
at its baseline because density does not change typography.
|
|
86
|
+
at its baseline because density does not change typography.
|
|
87
|
+
|
|
88
|
+
Inline choices (checkbox, radio, switch) are typographic, not field-sized:
|
|
89
|
+
they sit on a line of text, so they follow --control-font-size through
|
|
90
|
+
--choice-control-size instead of --control-size. Being an em value in
|
|
91
|
+
:root is deliberate — an unregistered custom property resolves its units
|
|
92
|
+
at the element that consumes it, so one declaration tracks whatever font
|
|
93
|
+
size the choice actually renders at. */
|
|
87
94
|
--control-size-sm: 2rem;
|
|
88
95
|
--control-size-md: 2.375rem;
|
|
89
96
|
--control-size-lg: 2.75rem;
|
|
90
97
|
--control-size: var(--control-size-md);
|
|
91
98
|
--control-pad-x: 1em;
|
|
92
99
|
--control-font-size: var(--font-size-md);
|
|
100
|
+
--choice-control-size: 1.125em;
|
|
93
101
|
--disabled-opacity: 0.65;
|
|
94
102
|
}
|
|
95
103
|
|
|
@@ -118,6 +126,10 @@
|
|
|
118
126
|
--soft-bg-mix: 88%;
|
|
119
127
|
--soft-border-mix: 65%;
|
|
120
128
|
--soft-hover-alpha: 12%;
|
|
129
|
+
/* Soft foreground: the share of raw intent in soft text. 100% keeps the
|
|
130
|
+
pure intent color; lower values rebate it toward --text, which vivid or
|
|
131
|
+
light intent palettes need to stay legible on their own soft surface. */
|
|
132
|
+
--soft-fg-mix: 100%;
|
|
121
133
|
|
|
122
134
|
/* Shared icon assets. Override these URLs when a strict CSP disallows data:. */
|
|
123
135
|
--icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%238a8594' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
|
|
@@ -142,7 +154,8 @@
|
|
|
142
154
|
}
|
|
143
155
|
|
|
144
156
|
@media (forced-colors: active) {
|
|
145
|
-
:root
|
|
157
|
+
:root,
|
|
158
|
+
[data-theme] {
|
|
146
159
|
--state-selected: Highlight;
|
|
147
160
|
--state-selected-fg: HighlightText;
|
|
148
161
|
--state-disabled: GrayText;
|
|
@@ -85,12 +85,13 @@
|
|
|
85
85
|
@supports (color: color-mix(in oklch, red, white)) {
|
|
86
86
|
.soft {
|
|
87
87
|
/* @sync soft-recipe */
|
|
88
|
-
--ui-bg: color-mix(in
|
|
88
|
+
--ui-bg: color-mix(in oklab, var(--surface) var(--soft-bg-mix), var(--intent, var(--neutral)));
|
|
89
89
|
--ui-border: color-mix(
|
|
90
|
-
in
|
|
90
|
+
in oklab,
|
|
91
91
|
var(--surface) var(--soft-border-mix),
|
|
92
92
|
var(--intent, var(--neutral))
|
|
93
93
|
);
|
|
94
|
+
--ui-fg: color-mix(in oklab, var(--text), var(--intent, var(--text)) var(--soft-fg-mix));
|
|
94
95
|
/* @sync soft-recipe */
|
|
95
96
|
}
|
|
96
97
|
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
/* Subtle background tint on checked — modern browsers only */
|
|
86
86
|
@supports (color: color-mix(in oklch, red, white)) {
|
|
87
87
|
.choice-card:has(:checked) {
|
|
88
|
-
--choice-card-bg: color-mix(in
|
|
88
|
+
--choice-card-bg: color-mix(in oklab, var(--surface) 96%, var(--intent, var(--primary)));
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -139,18 +139,19 @@
|
|
|
139
139
|
|
|
140
140
|
.choice-card:has(:checked) {
|
|
141
141
|
--choice-card-border: Highlight;
|
|
142
|
-
/* Pin the
|
|
143
|
-
|
|
142
|
+
/* Pin the selected surface to the system canvas: only the essential
|
|
143
|
+
marker pseudos opt out of remapping, never the interactive card host. */
|
|
144
144
|
--choice-card-bg: Canvas;
|
|
145
|
-
forced-color-adjust: none;
|
|
146
145
|
}
|
|
147
146
|
|
|
148
147
|
.choice-card:has(:checked)::before {
|
|
149
148
|
background: Highlight;
|
|
150
149
|
box-shadow: 0 0 0 2px Canvas;
|
|
150
|
+
forced-color-adjust: none;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
.choice-card:has(:checked)::after {
|
|
154
154
|
background: HighlightText;
|
|
155
|
+
forced-color-adjust: none;
|
|
155
156
|
}
|
|
156
157
|
}
|