actual-css 0.1.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 +11 -0
- package/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/actual.css +4929 -0
- package/dist/actual.js +3 -0
- package/dist/actual.js.map +31 -0
- package/dist/actual.min.css +1 -0
- package/docs/README.md +26 -0
- package/docs/components.md +860 -0
- package/docs/design-notes/accessibility-decisions.md +32 -0
- package/docs/design-notes/browser-support.md +93 -0
- package/docs/design-notes/cascade-layer.md +52 -0
- package/docs/design-notes/css-anchor.md +33 -0
- package/docs/design-notes/naming.md +37 -0
- package/docs/design-notes/previous-work.md +5 -0
- package/docs/design-notes/references.md +324 -0
- package/docs/forms.md +1265 -0
- package/docs/javascript.md +426 -0
- package/docs/layout.md +480 -0
- package/docs/mental-model.md +73 -0
- package/docs/patterns.md +415 -0
- package/docs/reserved.md +7 -0
- package/docs/tokens.md +455 -0
- package/docs/typography.md +159 -0
- package/docs/ui.md +937 -0
- package/docs/utilities.md +384 -0
- package/llms.txt +17 -0
- package/package.json +101 -0
- package/src/css/actual.css +17 -0
- package/src/css/actual.full.css +2 -0
- package/src/css/actual.layer.css +3 -0
- package/src/css/base.css +70 -0
- package/src/css/components/accordion.css +97 -0
- package/src/css/components/actions.css +21 -0
- package/src/css/components/alert.css +137 -0
- package/src/css/components/avatar.css +199 -0
- package/src/css/components/badge.css +143 -0
- package/src/css/components/breadcrumb.css +56 -0
- package/src/css/components/busy.css +44 -0
- package/src/css/components/button.css +216 -0
- package/src/css/components/card.css +140 -0
- package/src/css/components/drawer.css +122 -0
- package/src/css/components/flyout.css +243 -0
- package/src/css/components/index.css +41 -0
- package/src/css/components/join.css +106 -0
- package/src/css/components/key.css +25 -0
- package/src/css/components/meter.css +81 -0
- package/src/css/components/modal.css +162 -0
- package/src/css/components/navbar.css +98 -0
- package/src/css/components/overline.css +49 -0
- package/src/css/components/pagination.css +30 -0
- package/src/css/components/progress.css +126 -0
- package/src/css/components/scrollspy.css +27 -0
- package/src/css/components/skeleton.css +67 -0
- package/src/css/components/spinner.css +60 -0
- package/src/css/components/status-bar.css +82 -0
- package/src/css/components/surface.css +48 -0
- package/src/css/components/tab.css +128 -0
- package/src/css/components/table.css +64 -0
- package/src/css/components/tooltip.css +107 -0
- package/src/css/dialog-fallback.css +56 -0
- package/src/css/focus.css +13 -0
- package/src/css/forms/choice-card.css +158 -0
- package/src/css/forms/choice.css +196 -0
- package/src/css/forms/control.css +106 -0
- package/src/css/forms/custom-select.css +93 -0
- package/src/css/forms/form-actions.css +43 -0
- package/src/css/forms/form.css +57 -0
- package/src/css/forms/index.css +15 -0
- package/src/css/forms/input-icon.css +36 -0
- package/src/css/forms/native.css +68 -0
- package/src/css/forms/select.css +36 -0
- package/src/css/forms/switch.css +127 -0
- package/src/css/forms/validation.css +63 -0
- package/src/css/grid.css +95 -0
- package/src/css/intents.css +33 -0
- package/src/css/layout.css +80 -0
- package/src/css/optional/index.css +5 -0
- package/src/css/optional/layout-extra.css +55 -0
- package/src/css/optional/scroll-snap.css +51 -0
- package/src/css/optional/scroller.css +51 -0
- package/src/css/optional/typography-fluid.css +48 -0
- package/src/css/optional/utilities-extra.css +289 -0
- package/src/css/print.css +47 -0
- package/src/css/prose.css +187 -0
- package/src/css/reset.css +56 -0
- package/src/css/theme.css +186 -0
- package/src/css/themes/corporate.css +60 -0
- package/src/css/themes/cyberpunk.css +60 -0
- package/src/css/themes/dark.css +32 -0
- package/src/css/themes/dim.css +33 -0
- package/src/css/themes/edge.css +143 -0
- package/src/css/themes/forest.css +65 -0
- package/src/css/themes/gradient.css +97 -0
- package/src/css/themes/index.css +43 -0
- package/src/css/themes/lavender.css +66 -0
- package/src/css/themes/mono.css +60 -0
- package/src/css/themes/neon.css +66 -0
- package/src/css/themes/ocean.css +60 -0
- package/src/css/themes/petrol.css +64 -0
- package/src/css/themes/spruce.css +64 -0
- package/src/css/themes/square.css +68 -0
- package/src/css/themes/sunset.css +66 -0
- package/src/css/tokens.css +122 -0
- package/src/css/utilities.css +162 -0
- package/src/css/variants.css +118 -0
- package/src/js/command.js +165 -0
- package/src/js/context-menu.js +291 -0
- package/src/js/dialog-fallback.js +163 -0
- package/src/js/dialog.js +503 -0
- package/src/js/enhance.js +208 -0
- package/src/js/events.js +22 -0
- package/src/js/filter.js +122 -0
- package/src/js/floating.js +462 -0
- package/src/js/flyout.js +187 -0
- package/src/js/focus.js +35 -0
- package/src/js/index.js +26 -0
- package/src/js/input.js +47 -0
- package/src/js/keys.js +30 -0
- package/src/js/mask.js +184 -0
- package/src/js/menu.js +88 -0
- package/src/js/password.js +98 -0
- package/src/js/scrollspy.js +121 -0
- package/src/js/selectors.js +59 -0
- package/src/js/status.js +158 -0
- package/src/js/surface.js +358 -0
- package/src/js/tab.js +173 -0
- package/src/js/tooltip.js +374 -0
- package/src/js/validation.js +419 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
color-scheme: light dark;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
[data-theme="light"] {
|
|
6
|
+
color-scheme: light;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
[data-theme="dark"] {
|
|
10
|
+
color-scheme: dark;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* Dark mode is progressive enhancement via light-dark(). Older browsers get
|
|
14
|
+
the light fallback rather than a partially dark native color scheme over
|
|
15
|
+
light tokens. */
|
|
16
|
+
@supports not (color: light-dark(red, blue)) {
|
|
17
|
+
:root,
|
|
18
|
+
[data-theme="light"],
|
|
19
|
+
[data-theme="dark"] {
|
|
20
|
+
color-scheme: light;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Default palette — "ink & terra": aubergine primary, terracotta secondary,
|
|
25
|
+
pigment-toned statuses (sage, ochre, brick) tuned to equal perceived weight.
|
|
26
|
+
The neutral ramp (text, borders, subtle surfaces) is tinted toward the
|
|
27
|
+
primary hue (~260) so the whole page carries the identity, quietly. */
|
|
28
|
+
|
|
29
|
+
/* Light fallback — also the default on browsers without light-dark() support. */
|
|
30
|
+
:root,
|
|
31
|
+
[data-theme="light"] {
|
|
32
|
+
/* Intent colors */
|
|
33
|
+
--primary: hsl(268 32% 33%);
|
|
34
|
+
--primary-fg: hsl(0 0% 98%);
|
|
35
|
+
|
|
36
|
+
--secondary: hsl(16 38% 38%);
|
|
37
|
+
--secondary-fg: hsl(0 0% 98%);
|
|
38
|
+
|
|
39
|
+
--success: hsl(150 40% 31%);
|
|
40
|
+
--success-fg: hsl(0 0% 98%);
|
|
41
|
+
|
|
42
|
+
--warning: hsl(36 68% 34%);
|
|
43
|
+
--warning-fg: hsl(0 0% 98%);
|
|
44
|
+
|
|
45
|
+
--danger: hsl(5 58% 43%);
|
|
46
|
+
--danger-fg: hsl(0 0% 98%);
|
|
47
|
+
|
|
48
|
+
--neutral: hsl(258 7% 43%);
|
|
49
|
+
--neutral-fg: hsl(0 0% 98%);
|
|
50
|
+
|
|
51
|
+
/* Surfaces */
|
|
52
|
+
--surface: hsl(0 0% 100%);
|
|
53
|
+
--surface-raised: hsl(0 0% 100%);
|
|
54
|
+
--surface-subtle: hsl(262 24% 96%);
|
|
55
|
+
--surface-solid: hsl(261 16% 13%);
|
|
56
|
+
|
|
57
|
+
/* Text */
|
|
58
|
+
--text: hsl(261 20% 13%);
|
|
59
|
+
--text-muted: hsl(259 9% 42%);
|
|
60
|
+
--text-subtle: hsl(258 7% 57%);
|
|
61
|
+
|
|
62
|
+
/* Lines and focus */
|
|
63
|
+
--border: hsl(260 15% 88%);
|
|
64
|
+
--focus: var(--primary);
|
|
65
|
+
/* Pre-color-mix fallback only — superseded below by a derivation from
|
|
66
|
+
--focus so overriding --primary/--focus never leaves a stale ring. */
|
|
67
|
+
--focus-ring: hsl(268 32% 33% / 0.22);
|
|
68
|
+
--focus-ring-shadow: 0 0 0 3px var(--focus-ring);
|
|
69
|
+
--hover-overlay: hsl(260 20% 10% / 0.04);
|
|
70
|
+
|
|
71
|
+
/* Radius scale — themes may override the whole scale (e.g. [data-theme="square"]) */
|
|
72
|
+
--radius: 0.5rem;
|
|
73
|
+
--radius-sm: 0.25rem;
|
|
74
|
+
--radius-lg: 0.75rem;
|
|
75
|
+
|
|
76
|
+
/* Shadow color — consumed by --shadow / --shadow-popout in tokens.css */
|
|
77
|
+
--shadow-color: hsl(260 25% 10%);
|
|
78
|
+
|
|
79
|
+
/* Heading and selection — derived from theme color tokens */
|
|
80
|
+
--heading: var(--text);
|
|
81
|
+
--selection-bg: var(--primary);
|
|
82
|
+
--selection-fg: var(--primary-fg);
|
|
83
|
+
|
|
84
|
+
/* hgroup internal gap */
|
|
85
|
+
--hgroup-gap: 0.25em;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Tone subsystem — fixed-backdrop foreground for components placed over media
|
|
89
|
+
or other surfaces outside the theme token stack. Use data-theme islands for
|
|
90
|
+
full dark/light subtree inversion. */
|
|
91
|
+
[data-tone="dark"] {
|
|
92
|
+
--tone-fg: white;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
[data-tone="light"] {
|
|
96
|
+
--tone-fg: var(--text);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Focus ring derivation — color-mix tier. Runs whether or not light-dark()
|
|
100
|
+
is also supported, so it covers the color-mix-without-light-dark browser
|
|
101
|
+
tier on its own; the light-dark block below refines it further with the
|
|
102
|
+
light/dark alpha split once both features are available. Deriving from
|
|
103
|
+
--focus (not a literal) means overriding --primary/--focus, in the
|
|
104
|
+
default theme or any custom one, keeps the ring in sync automatically. */
|
|
105
|
+
@supports (color: color-mix(in oklch, red, white)) {
|
|
106
|
+
:root,
|
|
107
|
+
[data-theme="light"],
|
|
108
|
+
[data-theme="dark"] {
|
|
109
|
+
--focus-ring: color-mix(in oklch, var(--focus) 22%, transparent);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* Auto dark mode via light-dark(). Resolves based on the element's color-scheme:
|
|
114
|
+
:root (light dark) follows the OS, [data-theme="light"] forces light,
|
|
115
|
+
[data-theme="dark"] forces dark by overriding color-scheme.
|
|
116
|
+
Dark pastels sit a little lower and more chromatic (L 70-76, sat 38-45)
|
|
117
|
+
than usual so the palette stays warm rather than washed gray. */
|
|
118
|
+
@supports (color: light-dark(red, blue)) {
|
|
119
|
+
:root,
|
|
120
|
+
[data-theme="light"] {
|
|
121
|
+
--primary: light-dark(hsl(268 32% 33%), hsl(268 42% 76%));
|
|
122
|
+
--primary-fg: light-dark(hsl(0 0% 98%), hsl(268 30% 12%));
|
|
123
|
+
|
|
124
|
+
--secondary: light-dark(hsl(16 38% 38%), hsl(18 45% 72%));
|
|
125
|
+
--secondary-fg: light-dark(hsl(0 0% 98%), hsl(18 32% 11%));
|
|
126
|
+
|
|
127
|
+
--success: light-dark(hsl(150 40% 31%), hsl(150 38% 62%));
|
|
128
|
+
--success-fg: light-dark(hsl(0 0% 98%), hsl(150 35% 8%));
|
|
129
|
+
|
|
130
|
+
--warning: light-dark(hsl(36 68% 34%), hsl(40 62% 64%));
|
|
131
|
+
--warning-fg: light-dark(hsl(0 0% 98%), hsl(38 35% 10%));
|
|
132
|
+
|
|
133
|
+
--danger: light-dark(hsl(5 58% 43%), hsl(4 60% 70%));
|
|
134
|
+
--danger-fg: light-dark(hsl(0 0% 98%), hsl(4 35% 10%));
|
|
135
|
+
|
|
136
|
+
--neutral: light-dark(hsl(258 7% 43%), hsl(258 10% 72%));
|
|
137
|
+
--neutral-fg: light-dark(hsl(0 0% 98%), hsl(260 18% 10%));
|
|
138
|
+
|
|
139
|
+
--surface: light-dark(hsl(0 0% 100%), hsl(263 17% 9%));
|
|
140
|
+
--surface-raised: light-dark(hsl(0 0% 100%), hsl(263 15% 12%));
|
|
141
|
+
--surface-subtle: light-dark(hsl(262 24% 96%), hsl(263 13% 16%));
|
|
142
|
+
--surface-solid: light-dark(hsl(261 16% 13%), hsl(0 0% 96%));
|
|
143
|
+
|
|
144
|
+
--text: light-dark(hsl(261 20% 13%), hsl(260 12% 95%));
|
|
145
|
+
--text-muted: light-dark(hsl(259 9% 42%), hsl(259 9% 67%));
|
|
146
|
+
--text-subtle: light-dark(hsl(258 7% 57%), hsl(258 7% 54%));
|
|
147
|
+
|
|
148
|
+
--border: light-dark(hsl(260 15% 88%), hsl(262 12% 24%));
|
|
149
|
+
--focus-ring: light-dark(hsl(268 32% 33% / 0.22), hsl(268 42% 76% / 0.28));
|
|
150
|
+
--hover-overlay: light-dark(hsl(260 20% 10% / 0.04), hsl(0 0% 100% / 0.06));
|
|
151
|
+
--shadow-color: light-dark(hsl(260 25% 10%), hsl(262 40% 2%));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@supports (color: color-mix(in oklch, red, white)) and (color: light-dark(red, blue)) {
|
|
156
|
+
:root,
|
|
157
|
+
[data-theme="light"] {
|
|
158
|
+
--focus-ring: light-dark(
|
|
159
|
+
color-mix(in oklch, var(--focus) 22%, transparent),
|
|
160
|
+
color-mix(in oklch, var(--focus) 28%, transparent)
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@media (forced-colors: active) {
|
|
166
|
+
:root,
|
|
167
|
+
[data-theme="light"],
|
|
168
|
+
[data-theme="dark"] {
|
|
169
|
+
--focus-outline: calc(var(--border-width) * 2) solid Highlight;
|
|
170
|
+
--focus-ring-shadow: none;
|
|
171
|
+
|
|
172
|
+
--backdrop-fill: Canvas;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@media (prefers-contrast: more) {
|
|
177
|
+
:root,
|
|
178
|
+
[data-theme="light"],
|
|
179
|
+
[data-theme="dark"] {
|
|
180
|
+
--border-width: 2px;
|
|
181
|
+
--focus-outline-offset: 3px;
|
|
182
|
+
--focus-ring-shadow: 0 0 0 4px var(--focus-ring);
|
|
183
|
+
--text-muted: var(--text);
|
|
184
|
+
--text-subtle: var(--text);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[data-theme="corporate"] {
|
|
2
|
+
color-scheme: light dark;
|
|
3
|
+
|
|
4
|
+
--primary: hsl(214 82% 44%);
|
|
5
|
+
--primary-fg: white;
|
|
6
|
+
--secondary: hsl(250 45% 48%);
|
|
7
|
+
--secondary-fg: white;
|
|
8
|
+
--success: hsl(152 62% 32%);
|
|
9
|
+
--success-fg: white;
|
|
10
|
+
--warning: hsl(40 94% 48%);
|
|
11
|
+
--warning-fg: hsl(35 30% 12%);
|
|
12
|
+
--danger: hsl(355 70% 50%);
|
|
13
|
+
--danger-fg: white;
|
|
14
|
+
--neutral: hsl(220 12% 42%);
|
|
15
|
+
--neutral-fg: white;
|
|
16
|
+
|
|
17
|
+
--surface: hsl(0 0% 100%);
|
|
18
|
+
--surface-raised: hsl(214 30% 98%);
|
|
19
|
+
--surface-subtle: hsl(214 35% 95%);
|
|
20
|
+
--surface-solid: hsl(220 24% 12%);
|
|
21
|
+
|
|
22
|
+
--text: hsl(220 24% 12%);
|
|
23
|
+
--text-muted: hsl(220 10% 42%);
|
|
24
|
+
--text-subtle: hsl(220 8% 55%);
|
|
25
|
+
|
|
26
|
+
--border: hsl(220 16% 86%);
|
|
27
|
+
--focus: var(--primary);
|
|
28
|
+
--focus-ring: hsl(214 82% 44% / 0.22);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@supports (color: light-dark(red, blue)) {
|
|
32
|
+
[data-theme="corporate"] {
|
|
33
|
+
--primary: light-dark(hsl(214 82% 44%), hsl(214 75% 80%));
|
|
34
|
+
--primary-fg: light-dark(white, hsl(214 30% 12%));
|
|
35
|
+
--secondary: light-dark(hsl(250 45% 48%), hsl(250 53% 80%));
|
|
36
|
+
--secondary-fg: light-dark(white, hsl(250 30% 12%));
|
|
37
|
+
--success: light-dark(hsl(152 62% 32%), hsl(152 70% 80%));
|
|
38
|
+
--success-fg: light-dark(white, hsl(152 30% 12%));
|
|
39
|
+
--warning: light-dark(hsl(40 94% 48%), hsl(40 75% 80%));
|
|
40
|
+
--warning-fg: light-dark(hsl(35 30% 12%), hsl(40 30% 12%));
|
|
41
|
+
--danger: light-dark(hsl(355 70% 50%), hsl(355 75% 80%));
|
|
42
|
+
--danger-fg: light-dark(white, hsl(355 30% 12%));
|
|
43
|
+
--neutral: light-dark(hsl(220 12% 42%), hsl(220 20% 80%));
|
|
44
|
+
--neutral-fg: light-dark(white, hsl(220 30% 12%));
|
|
45
|
+
|
|
46
|
+
--surface: light-dark(hsl(0 0% 100%), hsl(214 18% 8%));
|
|
47
|
+
--surface-raised: light-dark(hsl(214 30% 98%), hsl(214 16% 11%));
|
|
48
|
+
--surface-subtle: light-dark(hsl(214 35% 95%), hsl(214 14% 16%));
|
|
49
|
+
--surface-solid: light-dark(hsl(220 24% 12%), hsl(0 0% 96%));
|
|
50
|
+
|
|
51
|
+
--text: light-dark(hsl(220 24% 12%), hsl(0 0% 96%));
|
|
52
|
+
--text-muted: light-dark(hsl(220 10% 42%), hsl(214 8% 68%));
|
|
53
|
+
--text-subtle: light-dark(hsl(220 8% 55%), hsl(214 7% 55%));
|
|
54
|
+
|
|
55
|
+
--border: light-dark(hsl(220 16% 86%), hsl(214 12% 24%));
|
|
56
|
+
--focus-ring: light-dark(hsl(214 82% 44% / 0.22), hsl(214 75% 80% / 0.28));
|
|
57
|
+
--hover-overlay: light-dark(hsl(220 30% 10% / 0.04), hsl(0 0% 100% / 0.06));
|
|
58
|
+
--shadow-color: light-dark(hsl(220 30% 10%), hsl(0 0% 0%));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* Cyberpunk — light-only stress-test theme (single block, color-scheme: light,
|
|
2
|
+
* same shape as dark.css). Illustrative rather than production: it exists to
|
|
3
|
+
* prove the token contract survives an extreme spec — a saturated yellow
|
|
4
|
+
* canvas, near-black text and borders, dark-on-bright intent pairs, zero
|
|
5
|
+
* radius, 2px strokes, and hard offset shadows — without touching a single
|
|
6
|
+
* component rule. */
|
|
7
|
+
[data-theme="cyberpunk"] {
|
|
8
|
+
color-scheme: light;
|
|
9
|
+
|
|
10
|
+
/* Bright intents carry dark ink. Each -fg pair is hand-tuned: danger keeps
|
|
11
|
+
a light fg because saturated red is too dark for near-black text, and
|
|
12
|
+
neutral inverts the canvas (black chip, yellow text). */
|
|
13
|
+
--primary: hsl(330 100% 60%);
|
|
14
|
+
--primary-fg: hsl(330 100% 10%);
|
|
15
|
+
--secondary: hsl(187 100% 42%);
|
|
16
|
+
--secondary-fg: hsl(187 100% 8%);
|
|
17
|
+
--success: hsl(150 100% 35%);
|
|
18
|
+
--success-fg: hsl(150 100% 6%);
|
|
19
|
+
--warning: hsl(25 95% 50%);
|
|
20
|
+
--warning-fg: hsl(25 100% 8%);
|
|
21
|
+
--danger: hsl(0 85% 44%);
|
|
22
|
+
--danger-fg: hsl(0 0% 98%);
|
|
23
|
+
--neutral: hsl(56 30% 8%);
|
|
24
|
+
--neutral-fg: hsl(56 100% 55%);
|
|
25
|
+
|
|
26
|
+
/* Yellow canvas. Raised surfaces go paler instead of shadowed — elevation
|
|
27
|
+
is carried by the hard offset shadow below. */
|
|
28
|
+
--surface: hsl(56 100% 50%);
|
|
29
|
+
--surface-raised: hsl(54 100% 64%);
|
|
30
|
+
--surface-subtle: hsl(53 100% 80%);
|
|
31
|
+
--surface-solid: hsl(56 30% 8%);
|
|
32
|
+
|
|
33
|
+
--text: hsl(56 60% 6%);
|
|
34
|
+
--text-muted: hsl(56 25% 22%);
|
|
35
|
+
--text-subtle: hsl(56 14% 34%);
|
|
36
|
+
|
|
37
|
+
--border: hsl(56 60% 6%);
|
|
38
|
+
--focus: hsl(330 100% 42%);
|
|
39
|
+
--focus-ring: hsl(330 100% 42% / 0.3);
|
|
40
|
+
--hover-overlay: hsl(56 100% 8% / 0.08);
|
|
41
|
+
|
|
42
|
+
/* Structure: sharp corners, thick strokes, print-like offset shadows.
|
|
43
|
+
Overriding --shadow directly bypasses the color-mix shadow recipe in
|
|
44
|
+
tokens.css (themes load later, so these flat values win). */
|
|
45
|
+
--radius: 0;
|
|
46
|
+
--radius-sm: 0;
|
|
47
|
+
--radius-lg: 0;
|
|
48
|
+
--border-width: 2px;
|
|
49
|
+
--shadow: 0.25rem 0.25rem 0 hsl(56 60% 6%);
|
|
50
|
+
--shadow-popout: 0.25rem 0.25rem 0 hsl(56 60% 6%);
|
|
51
|
+
--shadow-color: hsl(56 60% 6%);
|
|
52
|
+
|
|
53
|
+
/* Soft surfaces mix against a saturated yellow, so the default recipe reads
|
|
54
|
+
as more yellow — pull more intent in for tints that stay legible. */
|
|
55
|
+
--soft-bg-mix: 78%;
|
|
56
|
+
--soft-border-mix: 40%;
|
|
57
|
+
|
|
58
|
+
--selection-bg: hsl(56 60% 6%);
|
|
59
|
+
--selection-fg: hsl(56 100% 50%);
|
|
60
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* Canonical dark theme. Single-block shape (color-scheme: dark only) — it
|
|
2
|
+
* does not adapt to prefers-color-scheme; opt in via [data-theme="dark"].
|
|
3
|
+
* dim.css is a darker variant with lifted surface tones. */
|
|
4
|
+
[data-theme="dark"] {
|
|
5
|
+
color-scheme: dark;
|
|
6
|
+
|
|
7
|
+
--primary: hsl(220 90% 66%);
|
|
8
|
+
--primary-fg: hsl(222 30% 8%);
|
|
9
|
+
--secondary: hsl(270 65% 70%);
|
|
10
|
+
--secondary-fg: hsl(270 30% 10%);
|
|
11
|
+
--success: hsl(145 55% 54%);
|
|
12
|
+
--success-fg: hsl(145 40% 8%);
|
|
13
|
+
--warning: hsl(38 92% 62%);
|
|
14
|
+
--warning-fg: hsl(35 35% 10%);
|
|
15
|
+
--danger: hsl(0 75% 66%);
|
|
16
|
+
--danger-fg: hsl(0 35% 10%);
|
|
17
|
+
--neutral: hsl(220 10% 72%);
|
|
18
|
+
--neutral-fg: hsl(222 24% 8%);
|
|
19
|
+
|
|
20
|
+
--surface: hsl(222 24% 8%);
|
|
21
|
+
--surface-raised: hsl(222 22% 11%);
|
|
22
|
+
--surface-subtle: hsl(222 18% 15%);
|
|
23
|
+
--surface-solid: hsl(0 0% 96%);
|
|
24
|
+
|
|
25
|
+
--text: hsl(0 0% 96%);
|
|
26
|
+
--text-muted: hsl(220 10% 68%);
|
|
27
|
+
--text-subtle: hsl(220 8% 55%);
|
|
28
|
+
--border: hsl(222 14% 24%);
|
|
29
|
+
--focus: var(--primary);
|
|
30
|
+
--focus-ring: hsl(220 90% 66% / 0.28);
|
|
31
|
+
--hover-overlay: hsl(0 0% 100% / 0.06);
|
|
32
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* Dim — a dark theme variant that lifts the surface tones up a few percentage
|
|
2
|
+
* points. Same shape as dark.css (dark-only, single block) so authors can drop
|
|
3
|
+
* it in when the canonical dark is too dense. Demonstrates how a theme can
|
|
4
|
+
* recolor the same token set without changing structure. */
|
|
5
|
+
[data-theme="dim"] {
|
|
6
|
+
color-scheme: dark;
|
|
7
|
+
|
|
8
|
+
--primary: hsl(210 92% 70%);
|
|
9
|
+
--primary-fg: hsl(218 28% 10%);
|
|
10
|
+
--secondary: hsl(270 70% 74%);
|
|
11
|
+
--secondary-fg: hsl(270 30% 10%);
|
|
12
|
+
--success: hsl(150 56% 58%);
|
|
13
|
+
--success-fg: hsl(150 38% 9%);
|
|
14
|
+
--warning: hsl(40 92% 64%);
|
|
15
|
+
--warning-fg: hsl(35 35% 10%);
|
|
16
|
+
--danger: hsl(0 74% 68%);
|
|
17
|
+
--danger-fg: hsl(0 35% 10%);
|
|
18
|
+
--neutral: hsl(220 10% 72%);
|
|
19
|
+
--neutral-fg: hsl(220 24% 10%);
|
|
20
|
+
|
|
21
|
+
--surface: hsl(220 20% 13%);
|
|
22
|
+
--surface-raised: hsl(220 18% 16%);
|
|
23
|
+
--surface-subtle: hsl(220 16% 20%);
|
|
24
|
+
--surface-solid: hsl(0 0% 96%);
|
|
25
|
+
|
|
26
|
+
--text: hsl(220 18% 94%);
|
|
27
|
+
--text-muted: hsl(220 10% 70%);
|
|
28
|
+
--text-subtle: hsl(220 8% 58%);
|
|
29
|
+
--border: hsl(220 12% 28%);
|
|
30
|
+
--focus: var(--primary);
|
|
31
|
+
--focus-ring: hsl(210 92% 70% / 0.28);
|
|
32
|
+
--hover-overlay: hsl(0 0% 100% / 0.06);
|
|
33
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/* Edge - paired light/dark theme that demonstrates component-local
|
|
2
|
+
* border-accent tokens. Buttons become surface controls with an
|
|
3
|
+
* intent-colored lower edge (.solid remains available when an action needs a
|
|
4
|
+
* filled treatment), text controls (input/textarea/select) pick up the same
|
|
5
|
+
* lower-edge accent via --control-border-block-end-*, alerts get an
|
|
6
|
+
* intent-colored leading flag via --alert-border-inline-start-*, and text
|
|
7
|
+
* controls and buttons both get a thinner, tighter focus outline than the
|
|
8
|
+
* shared recipe. */
|
|
9
|
+
[data-theme="edge"] {
|
|
10
|
+
color-scheme: light dark;
|
|
11
|
+
|
|
12
|
+
--primary: hsl(224 72% 42%);
|
|
13
|
+
--primary-fg: white;
|
|
14
|
+
--secondary: hsl(166 54% 30%);
|
|
15
|
+
--secondary-fg: white;
|
|
16
|
+
--success: hsl(145 46% 32%);
|
|
17
|
+
--success-fg: white;
|
|
18
|
+
--warning: hsl(36 80% 38%);
|
|
19
|
+
--warning-fg: hsl(34 35% 10%);
|
|
20
|
+
--danger: hsl(354 62% 46%);
|
|
21
|
+
--danger-fg: white;
|
|
22
|
+
--neutral: hsl(228 9% 42%);
|
|
23
|
+
--neutral-fg: white;
|
|
24
|
+
|
|
25
|
+
--surface: hsl(40 20% 99%);
|
|
26
|
+
--surface-raised: hsl(0 0% 100%);
|
|
27
|
+
--surface-subtle: hsl(220 24% 95%);
|
|
28
|
+
--surface-solid: hsl(228 26% 12%);
|
|
29
|
+
|
|
30
|
+
--text: hsl(228 24% 12%);
|
|
31
|
+
--text-muted: hsl(228 9% 42%);
|
|
32
|
+
--text-subtle: hsl(228 7% 56%);
|
|
33
|
+
|
|
34
|
+
--border: hsl(220 14% 86%);
|
|
35
|
+
--focus: var(--primary);
|
|
36
|
+
--focus-ring: hsl(224 72% 42% / 0.22);
|
|
37
|
+
--hover-overlay: hsl(228 30% 10% / 0.04);
|
|
38
|
+
|
|
39
|
+
--radius: 0.375rem;
|
|
40
|
+
--radius-sm: 0.25rem;
|
|
41
|
+
--radius-lg: 0.625rem;
|
|
42
|
+
|
|
43
|
+
--btn-default-bg: var(--surface-subtle);
|
|
44
|
+
--btn-default-border: transparent;
|
|
45
|
+
--btn-border-color: transparent;
|
|
46
|
+
--btn-border-block-end-width: 2px;
|
|
47
|
+
|
|
48
|
+
--control-border-block-end-color: var(--primary);
|
|
49
|
+
--control-border-block-end-width: 2px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Intent-dependent button tokens must resolve on the button itself. If these
|
|
53
|
+
live on [data-theme], var(--intent) computes before local intent classes
|
|
54
|
+
apply and every button keeps the same primary edge. */
|
|
55
|
+
[data-theme="edge"] .btn:not(.link) {
|
|
56
|
+
--btn-border-block-end-color: var(--intent, var(--primary));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
[data-theme="edge"] .btn:not(:where(.solid, .soft, .outline, .ghost, .link)) {
|
|
60
|
+
--btn-default-fg: var(--intent, var(--text));
|
|
61
|
+
--ui-hover-bg: var(--surface-raised);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@media (hover: hover) {
|
|
65
|
+
[data-theme="edge"]
|
|
66
|
+
.btn:not(
|
|
67
|
+
:where(:disabled, [aria-disabled="true"], .solid, .soft, .outline, .ghost, .link)
|
|
68
|
+
):hover {
|
|
69
|
+
box-shadow: none;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Intent-dependent alert token, same reasoning as the button rule above:
|
|
74
|
+
must resolve on the alert itself so local intent classes (.danger, etc.)
|
|
75
|
+
win over the bare --primary fallback. */
|
|
76
|
+
[data-theme="edge"] .alert {
|
|
77
|
+
--alert-border-inline-start-color: var(--intent, var(--primary));
|
|
78
|
+
--alert-border-inline-start-width: 4px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Focus recipe override — the base recipe (control.css) flips --control-border
|
|
82
|
+
to --focus on top of the outline + ring, which triples up with the lower-edge
|
|
83
|
+
accent already visible here. Edge drops the border-color flip and thickens
|
|
84
|
+
the accent edge instead; the ring stays untouched. */
|
|
85
|
+
[data-theme="edge"] :is(.input, .textarea, .select):focus-visible {
|
|
86
|
+
--control-border: var(--border);
|
|
87
|
+
--control-border-block-end-width: 3px;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* The shared 2px-solid/2px-offset outline reads as a second ring on top of
|
|
91
|
+
the accent edge (inputs) or the box-shadow ring (buttons). Edge thins both
|
|
92
|
+
to the border width and tightens the offset so the outline hugs the
|
|
93
|
+
control instead of floating a second halo around it. Gated outside
|
|
94
|
+
forced-colors so that mode's Highlight-colored --focus-outline (theme.css)
|
|
95
|
+
stays in charge for inputs — a direct property on the element would
|
|
96
|
+
otherwise out-specificity that fallback regardless of the media condition
|
|
97
|
+
it was declared under. Buttons don't consume --focus-outline (they compute
|
|
98
|
+
their own outline so it can use --btn-focus-color's intent awareness), so
|
|
99
|
+
they get their own local width token, --btn-focus-outline-width. */
|
|
100
|
+
@media not (forced-colors: active) {
|
|
101
|
+
[data-theme="edge"] :is(.input, .textarea, .select, .btn) {
|
|
102
|
+
--focus-outline-offset: 1px;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
[data-theme="edge"] :is(.input, .textarea, .select) {
|
|
106
|
+
--focus-outline: var(--border-width) solid var(--focus);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
[data-theme="edge"] .btn {
|
|
110
|
+
--btn-focus-outline-width: var(--border-width);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@supports (color: light-dark(red, blue)) {
|
|
115
|
+
[data-theme="edge"] {
|
|
116
|
+
--primary: light-dark(hsl(224 72% 42%), hsl(220 80% 76%));
|
|
117
|
+
--primary-fg: light-dark(white, hsl(224 35% 10%));
|
|
118
|
+
--secondary: light-dark(hsl(166 54% 30%), hsl(166 58% 70%));
|
|
119
|
+
--secondary-fg: light-dark(white, hsl(166 35% 9%));
|
|
120
|
+
--success: light-dark(hsl(145 46% 32%), hsl(145 48% 64%));
|
|
121
|
+
--success-fg: light-dark(white, hsl(145 35% 8%));
|
|
122
|
+
--warning: light-dark(hsl(36 80% 38%), hsl(40 72% 66%));
|
|
123
|
+
--warning-fg: light-dark(hsl(34 35% 10%), hsl(38 35% 10%));
|
|
124
|
+
--danger: light-dark(hsl(354 62% 46%), hsl(354 66% 72%));
|
|
125
|
+
--danger-fg: light-dark(white, hsl(354 35% 10%));
|
|
126
|
+
--neutral: light-dark(hsl(228 9% 42%), hsl(228 12% 72%));
|
|
127
|
+
--neutral-fg: light-dark(white, hsl(228 24% 10%));
|
|
128
|
+
|
|
129
|
+
--surface: light-dark(hsl(40 20% 99%), hsl(228 20% 8%));
|
|
130
|
+
--surface-raised: light-dark(hsl(0 0% 100%), hsl(228 17% 11%));
|
|
131
|
+
--surface-subtle: light-dark(hsl(220 24% 95%), hsl(228 14% 16%));
|
|
132
|
+
--surface-solid: light-dark(hsl(228 26% 12%), hsl(0 0% 96%));
|
|
133
|
+
|
|
134
|
+
--text: light-dark(hsl(228 24% 12%), hsl(0 0% 96%));
|
|
135
|
+
--text-muted: light-dark(hsl(228 9% 42%), hsl(228 8% 68%));
|
|
136
|
+
--text-subtle: light-dark(hsl(228 7% 56%), hsl(228 7% 55%));
|
|
137
|
+
|
|
138
|
+
--border: light-dark(hsl(220 14% 86%), hsl(228 12% 24%));
|
|
139
|
+
--focus-ring: light-dark(hsl(224 72% 42% / 0.22), hsl(220 80% 76% / 0.28));
|
|
140
|
+
--hover-overlay: light-dark(hsl(228 30% 10% / 0.04), hsl(0 0% 100% / 0.06));
|
|
141
|
+
--shadow-color: light-dark(hsl(228 30% 10%), hsl(0 0% 0%));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[data-theme="forest"] {
|
|
2
|
+
color-scheme: light dark;
|
|
3
|
+
|
|
4
|
+
--primary: hsl(175 48% 26%);
|
|
5
|
+
--primary-fg: white;
|
|
6
|
+
--secondary: hsl(82 42% 34%);
|
|
7
|
+
--secondary-fg: white;
|
|
8
|
+
--success: hsl(148 58% 32%);
|
|
9
|
+
--success-fg: white;
|
|
10
|
+
--warning: hsl(42 88% 48%);
|
|
11
|
+
--warning-fg: hsl(35 35% 12%);
|
|
12
|
+
--danger: hsl(4 62% 48%);
|
|
13
|
+
--danger-fg: white;
|
|
14
|
+
--neutral: hsl(120 10% 34%);
|
|
15
|
+
--neutral-fg: white;
|
|
16
|
+
|
|
17
|
+
--surface: hsl(48 36% 96%);
|
|
18
|
+
--surface-raised: hsl(45 36% 98%);
|
|
19
|
+
--surface-subtle: hsl(112 26% 91%);
|
|
20
|
+
--surface-solid: hsl(130 22% 15%);
|
|
21
|
+
|
|
22
|
+
--text: hsl(130 20% 14%);
|
|
23
|
+
--text-muted: hsl(125 10% 38%);
|
|
24
|
+
--text-subtle: hsl(125 8% 50%);
|
|
25
|
+
|
|
26
|
+
--border: hsl(105 18% 78%);
|
|
27
|
+
--focus: var(--primary);
|
|
28
|
+
--focus-ring: hsl(175 48% 26% / 0.22);
|
|
29
|
+
|
|
30
|
+
/* Organic rounding — demonstrates scaling the radius tokens up. */
|
|
31
|
+
--radius: 0.75rem;
|
|
32
|
+
--radius-sm: 0.5rem;
|
|
33
|
+
--radius-lg: 1.25rem;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@supports (color: light-dark(red, blue)) {
|
|
37
|
+
[data-theme="forest"] {
|
|
38
|
+
--primary: light-dark(hsl(175 48% 26%), hsl(175 45% 76%));
|
|
39
|
+
--primary-fg: light-dark(white, hsl(175 30% 12%));
|
|
40
|
+
--secondary: light-dark(hsl(82 42% 34%), hsl(82 50% 80%));
|
|
41
|
+
--secondary-fg: light-dark(white, hsl(82 30% 12%));
|
|
42
|
+
--success: light-dark(hsl(148 58% 32%), hsl(148 66% 80%));
|
|
43
|
+
--success-fg: light-dark(white, hsl(148 30% 12%));
|
|
44
|
+
--warning: light-dark(hsl(42 88% 48%), hsl(42 75% 80%));
|
|
45
|
+
--warning-fg: light-dark(hsl(35 35% 12%), hsl(42 30% 12%));
|
|
46
|
+
--danger: light-dark(hsl(4 62% 48%), hsl(4 70% 80%));
|
|
47
|
+
--danger-fg: light-dark(white, hsl(4 30% 12%));
|
|
48
|
+
--neutral: light-dark(hsl(120 10% 34%), hsl(120 18% 80%));
|
|
49
|
+
--neutral-fg: light-dark(white, hsl(120 30% 12%));
|
|
50
|
+
|
|
51
|
+
--surface: light-dark(hsl(48 36% 96%), hsl(130 18% 8%));
|
|
52
|
+
--surface-raised: light-dark(hsl(45 36% 98%), hsl(130 16% 11%));
|
|
53
|
+
--surface-subtle: light-dark(hsl(112 26% 91%), hsl(130 14% 16%));
|
|
54
|
+
--surface-solid: light-dark(hsl(130 22% 15%), hsl(0 0% 96%));
|
|
55
|
+
|
|
56
|
+
--text: light-dark(hsl(130 20% 14%), hsl(0 0% 96%));
|
|
57
|
+
--text-muted: light-dark(hsl(125 10% 38%), hsl(130 8% 68%));
|
|
58
|
+
--text-subtle: light-dark(hsl(125 8% 50%), hsl(130 7% 55%));
|
|
59
|
+
|
|
60
|
+
--border: light-dark(hsl(105 18% 78%), hsl(130 12% 24%));
|
|
61
|
+
--focus-ring: light-dark(hsl(175 48% 26% / 0.22), hsl(175 45% 76% / 0.28));
|
|
62
|
+
--hover-overlay: light-dark(hsl(220 30% 10% / 0.04), hsl(0 0% 100% / 0.06));
|
|
63
|
+
--shadow-color: light-dark(hsl(220 30% 10%), hsl(0 0% 0%));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/* Gradient — paired light/dark theme, palette inspired by Bootstrap 4's
|
|
2
|
+
* defaults. Demonstrates that a solid button can be given the classic
|
|
3
|
+
* Bootstrap 4 gradient treatment (a 15%-white-lightened top fading to the
|
|
4
|
+
* flat intent color) purely through token overrides, without touching
|
|
5
|
+
* button.css. Only bare/.solid buttons are targeted — .soft/.outline/.ghost/
|
|
6
|
+
* .link stay flat, matching Bootstrap 4's own gradient mixin, which only
|
|
7
|
+
* wraps its filled button variant. */
|
|
8
|
+
[data-theme="gradient"] {
|
|
9
|
+
color-scheme: light dark;
|
|
10
|
+
|
|
11
|
+
--primary: hsl(211 100% 50%);
|
|
12
|
+
--primary-fg: white;
|
|
13
|
+
--secondary: hsl(208 7% 46%);
|
|
14
|
+
--secondary-fg: white;
|
|
15
|
+
--success: hsl(134 61% 41%);
|
|
16
|
+
--success-fg: white;
|
|
17
|
+
--warning: hsl(45 100% 51%);
|
|
18
|
+
--warning-fg: hsl(45 100% 10%);
|
|
19
|
+
--danger: hsl(354 70% 54%);
|
|
20
|
+
--danger-fg: white;
|
|
21
|
+
--neutral: hsl(210 10% 23%);
|
|
22
|
+
--neutral-fg: white;
|
|
23
|
+
|
|
24
|
+
--surface: hsl(0 0% 100%);
|
|
25
|
+
--surface-raised: hsl(0 0% 100%);
|
|
26
|
+
--surface-subtle: hsl(210 17% 95%);
|
|
27
|
+
--surface-solid: hsl(210 10% 15%);
|
|
28
|
+
|
|
29
|
+
--text: hsl(210 11% 15%);
|
|
30
|
+
--text-muted: hsl(208 7% 46%);
|
|
31
|
+
--text-subtle: hsl(210 9% 62%);
|
|
32
|
+
|
|
33
|
+
--border: hsl(210 14% 89%);
|
|
34
|
+
--focus: var(--primary);
|
|
35
|
+
--focus-ring: hsl(211 100% 50% / 0.25);
|
|
36
|
+
--hover-overlay: hsl(210 30% 10% / 0.04);
|
|
37
|
+
|
|
38
|
+
--radius: 0.25rem;
|
|
39
|
+
--radius-sm: 0.2rem;
|
|
40
|
+
--radius-lg: 0.3rem;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@supports (color: light-dark(red, blue)) {
|
|
44
|
+
[data-theme="gradient"] {
|
|
45
|
+
--primary: light-dark(hsl(211 100% 50%), hsl(211 90% 72%));
|
|
46
|
+
--primary-fg: light-dark(white, hsl(211 40% 10%));
|
|
47
|
+
--secondary: light-dark(hsl(208 7% 46%), hsl(208 10% 72%));
|
|
48
|
+
--secondary-fg: light-dark(white, hsl(208 15% 10%));
|
|
49
|
+
--success: light-dark(hsl(134 61% 41%), hsl(134 55% 65%));
|
|
50
|
+
--success-fg: light-dark(white, hsl(134 40% 8%));
|
|
51
|
+
--warning: light-dark(hsl(45 100% 51%), hsl(45 90% 70%));
|
|
52
|
+
--warning-fg: light-dark(hsl(45 100% 10%), hsl(45 100% 10%));
|
|
53
|
+
--danger: light-dark(hsl(354 70% 54%), hsl(354 75% 74%));
|
|
54
|
+
--danger-fg: light-dark(white, hsl(354 40% 10%));
|
|
55
|
+
--neutral: light-dark(hsl(210 10% 23%), hsl(210 12% 75%));
|
|
56
|
+
--neutral-fg: light-dark(white, hsl(210 15% 10%));
|
|
57
|
+
|
|
58
|
+
--surface: light-dark(hsl(0 0% 100%), hsl(210 15% 8%));
|
|
59
|
+
--surface-raised: light-dark(hsl(0 0% 100%), hsl(210 13% 11%));
|
|
60
|
+
--surface-subtle: light-dark(hsl(210 17% 95%), hsl(210 12% 16%));
|
|
61
|
+
--surface-solid: light-dark(hsl(210 10% 15%), hsl(0 0% 96%));
|
|
62
|
+
|
|
63
|
+
--text: light-dark(hsl(210 11% 15%), hsl(0 0% 96%));
|
|
64
|
+
--text-muted: light-dark(hsl(208 7% 46%), hsl(210 8% 68%));
|
|
65
|
+
--text-subtle: light-dark(hsl(210 9% 62%), hsl(210 7% 55%));
|
|
66
|
+
|
|
67
|
+
--border: light-dark(hsl(210 14% 89%), hsl(210 12% 24%));
|
|
68
|
+
--focus-ring: light-dark(hsl(211 100% 50% / 0.25), hsl(211 90% 72% / 0.3));
|
|
69
|
+
--hover-overlay: light-dark(hsl(210 30% 10% / 0.04), hsl(0 0% 100% / 0.06));
|
|
70
|
+
--shadow-color: light-dark(hsl(210 30% 10%), hsl(0 0% 0%));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@supports (color: color-mix(in oklch, red, white)) {
|
|
75
|
+
/* Bootstrap 4 gradient recipe (linear-gradient(180deg, mix(white, $color,
|
|
76
|
+
15%), $color)) ported to the token contract. --ui-bg covers explicit
|
|
77
|
+
.solid; --btn-default-bg covers the bare/no-variant default. Bootstrap 4
|
|
78
|
+
still darkens the button on hover even with gradients enabled, so
|
|
79
|
+
--ui-hover-bg reruns the same recipe over a darkened base color instead
|
|
80
|
+
of reusing --ui-bg verbatim — the resting gradient shape survives, just
|
|
81
|
+
shifted darker, same as the flat color-mix darken variants.css uses for
|
|
82
|
+
hover on ungradiented themes. */
|
|
83
|
+
[data-theme="gradient"] .btn:not(:where(.soft, .outline, .ghost, .link)) {
|
|
84
|
+
--gradient-hover-color: color-mix(in oklch, var(--intent, var(--neutral)) 88%, black);
|
|
85
|
+
--ui-bg: linear-gradient(
|
|
86
|
+
180deg,
|
|
87
|
+
color-mix(in oklch, white 15%, var(--intent, var(--neutral))),
|
|
88
|
+
var(--intent, var(--neutral))
|
|
89
|
+
);
|
|
90
|
+
--btn-default-bg: var(--ui-bg);
|
|
91
|
+
--ui-hover-bg: linear-gradient(
|
|
92
|
+
180deg,
|
|
93
|
+
color-mix(in oklch, white 15%, var(--gradient-hover-color)),
|
|
94
|
+
var(--gradient-hover-color)
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|