@waveso/ui 0.5.0 → 0.7.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/README.md +152 -68
- package/dist/accordion.js +3 -3
- package/dist/accordion.js.map +1 -1
- package/dist/action-bar.js +2 -2
- package/dist/action-bar.js.map +1 -1
- package/dist/alert-dialog.js +4 -4
- package/dist/alert-dialog.js.map +1 -1
- package/dist/alert.js +5 -5
- package/dist/alert.js.map +1 -1
- package/dist/animate.d.ts.map +1 -1
- package/dist/animate.js +1 -2
- package/dist/animate.js.map +1 -1
- package/dist/autocomplete.js +8 -8
- package/dist/autocomplete.js.map +1 -1
- package/dist/avatar.js +5 -5
- package/dist/avatar.js.map +1 -1
- package/dist/badge.d.ts +1 -1
- package/dist/badge.d.ts.map +1 -1
- package/dist/badge.js +5 -6
- package/dist/badge.js.map +1 -1
- package/dist/breadcrumb.js +3 -3
- package/dist/breadcrumb.js.map +1 -1
- package/dist/button-group.js +5 -5
- package/dist/button-group.js.map +1 -1
- package/dist/button.d.ts +2 -2
- package/dist/button.d.ts.map +1 -1
- package/dist/button.js +9 -10
- package/dist/button.js.map +1 -1
- package/dist/card.js +4 -4
- package/dist/card.js.map +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/combobox.d.ts.map +1 -1
- package/dist/combobox.js +10 -10
- package/dist/combobox.js.map +1 -1
- package/dist/context-menu.js +9 -9
- package/dist/context-menu.js.map +1 -1
- package/dist/dialog.d.ts.map +1 -1
- package/dist/dialog.js +4 -4
- package/dist/dialog.js.map +1 -1
- package/dist/drawer.js +4 -4
- package/dist/drawer.js.map +1 -1
- package/dist/field.js +2 -2
- package/dist/field.js.map +1 -1
- package/dist/form.js +2 -2
- package/dist/form.js.map +1 -1
- package/dist/infinite-scroll.js +2 -2
- package/dist/infinite-scroll.js.map +1 -1
- package/dist/input-group.d.ts +1 -1
- package/dist/input-group.js +5 -5
- package/dist/input-group.js.map +1 -1
- package/dist/input-otp.js +3 -3
- package/dist/input-otp.js.map +1 -1
- package/dist/input.js +1 -1
- package/dist/input.js.map +1 -1
- package/dist/item.d.ts +1 -1
- package/dist/item.js +4 -4
- package/dist/item.js.map +1 -1
- package/dist/kbd.js +1 -1
- package/dist/kbd.js.map +1 -1
- package/dist/menu.js +9 -9
- package/dist/menu.js.map +1 -1
- package/dist/menubar.js +1 -1
- package/dist/menubar.js.map +1 -1
- package/dist/popover.js +2 -2
- package/dist/popover.js.map +1 -1
- package/dist/preview-card.js +1 -1
- package/dist/preview-card.js.map +1 -1
- package/dist/progress.js +2 -2
- package/dist/progress.js.map +1 -1
- package/dist/radio.js +2 -2
- package/dist/radio.js.map +1 -1
- package/dist/scroll-area.js +2 -2
- package/dist/scroll-area.js.map +1 -1
- package/dist/select.js +8 -8
- package/dist/select.js.map +1 -1
- package/dist/separator.js +1 -1
- package/dist/separator.js.map +1 -1
- package/dist/sidebar.js +19 -19
- package/dist/sidebar.js.map +1 -1
- package/dist/skeleton.js +1 -1
- package/dist/skeleton.js.map +1 -1
- package/dist/slider.js +2 -2
- package/dist/slider.js.map +1 -1
- package/dist/styles.css +493 -202
- package/dist/switch.js +2 -2
- package/dist/switch.js.map +1 -1
- package/dist/table.js +5 -5
- package/dist/table.js.map +1 -1
- package/dist/tabs.js +3 -3
- package/dist/tabs.js.map +1 -1
- package/dist/textarea.js +1 -1
- package/dist/textarea.js.map +1 -1
- package/dist/toast.d.ts +3 -3
- package/dist/toast.d.ts.map +1 -1
- package/dist/toast.js +37 -10
- package/dist/toast.js.map +1 -1
- package/dist/toggle-group.js +2 -2
- package/dist/toggle-group.js.map +1 -1
- package/dist/toggle.js +3 -3
- package/dist/toggle.js.map +1 -1
- package/dist/tooltip.js +1 -1
- package/dist/tooltip.js.map +1 -1
- package/package.json +9 -20
package/dist/styles.css
CHANGED
|
@@ -6,16 +6,12 @@
|
|
|
6
6
|
* @import 'tailwindcss';
|
|
7
7
|
* @import '@waveso/ui/styles.css';
|
|
8
8
|
*
|
|
9
|
-
* This brings the `
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* This brings the `dark` variant, every theme token (override in your own
|
|
10
|
+
* :root / .dark), motion tokens + recipes, the few self-hosted keyframe
|
|
11
|
+
* utilities the components need, and the `@source` rule. No other
|
|
12
|
+
* library-related imports needed — zero runtime dependencies.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
/* Keyframe animation utilities used by popup components
|
|
16
|
-
* (`data-open:animate-in`, `fade-in-0`, `zoom-in-95`, etc.). */
|
|
17
|
-
@import "tw-animate-css";
|
|
18
|
-
|
|
19
15
|
/* Auto-register component source files so Tailwind generates CSS for all
|
|
20
16
|
* utility classes used by @waveso/ui components. Resolves relative to this
|
|
21
17
|
* file's location in node_modules/@waveso/ui/dist/. */
|
|
@@ -29,56 +25,146 @@
|
|
|
29
25
|
* ------------------------------------------------------------------------- */
|
|
30
26
|
|
|
31
27
|
:root {
|
|
32
|
-
/*
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
--
|
|
42
|
-
--
|
|
43
|
-
--
|
|
44
|
-
--
|
|
45
|
-
--
|
|
46
|
-
--
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
--
|
|
50
|
-
--
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
28
|
+
/* ========================================================================
|
|
29
|
+
* Palettes — raw primitives. No `--color-` prefix on purpose: these live in
|
|
30
|
+
* `:root`, not `@theme`, so they generate NO utilities (no `bg-ion-300`).
|
|
31
|
+
* They're referenced by the semantic tokens below, never used directly.
|
|
32
|
+
* ====================================================================== */
|
|
33
|
+
|
|
34
|
+
/* Wave — brand ramp. 500 = Wave Blue #0074DE.
|
|
35
|
+
* A true cobalt signal: calm, trustable, solid, constant. */
|
|
36
|
+
--wave-50: #EEF8FF;
|
|
37
|
+
--wave-100: #D6EEFF;
|
|
38
|
+
--wave-200: #AEDDFF;
|
|
39
|
+
--wave-300: #7BC3FF;
|
|
40
|
+
--wave-400: #3EA3FF;
|
|
41
|
+
--wave-500: #0074DE;
|
|
42
|
+
--wave-600: #0061C6;
|
|
43
|
+
--wave-700: #004C9F;
|
|
44
|
+
--wave-800: #003976;
|
|
45
|
+
--wave-900: #042954;
|
|
46
|
+
--wave-950: #061C37;
|
|
47
|
+
|
|
48
|
+
/* ── Neutral theme palettes (primitives) ─────────────────────────────────
|
|
49
|
+
* Three complete neutral ramps, one per theme. The theme class on <html>
|
|
50
|
+
* wires the ACTIVE one into the `--ui-*` alias (step 2); the semantic layer
|
|
51
|
+
* reads `--ui-*`, never these directly. `--wave-*` (brand) is shared by all
|
|
52
|
+
* three. Default theme = Graphite.
|
|
53
|
+
* ──────────────────────────────────────────────────────────────────────── */
|
|
54
|
+
|
|
55
|
+
/* Graphite — neutral grey (default) */
|
|
56
|
+
--graphite-50: #FAFAFB;
|
|
57
|
+
--graphite-100: #F3F3F4;
|
|
58
|
+
--graphite-200: #E5E5E8;
|
|
59
|
+
--graphite-300: #D1D2D7;
|
|
60
|
+
--graphite-400: #ABACB2;
|
|
61
|
+
--graphite-500: #8B8C94;
|
|
62
|
+
--graphite-600: #6C6D76;
|
|
63
|
+
--graphite-700: #4C4D55;
|
|
64
|
+
--graphite-800: #3B3C44;
|
|
65
|
+
--graphite-900: #323339;
|
|
66
|
+
--graphite-950: #2C2D32;
|
|
67
|
+
|
|
68
|
+
/* Ink — deep navy surfaces, neutral-cool structure (page #020812, surface #050F1E).
|
|
69
|
+
* Chroma fades from full navy at the dark surfaces to near-neutral at the light
|
|
70
|
+
* end, so text/borders read as a distinct layer rather than melting into navy. */
|
|
71
|
+
--ink-50: #F2F4F6;
|
|
72
|
+
--ink-100: #DFE1E5;
|
|
73
|
+
--ink-200: #C5C9CE;
|
|
74
|
+
--ink-300: #AAAFB6;
|
|
75
|
+
--ink-400: #8C929A;
|
|
76
|
+
--ink-500: #6E747D;
|
|
77
|
+
--ink-600: #4F5763;
|
|
78
|
+
--ink-700: #323D4C;
|
|
79
|
+
--ink-800: #162336;
|
|
80
|
+
--ink-900: #050F1E;
|
|
81
|
+
--ink-950: #020812;
|
|
82
|
+
|
|
83
|
+
/* Paper — cool near-neutral (anchor #EFF0EB @ 200 = foundation) */
|
|
84
|
+
--paper-50: #FCFDFA;
|
|
85
|
+
--paper-100: #F6F7F3;
|
|
86
|
+
--paper-200: #EFF0EB;
|
|
87
|
+
--paper-300: #D7D8D2;
|
|
88
|
+
--paper-400: #AAACA5;
|
|
89
|
+
--paper-500: #83847D;
|
|
90
|
+
--paper-600: #63645E;
|
|
91
|
+
--paper-700: #494A44;
|
|
92
|
+
--paper-800: #30312C;
|
|
93
|
+
--paper-900: #1B1C18;
|
|
94
|
+
--paper-950: #0C0D09;
|
|
95
|
+
|
|
96
|
+
/* Active neutral alias — the theme class on <html> repoints these to one of
|
|
97
|
+
* the ramps above (step 3). Default (no theme class) = Graphite. The semantic
|
|
98
|
+
* layer below reads ONLY `--ui-*`; components never touch a ramp directly. */
|
|
99
|
+
--ui-50: var(--graphite-50);
|
|
100
|
+
--ui-100: var(--graphite-100);
|
|
101
|
+
--ui-200: var(--graphite-200);
|
|
102
|
+
--ui-300: var(--graphite-300);
|
|
103
|
+
--ui-400: var(--graphite-400);
|
|
104
|
+
--ui-500: var(--graphite-500);
|
|
105
|
+
--ui-600: var(--graphite-600);
|
|
106
|
+
--ui-700: var(--graphite-700);
|
|
107
|
+
--ui-800: var(--graphite-800);
|
|
108
|
+
--ui-900: var(--graphite-900);
|
|
109
|
+
--ui-950: var(--graphite-950);
|
|
110
|
+
|
|
111
|
+
/* ========================================================================
|
|
112
|
+
* Semantic tokens — light (default). The spec's `.light` block lives in
|
|
113
|
+
* `:root` so consumers get the light theme without needing a `.light` class.
|
|
114
|
+
* ====================================================================== */
|
|
115
|
+
|
|
116
|
+
/* Backgrounds = elevation */
|
|
117
|
+
--foundation: var(--ui-200);
|
|
118
|
+
--surface: var(--ui-100);
|
|
119
|
+
--elevated: var(--ui-50);
|
|
120
|
+
|
|
121
|
+
/* Contrast = emphasis — highest-contrast text → muted → soft. */
|
|
122
|
+
--contrast: var(--ui-950);
|
|
123
|
+
--muted: var(--ui-600);
|
|
124
|
+
--soft: var(--ui-500);
|
|
125
|
+
|
|
126
|
+
/* Inverse — an inverted neutral pair (e.g. the dark tooltip). Aliases, so
|
|
127
|
+
* they auto-flip with `.dark` (var() re-resolves at the use site). */
|
|
128
|
+
--surface-inverse: var(--contrast);
|
|
129
|
+
--contrast-inverse: var(--foundation);
|
|
130
|
+
|
|
131
|
+
/* Brand — `primary` wired to the Wave ramp; `secondary` is the neutral fill
|
|
132
|
+
* (secondary/ghost buttons, hovers, selected) at ion-300; `accent` is the
|
|
133
|
+
* bright signal (Wave Blue 300, the strand now-glow). No per-fill on-color
|
|
134
|
+
* tokens: text on the saturated fills is
|
|
135
|
+
* `text-white`, text on the neutral `secondary` is `text-contrast`. */
|
|
136
|
+
--primary: var(--wave-500);
|
|
137
|
+
--secondary: var(--ui-300);
|
|
138
|
+
--accent: var(--wave-300); /* the bright signal — the strand's "now" cursor glow */
|
|
139
|
+
|
|
140
|
+
/* Borders = structure — mixed from the ACTIVE palette so they auto-match
|
|
141
|
+
* every theme: a hairline of the darkest neutral in light mode. */
|
|
142
|
+
--line: color-mix(in srgb, var(--ui-950) 7%, transparent);
|
|
143
|
+
--edge: color-mix(in srgb, var(--ui-950) 14%, transparent);
|
|
144
|
+
--solid: var(--ui-300);
|
|
145
|
+
|
|
146
|
+
/* Rings = brand themed */
|
|
147
|
+
--focus: var(--primary);
|
|
148
|
+
|
|
149
|
+
/* Shadow — two dials for the layered `shadow-*` scale: `--shadow-color` (HSL
|
|
150
|
+
* components — a deep cool-tinted near-black, never pure #000 which reads
|
|
151
|
+
* heavy) and `--shadow-strength` (per-layer alpha / intensity). Both resolve
|
|
152
|
+
* per :root/.dark, so retinting OR dimming every shadow is one token. For a
|
|
153
|
+
* colored surface set a named tint, e.g. `--shadow-color-primary`. */
|
|
154
|
+
--shadow-color: 220deg 45% 6%;
|
|
155
|
+
--shadow-strength: 0.22;
|
|
54
156
|
|
|
55
157
|
/* Status */
|
|
56
|
-
--destructive: oklch(0.
|
|
57
|
-
--success: oklch(0.
|
|
58
|
-
--warning: oklch(0.
|
|
59
|
-
|
|
60
|
-
/* Charts */
|
|
61
|
-
--chart-1: oklch(0.809 0.105 251.813);
|
|
62
|
-
--chart-2: oklch(0.623 0.214 259.815);
|
|
63
|
-
--chart-3: oklch(0.546 0.245 262.881);
|
|
64
|
-
--chart-4: oklch(0.488 0.243 264.376);
|
|
65
|
-
--chart-5: oklch(0.424 0.199 265.638);
|
|
158
|
+
--destructive: oklch(0.620 0.200 25);
|
|
159
|
+
--success: oklch(0.710 0.185 155); /* cool emerald — distinct from the warning yellow, kept ownable (off the Apple/Tailwind default) */
|
|
160
|
+
--warning: oklch(0.830 0.156 93);
|
|
161
|
+
--info: var(--wave-500); /* the one blue — Wave Blue (= --primary / --focus) */
|
|
66
162
|
|
|
67
163
|
/* Presence */
|
|
68
|
-
--presence-online: oklch(0.
|
|
69
|
-
--presence-away: oklch(0.
|
|
70
|
-
--presence-busy: oklch(0.
|
|
71
|
-
--presence-invisible:
|
|
72
|
-
|
|
73
|
-
/* Sidebar */
|
|
74
|
-
--sidebar: oklch(0.985 0 0);
|
|
75
|
-
--sidebar-foreground: oklch(0.145 0 0);
|
|
76
|
-
--sidebar-primary: oklch(0.546 0.245 262.881);
|
|
77
|
-
--sidebar-primary-foreground: oklch(0.97 0.014 254.604);
|
|
78
|
-
--sidebar-accent: oklch(0.488 0.243 264.376);
|
|
79
|
-
--sidebar-accent-foreground: oklch(0.97 0.014 254.604);
|
|
80
|
-
--sidebar-border: oklch(0.922 0 0);
|
|
81
|
-
--sidebar-ring: oklch(0.708 0 0);
|
|
164
|
+
--presence-online: oklch(0.710 0.185 155); /* = success colour */
|
|
165
|
+
--presence-away: oklch(0.830 0.156 93); /* = warning colour */
|
|
166
|
+
--presence-busy: oklch(0.620 0.200 25); /* = destructive colour */
|
|
167
|
+
--presence-invisible: var(--foundation); /* invisible = the page itself; pair with a border so the dot reads as a hollow ring */
|
|
82
168
|
|
|
83
169
|
/* Radius */
|
|
84
170
|
--radius: 0.625rem;
|
|
@@ -96,15 +182,33 @@
|
|
|
96
182
|
* native / HIG behavior; real links keep their own pointer regardless. */
|
|
97
183
|
--cursor-clickable: pointer;
|
|
98
184
|
|
|
99
|
-
/* Motion — tokens consumed by the `motion-*` recipes (see Utilities).
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
185
|
+
/* Motion — tokens consumed by the `motion-*` recipes (see Utilities). Override
|
|
186
|
+
* any value in your own :root. `prefers-reduced-motion` zeroes them (bottom of
|
|
187
|
+
* file), so every recipe collapses safely.
|
|
188
|
+
*
|
|
189
|
+
* THE SYSTEM — 5 scalable magnitudes × 3 tiers (sm/md/lg) + 1 fixed signature:
|
|
190
|
+
* scalable → --duration · --blur · --scale · --offset · --stagger
|
|
191
|
+
* fixed → --ease (the one curve — never tiered)
|
|
192
|
+
* tiers → sm = controls/icons · md = popups · lg = dialogs
|
|
193
|
+
* sm/lg zoom in place; md also slides. `--offset`/`--stagger` sm+lg are
|
|
194
|
+
* defined ahead of use (wired per surface as we build them out). */
|
|
195
|
+
--ease: cubic-bezier(0.22, 1, 0.36, 1); /* the one curve — never tiered */
|
|
196
|
+
|
|
197
|
+
--duration-sm: 150ms; /* controls, icons */
|
|
198
|
+
--duration-md: 200ms; /* popups */
|
|
199
|
+
--duration-lg: 250ms; /* dialogs */
|
|
200
|
+
--blur-sm: 2px;
|
|
201
|
+
--blur-md: 4px;
|
|
202
|
+
--blur-lg: 8px;
|
|
203
|
+
--scale-sm: 0.95;
|
|
204
|
+
--scale-md: 0.9;
|
|
205
|
+
--scale-lg: 0.85;
|
|
206
|
+
--offset-sm: 2px; /* item/icon nudge */
|
|
207
|
+
--offset-md: 4px; /* popup slide */
|
|
208
|
+
--offset-lg: 8px;
|
|
209
|
+
--stagger-sm: 30ms; /* list-item delay */
|
|
210
|
+
--stagger-md: 60ms;
|
|
211
|
+
--stagger-lg: 90ms;
|
|
108
212
|
}
|
|
109
213
|
|
|
110
214
|
/* ---------------------------------------------------------------------------
|
|
@@ -112,99 +216,110 @@
|
|
|
112
216
|
* ------------------------------------------------------------------------- */
|
|
113
217
|
|
|
114
218
|
.dark {
|
|
115
|
-
/*
|
|
116
|
-
--
|
|
117
|
-
--
|
|
118
|
-
--
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
--
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
--
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
--
|
|
133
|
-
--
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
219
|
+
/* Backgrounds = elevation */
|
|
220
|
+
--foundation: var(--ui-950);
|
|
221
|
+
--surface: var(--ui-900);
|
|
222
|
+
--elevated: var(--ui-800);
|
|
223
|
+
|
|
224
|
+
/* Contrast = emphasis */
|
|
225
|
+
--contrast: var(--ui-100);
|
|
226
|
+
--muted: var(--ui-400);
|
|
227
|
+
--soft: var(--ui-600);
|
|
228
|
+
|
|
229
|
+
/* Brand — only `secondary` differs from light; mirrored to ion-700 so the
|
|
230
|
+
* neutral fill stands out against the dark surfaces. primary / accent /
|
|
231
|
+
* inverse / focus auto-flip or stay constant via the `:root` definitions. */
|
|
232
|
+
--secondary: var(--ui-700);
|
|
233
|
+
|
|
234
|
+
/* Borders = structure — a hairline of the lightest neutral (auto-matches theme). */
|
|
235
|
+
--line: color-mix(in srgb, var(--ui-50) 5%, transparent);
|
|
236
|
+
--edge: color-mix(in srgb, var(--ui-50) 13%, transparent);
|
|
237
|
+
--solid: var(--ui-700);
|
|
238
|
+
|
|
239
|
+
/* Shadow — darker tint, lower strength: a near-black shadow on a dark
|
|
240
|
+
* surface reads heavier than on white, so dim it. */
|
|
241
|
+
--shadow-color: 220deg 40% 3%;
|
|
242
|
+
--shadow-strength: 0.18;
|
|
137
243
|
|
|
138
244
|
/* Status */
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
--
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
--
|
|
145
|
-
--chart-2: oklch(0.58 0.2 260);
|
|
146
|
-
--chart-3: oklch(0.5 0.22 263);
|
|
147
|
-
--chart-4: oklch(0.45 0.2 265);
|
|
148
|
-
--chart-5: oklch(0.38 0.17 266);
|
|
245
|
+
/* Slightly BRIGHTER than the :root (light) values.
|
|
246
|
+
* Never darker, or the colour recedes on dark surfaces (the old reversal bug). */
|
|
247
|
+
--destructive: oklch(0.630 0.200 25);
|
|
248
|
+
--success: oklch(0.735 0.185 155); /* green A, hue-aware lift (+.025) brighter than light */
|
|
249
|
+
--warning: oklch(0.850 0.156 93);
|
|
250
|
+
--info: var(--wave-400); /* brighter Wave Blue for legible text-info on dark surfaces */
|
|
149
251
|
|
|
150
252
|
/* Presence */
|
|
151
|
-
--presence-online: oklch(0.
|
|
152
|
-
--presence-away: oklch(0.
|
|
153
|
-
--presence-busy: oklch(0.
|
|
154
|
-
--presence-invisible:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
--
|
|
253
|
+
--presence-online: oklch(0.735 0.185 155); /* brighter on dark, like status */
|
|
254
|
+
--presence-away: oklch(0.850 0.156 93);
|
|
255
|
+
--presence-busy: oklch(0.630 0.200 25);
|
|
256
|
+
--presence-invisible: var(--foundation); /* re-declared so it re-resolves to the dark foundation */
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* ---------------------------------------------------------------------------
|
|
260
|
+
* Theme presets — each repoints the `--ui-*` alias to one neutral ramp. Put a
|
|
261
|
+
* class on a root element: `<html class="theme-paper">`. Graphite is also the bare
|
|
262
|
+
* `:root` default, so `theme-graphite` is optional/explicit. Light vs dark is the
|
|
263
|
+
* separate `.dark` axis — they compose (e.g. `class="theme-paper dark"`).
|
|
264
|
+
* ------------------------------------------------------------------------- */
|
|
265
|
+
.theme-graphite {
|
|
266
|
+
--ui-50: var(--graphite-50); --ui-100: var(--graphite-100); --ui-200: var(--graphite-200);
|
|
267
|
+
--ui-300: var(--graphite-300); --ui-400: var(--graphite-400); --ui-500: var(--graphite-500);
|
|
268
|
+
--ui-600: var(--graphite-600); --ui-700: var(--graphite-700); --ui-800: var(--graphite-800);
|
|
269
|
+
--ui-900: var(--graphite-900); --ui-950: var(--graphite-950);
|
|
270
|
+
}
|
|
271
|
+
.theme-ink {
|
|
272
|
+
--ui-50: var(--ink-50); --ui-100: var(--ink-100); --ui-200: var(--ink-200);
|
|
273
|
+
--ui-300: var(--ink-300); --ui-400: var(--ink-400); --ui-500: var(--ink-500);
|
|
274
|
+
--ui-600: var(--ink-600); --ui-700: var(--ink-700); --ui-800: var(--ink-800);
|
|
275
|
+
--ui-900: var(--ink-900); --ui-950: var(--ink-950);
|
|
276
|
+
}
|
|
277
|
+
.theme-paper {
|
|
278
|
+
--ui-50: var(--paper-50); --ui-100: var(--paper-100); --ui-200: var(--paper-200);
|
|
279
|
+
--ui-300: var(--paper-300); --ui-400: var(--paper-400); --ui-500: var(--paper-500);
|
|
280
|
+
--ui-600: var(--paper-600); --ui-700: var(--paper-700); --ui-800: var(--paper-800);
|
|
281
|
+
--ui-900: var(--paper-900); --ui-950: var(--paper-950);
|
|
165
282
|
}
|
|
166
283
|
|
|
167
284
|
/* ---------------------------------------------------------------------------
|
|
168
285
|
* Tailwind v4 theme mapping — maps CSS variables to Tailwind color tokens.
|
|
169
286
|
* Consumers MUST include this for Tailwind classes like `bg-primary`,
|
|
170
|
-
* `text-muted
|
|
287
|
+
* `text-muted`, `border-line` etc. to work.
|
|
171
288
|
* ------------------------------------------------------------------------- */
|
|
172
289
|
|
|
173
290
|
@theme inline {
|
|
174
|
-
/*
|
|
175
|
-
--color-
|
|
176
|
-
--color-
|
|
177
|
-
--color-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
--color-
|
|
181
|
-
|
|
182
|
-
|
|
291
|
+
/* Surfaces */
|
|
292
|
+
--color-foundation: var(--foundation);
|
|
293
|
+
--color-surface: var(--surface);
|
|
294
|
+
--color-elevated: var(--elevated);
|
|
295
|
+
|
|
296
|
+
/* Contrast / text — `contrast` (highest emphasis) → `muted` → `soft`. */
|
|
297
|
+
--color-contrast: var(--contrast);
|
|
298
|
+
--color-muted: var(--muted);
|
|
299
|
+
--color-soft: var(--soft);
|
|
300
|
+
|
|
301
|
+
/* Inverse — maps the `:root` inverse aliases to utilities. */
|
|
302
|
+
--color-surface-inverse: var(--surface-inverse);
|
|
303
|
+
--color-contrast-inverse: var(--contrast-inverse);
|
|
304
|
+
|
|
305
|
+
/* Brand — saturated fills use `text-white`, the neutral `secondary` uses
|
|
306
|
+
* `text-contrast`. No per-fill on-color tokens. */
|
|
183
307
|
--color-primary: var(--primary);
|
|
184
|
-
--color-primary-foreground: var(--primary-foreground);
|
|
185
308
|
--color-secondary: var(--secondary);
|
|
186
|
-
--color-secondary-foreground: var(--secondary-foreground);
|
|
187
309
|
--color-accent: var(--accent);
|
|
188
|
-
--color-accent-foreground: var(--accent-foreground);
|
|
189
310
|
|
|
190
|
-
/*
|
|
191
|
-
|
|
192
|
-
--color-
|
|
193
|
-
--color-
|
|
194
|
-
--color-
|
|
195
|
-
--color-
|
|
311
|
+
/* Structure — `line` (faint divider), `edge` (input border), `solid` (opaque
|
|
312
|
+
* border), `focus` (brand-themed ring = primary). */
|
|
313
|
+
--color-line: var(--line);
|
|
314
|
+
--color-edge: var(--edge);
|
|
315
|
+
--color-solid: var(--solid);
|
|
316
|
+
--color-focus: var(--focus);
|
|
196
317
|
|
|
197
318
|
/* Status */
|
|
198
319
|
--color-destructive: var(--destructive);
|
|
199
320
|
--color-success: var(--success);
|
|
200
321
|
--color-warning: var(--warning);
|
|
201
|
-
|
|
202
|
-
/* Charts */
|
|
203
|
-
--color-chart-1: var(--chart-1);
|
|
204
|
-
--color-chart-2: var(--chart-2);
|
|
205
|
-
--color-chart-3: var(--chart-3);
|
|
206
|
-
--color-chart-4: var(--chart-4);
|
|
207
|
-
--color-chart-5: var(--chart-5);
|
|
322
|
+
--color-info: var(--info);
|
|
208
323
|
|
|
209
324
|
/* Presence */
|
|
210
325
|
--color-presence-online: var(--presence-online);
|
|
@@ -212,25 +327,12 @@
|
|
|
212
327
|
--color-presence-busy: var(--presence-busy);
|
|
213
328
|
--color-presence-invisible: var(--presence-invisible);
|
|
214
329
|
|
|
215
|
-
/*
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
--
|
|
219
|
-
--
|
|
220
|
-
--
|
|
221
|
-
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
222
|
-
--color-sidebar-border: var(--sidebar-border);
|
|
223
|
-
--color-sidebar-ring: var(--sidebar-ring);
|
|
224
|
-
|
|
225
|
-
/* Radius */
|
|
226
|
-
--radius-xs: calc(var(--radius) - 6px);
|
|
227
|
-
--radius-sm: calc(var(--radius) - 4px);
|
|
228
|
-
--radius-md: calc(var(--radius) - 2px);
|
|
229
|
-
--radius-lg: var(--radius);
|
|
230
|
-
--radius-xl: calc(var(--radius) + 4px);
|
|
231
|
-
--radius-2xl: calc(var(--radius) + 8px);
|
|
232
|
-
--radius-3xl: calc(var(--radius) + 12px);
|
|
233
|
-
--radius-4xl: calc(var(--radius) + 16px);
|
|
330
|
+
/* Radius — 3-tier scale, spacing-aligned + concentric (outer = inner + one
|
|
331
|
+
* --spacing); synced 1:1 with the motion sm/md/lg tiers. `--spacing` is
|
|
332
|
+
* Tailwind-provided (0.25rem = 4px). */
|
|
333
|
+
--radius-sm: calc(var(--radius) - var(--spacing)); /* 6px — small controls */
|
|
334
|
+
--radius-md: var(--radius); /* 10px — default (buttons, inputs, menus, popovers) */
|
|
335
|
+
--radius-lg: calc(var(--radius) + var(--spacing)); /* 14px — large surfaces (dialogs, drawers, cards) */
|
|
234
336
|
|
|
235
337
|
/* Typography — passthroughs so consumers' `--font-sans` /
|
|
236
338
|
* `--font-mono` flow through to Tailwind's `font-sans` /
|
|
@@ -239,6 +341,31 @@
|
|
|
239
341
|
--font-mono: var(--font-mono);
|
|
240
342
|
}
|
|
241
343
|
|
|
344
|
+
/* Shadow scale — layered, tinted by `--shadow-color` and dimmed by
|
|
345
|
+
* `--shadow-strength` (both resolve per :root/.dark, so retinting or dimming
|
|
346
|
+
* every shadow is one token). Tiers differ by layer count + spread, not alpha.
|
|
347
|
+
* Overrides Tailwind's shadow-sm/md/lg. */
|
|
348
|
+
@theme {
|
|
349
|
+
--shadow-sm:
|
|
350
|
+
0px 0.5px 0.7px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
351
|
+
0px 0.8px 1px -1.2px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
352
|
+
0px 2px 2.5px -2.5px hsl(var(--shadow-color) / var(--shadow-strength));
|
|
353
|
+
--shadow-md:
|
|
354
|
+
0px 0.5px 0.7px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
355
|
+
0px 1.6px 2px -0.8px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
356
|
+
0px 4.1px 5.2px -1.7px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
357
|
+
0px 10px 12.6px -2.5px hsl(var(--shadow-color) / var(--shadow-strength));
|
|
358
|
+
--shadow-lg:
|
|
359
|
+
0px 0.5px 0.7px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
360
|
+
0px 2.9px 3.7px -0.4px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
361
|
+
0px 5.4px 6.8px -0.7px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
362
|
+
0px 8.9px 11.2px -1.1px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
363
|
+
0px 14.3px 18px -1.4px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
364
|
+
0px 22.3px 28.1px -1.8px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
365
|
+
0px 33.9px 42.7px -2.1px hsl(var(--shadow-color) / var(--shadow-strength)),
|
|
366
|
+
0px 50px 62.9px -2.5px hsl(var(--shadow-color) / var(--shadow-strength));
|
|
367
|
+
}
|
|
368
|
+
|
|
242
369
|
/* ---------------------------------------------------------------------------
|
|
243
370
|
* Utilities
|
|
244
371
|
* ------------------------------------------------------------------------- */
|
|
@@ -252,14 +379,14 @@
|
|
|
252
379
|
|
|
253
380
|
/* `motion-color` — interaction-state transition for controls: smoothly
|
|
254
381
|
* animates color / background / border / ring (box-shadow) on hover, focus,
|
|
255
|
-
* pressed, checked, etc.
|
|
256
|
-
* enter/exit recipes below win over
|
|
257
|
-
* button that also carries `motion-scale`). */
|
|
382
|
+
* pressed, checked, etc. Runs at the `sm` tier (controls are small + fast). A
|
|
383
|
+
* plain layered `@utility`, so the unlayered enter/exit recipes below win over
|
|
384
|
+
* it when both land on one element (e.g. a button that also carries `motion-scale-sm`). */
|
|
258
385
|
@utility motion-color {
|
|
259
|
-
transition: color var(--duration) var(--ease),
|
|
260
|
-
background-color var(--duration) var(--ease),
|
|
261
|
-
border-color var(--duration) var(--ease),
|
|
262
|
-
box-shadow var(--duration) var(--ease);
|
|
386
|
+
transition: color var(--duration-sm) var(--ease),
|
|
387
|
+
background-color var(--duration-sm) var(--ease),
|
|
388
|
+
border-color var(--duration-sm) var(--ease),
|
|
389
|
+
box-shadow var(--duration-sm) var(--ease);
|
|
263
390
|
}
|
|
264
391
|
|
|
265
392
|
/* Motion recipes — Base UI primitives emit `data-starting-style` (enter)
|
|
@@ -292,77 +419,214 @@
|
|
|
292
419
|
}
|
|
293
420
|
}
|
|
294
421
|
|
|
295
|
-
/*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
|
|
422
|
+
/* Enter/exit recipes — THREE idioms, each tiered sm/md/lg.
|
|
423
|
+
* `motion-scale-*` ZOOMs (opacity + blur + scale) — icons (sm), dialogs (lg).
|
|
424
|
+
* `motion-slide-*` SLIDES (opacity + blur + directional translate) — popups (md).
|
|
425
|
+
* `motion-fade-*` FADES in place (opacity + blur, no transform).
|
|
426
|
+
* Tiers: sm = controls/icons · md = popups · lg = dialogs. Pick ONE idiom +
|
|
427
|
+
* tier per surface (don't compose — each declares its own unlayered transition).
|
|
428
|
+
* Companion idioms: `motion-color` (controls) and `motion-scrim` (backdrops). */
|
|
429
|
+
@utility motion-scale-sm {
|
|
299
430
|
filter: blur(0.001px);
|
|
431
|
+
scale: 1;
|
|
300
432
|
&[data-starting-style],
|
|
301
433
|
&[data-ending-style] {
|
|
302
434
|
opacity: 0;
|
|
303
|
-
filter: blur(var(--blur));
|
|
435
|
+
filter: blur(var(--blur-sm));
|
|
436
|
+
scale: var(--scale-sm);
|
|
304
437
|
}
|
|
305
438
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
439
|
+
@utility motion-scale-md {
|
|
440
|
+
filter: blur(0.001px);
|
|
441
|
+
scale: 1;
|
|
442
|
+
&[data-starting-style],
|
|
443
|
+
&[data-ending-style] {
|
|
444
|
+
opacity: 0;
|
|
445
|
+
filter: blur(var(--blur-md));
|
|
446
|
+
scale: var(--scale-md);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
@utility motion-scale-lg {
|
|
313
450
|
filter: blur(0.001px);
|
|
314
451
|
scale: 1;
|
|
315
452
|
&[data-starting-style],
|
|
316
453
|
&[data-ending-style] {
|
|
317
454
|
opacity: 0;
|
|
318
|
-
filter: blur(var(--
|
|
319
|
-
scale: var(--scale);
|
|
455
|
+
filter: blur(var(--blur-lg));
|
|
456
|
+
scale: var(--scale-lg);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/* `motion-slide-*` — directional slide: the surface starts offset AWAY from its
|
|
461
|
+
* trigger's `data-[side]` (Base UI sets it) and settles toward it; default /
|
|
462
|
+
* side=bottom rises up. Opacity + blur + translate (`--offset-*`), NO scale. */
|
|
463
|
+
@utility motion-slide-sm {
|
|
464
|
+
filter: blur(0.001px);
|
|
465
|
+
translate: 0;
|
|
466
|
+
&[data-starting-style],
|
|
467
|
+
&[data-ending-style] {
|
|
468
|
+
opacity: 0;
|
|
469
|
+
filter: blur(var(--blur-sm));
|
|
470
|
+
translate: 0 var(--offset-sm);
|
|
471
|
+
}
|
|
472
|
+
&[data-side=top][data-starting-style],
|
|
473
|
+
&[data-side=top][data-ending-style] { translate: 0 calc(var(--offset-sm) * -1); }
|
|
474
|
+
&[data-side=left][data-starting-style],
|
|
475
|
+
&[data-side=left][data-ending-style],
|
|
476
|
+
&[data-side=inline-start][data-starting-style],
|
|
477
|
+
&[data-side=inline-start][data-ending-style] { translate: calc(var(--offset-sm) * -1) 0; }
|
|
478
|
+
&[data-side=right][data-starting-style],
|
|
479
|
+
&[data-side=right][data-ending-style],
|
|
480
|
+
&[data-side=inline-end][data-starting-style],
|
|
481
|
+
&[data-side=inline-end][data-ending-style] { translate: var(--offset-sm) 0; }
|
|
482
|
+
}
|
|
483
|
+
@utility motion-slide-md {
|
|
484
|
+
filter: blur(0.001px);
|
|
485
|
+
translate: 0;
|
|
486
|
+
&[data-starting-style],
|
|
487
|
+
&[data-ending-style] {
|
|
488
|
+
opacity: 0;
|
|
489
|
+
filter: blur(var(--blur-md));
|
|
490
|
+
translate: 0 var(--offset-md); /* default + side=bottom: start lower, rise up */
|
|
491
|
+
}
|
|
492
|
+
&[data-side=top][data-starting-style],
|
|
493
|
+
&[data-side=top][data-ending-style] { translate: 0 calc(var(--offset-md) * -1); }
|
|
494
|
+
&[data-side=left][data-starting-style],
|
|
495
|
+
&[data-side=left][data-ending-style],
|
|
496
|
+
&[data-side=inline-start][data-starting-style],
|
|
497
|
+
&[data-side=inline-start][data-ending-style] { translate: calc(var(--offset-md) * -1) 0; }
|
|
498
|
+
&[data-side=right][data-starting-style],
|
|
499
|
+
&[data-side=right][data-ending-style],
|
|
500
|
+
&[data-side=inline-end][data-starting-style],
|
|
501
|
+
&[data-side=inline-end][data-ending-style] { translate: var(--offset-md) 0; }
|
|
502
|
+
}
|
|
503
|
+
@utility motion-slide-lg {
|
|
504
|
+
filter: blur(0.001px);
|
|
505
|
+
translate: 0;
|
|
506
|
+
&[data-starting-style],
|
|
507
|
+
&[data-ending-style] {
|
|
508
|
+
opacity: 0;
|
|
509
|
+
filter: blur(var(--blur-lg));
|
|
510
|
+
translate: 0 var(--offset-lg);
|
|
511
|
+
}
|
|
512
|
+
&[data-side=top][data-starting-style],
|
|
513
|
+
&[data-side=top][data-ending-style] { translate: 0 calc(var(--offset-lg) * -1); }
|
|
514
|
+
&[data-side=left][data-starting-style],
|
|
515
|
+
&[data-side=left][data-ending-style],
|
|
516
|
+
&[data-side=inline-start][data-starting-style],
|
|
517
|
+
&[data-side=inline-start][data-ending-style] { translate: calc(var(--offset-lg) * -1) 0; }
|
|
518
|
+
&[data-side=right][data-starting-style],
|
|
519
|
+
&[data-side=right][data-ending-style],
|
|
520
|
+
&[data-side=inline-end][data-starting-style],
|
|
521
|
+
&[data-side=inline-end][data-ending-style] { translate: var(--offset-lg) 0; }
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/* `motion-fade-*` — fade in place: opacity + blur, no transform. The signature
|
|
525
|
+
* blur-fade for content that should appear without moving or scaling. */
|
|
526
|
+
@utility motion-fade-sm {
|
|
527
|
+
filter: blur(0.001px);
|
|
528
|
+
&[data-starting-style],
|
|
529
|
+
&[data-ending-style] {
|
|
530
|
+
opacity: 0;
|
|
531
|
+
filter: blur(var(--blur-sm));
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
@utility motion-fade-md {
|
|
535
|
+
filter: blur(0.001px);
|
|
536
|
+
&[data-starting-style],
|
|
537
|
+
&[data-ending-style] {
|
|
538
|
+
opacity: 0;
|
|
539
|
+
filter: blur(var(--blur-md));
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
@utility motion-fade-lg {
|
|
543
|
+
filter: blur(0.001px);
|
|
544
|
+
&[data-starting-style],
|
|
545
|
+
&[data-ending-style] {
|
|
546
|
+
opacity: 0;
|
|
547
|
+
filter: blur(var(--blur-lg));
|
|
320
548
|
}
|
|
321
549
|
}
|
|
322
550
|
|
|
323
|
-
/* `motion-
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
* and
|
|
327
|
-
@utility motion-
|
|
551
|
+
/* `motion-pop-md` — COMBINED idiom: scale + slide together (dropdowns "pop up
|
|
552
|
+
* while zooming"). The one surface that wants two idioms — so it's a single
|
|
553
|
+
* recipe with one transition. Don't try `motion-scale-md motion-slide-md`: their
|
|
554
|
+
* transitions collide and scale won't animate. md only (no sm/lg consumer). */
|
|
555
|
+
@utility motion-pop-md {
|
|
328
556
|
filter: blur(0.001px);
|
|
557
|
+
scale: 1;
|
|
329
558
|
translate: 0;
|
|
330
559
|
&[data-starting-style],
|
|
331
560
|
&[data-ending-style] {
|
|
332
561
|
opacity: 0;
|
|
333
|
-
filter: blur(var(--blur));
|
|
334
|
-
|
|
562
|
+
filter: blur(var(--blur-md));
|
|
563
|
+
scale: var(--scale-md);
|
|
564
|
+
translate: 0 var(--offset-md); /* default + side=bottom: start lower, rise up */
|
|
335
565
|
}
|
|
336
566
|
&[data-side=top][data-starting-style],
|
|
337
|
-
&[data-side=top][data-ending-style] { translate: 0 calc(var(--offset) * -1); }
|
|
567
|
+
&[data-side=top][data-ending-style] { translate: 0 calc(var(--offset-md) * -1); }
|
|
338
568
|
&[data-side=left][data-starting-style],
|
|
339
569
|
&[data-side=left][data-ending-style],
|
|
340
570
|
&[data-side=inline-start][data-starting-style],
|
|
341
|
-
&[data-side=inline-start][data-ending-style] { translate: calc(var(--offset) * -1) 0; }
|
|
571
|
+
&[data-side=inline-start][data-ending-style] { translate: calc(var(--offset-md) * -1) 0; }
|
|
342
572
|
&[data-side=right][data-starting-style],
|
|
343
573
|
&[data-side=right][data-ending-style],
|
|
344
574
|
&[data-side=inline-end][data-starting-style],
|
|
345
|
-
&[data-side=inline-end][data-ending-style] { translate: var(--offset) 0; }
|
|
575
|
+
&[data-side=inline-end][data-ending-style] { translate: var(--offset-md) 0; }
|
|
346
576
|
}
|
|
347
577
|
|
|
348
578
|
/* Recipe transitions — UNLAYERED on purpose (see note above): beats any
|
|
349
579
|
* layered `transition-*` utility on the same element without `!important`. */
|
|
350
580
|
.motion-scrim {
|
|
351
|
-
transition: opacity var(--duration) var(--ease);
|
|
581
|
+
transition: opacity var(--duration-lg) var(--ease);
|
|
352
582
|
}
|
|
353
|
-
.motion-
|
|
354
|
-
transition: opacity var(--duration) var(--ease),
|
|
355
|
-
filter var(--duration) var(--ease)
|
|
583
|
+
.motion-scale-sm {
|
|
584
|
+
transition: opacity var(--duration-sm) var(--ease),
|
|
585
|
+
filter var(--duration-sm) var(--ease),
|
|
586
|
+
scale var(--duration-sm) var(--ease);
|
|
356
587
|
}
|
|
357
|
-
.motion-scale {
|
|
358
|
-
transition: opacity var(--duration) var(--ease),
|
|
359
|
-
filter var(--duration) var(--ease),
|
|
360
|
-
scale var(--duration) var(--ease);
|
|
588
|
+
.motion-scale-md {
|
|
589
|
+
transition: opacity var(--duration-md) var(--ease),
|
|
590
|
+
filter var(--duration-md) var(--ease),
|
|
591
|
+
scale var(--duration-md) var(--ease);
|
|
361
592
|
}
|
|
362
|
-
.motion-
|
|
363
|
-
transition: opacity var(--duration) var(--ease),
|
|
364
|
-
filter var(--duration) var(--ease),
|
|
365
|
-
|
|
593
|
+
.motion-scale-lg {
|
|
594
|
+
transition: opacity var(--duration-lg) var(--ease),
|
|
595
|
+
filter var(--duration-lg) var(--ease),
|
|
596
|
+
scale var(--duration-lg) var(--ease);
|
|
597
|
+
}
|
|
598
|
+
.motion-slide-sm {
|
|
599
|
+
transition: opacity var(--duration-sm) var(--ease),
|
|
600
|
+
filter var(--duration-sm) var(--ease),
|
|
601
|
+
translate var(--duration-sm) var(--ease);
|
|
602
|
+
}
|
|
603
|
+
.motion-slide-md {
|
|
604
|
+
transition: opacity var(--duration-md) var(--ease),
|
|
605
|
+
filter var(--duration-md) var(--ease),
|
|
606
|
+
translate var(--duration-md) var(--ease);
|
|
607
|
+
}
|
|
608
|
+
.motion-slide-lg {
|
|
609
|
+
transition: opacity var(--duration-lg) var(--ease),
|
|
610
|
+
filter var(--duration-lg) var(--ease),
|
|
611
|
+
translate var(--duration-lg) var(--ease);
|
|
612
|
+
}
|
|
613
|
+
.motion-fade-sm {
|
|
614
|
+
transition: opacity var(--duration-sm) var(--ease),
|
|
615
|
+
filter var(--duration-sm) var(--ease);
|
|
616
|
+
}
|
|
617
|
+
.motion-fade-md {
|
|
618
|
+
transition: opacity var(--duration-md) var(--ease),
|
|
619
|
+
filter var(--duration-md) var(--ease);
|
|
620
|
+
}
|
|
621
|
+
.motion-fade-lg {
|
|
622
|
+
transition: opacity var(--duration-lg) var(--ease),
|
|
623
|
+
filter var(--duration-lg) var(--ease);
|
|
624
|
+
}
|
|
625
|
+
.motion-pop-md {
|
|
626
|
+
transition: opacity var(--duration-md) var(--ease),
|
|
627
|
+
filter var(--duration-md) var(--ease),
|
|
628
|
+
scale var(--duration-md) var(--ease),
|
|
629
|
+
translate var(--duration-md) var(--ease);
|
|
366
630
|
}
|
|
367
631
|
|
|
368
632
|
/* ---------------------------------------------------------------------------
|
|
@@ -370,10 +634,37 @@
|
|
|
370
634
|
* ------------------------------------------------------------------------- */
|
|
371
635
|
@media (prefers-reduced-motion: reduce) {
|
|
372
636
|
:root {
|
|
373
|
-
--duration: 0ms;
|
|
374
|
-
--blur: 0px;
|
|
375
|
-
--scale: 1;
|
|
376
|
-
--offset: 0px;
|
|
377
|
-
--stagger: 0ms;
|
|
637
|
+
--duration-sm: 0ms; --duration-md: 0ms; --duration-lg: 0ms;
|
|
638
|
+
--blur-sm: 0px; --blur-md: 0px; --blur-lg: 0px;
|
|
639
|
+
--scale-sm: 1; --scale-md: 1; --scale-lg: 1;
|
|
640
|
+
--offset-sm: 0px; --offset-md: 0px; --offset-lg: 0px;
|
|
641
|
+
--stagger-sm: 0ms; --stagger-md: 0ms; --stagger-lg: 0ms;
|
|
378
642
|
}
|
|
379
643
|
}
|
|
644
|
+
|
|
645
|
+
/* ---------------------------------------------------------------------------
|
|
646
|
+
* Keyframe utilities — self-hosted (replaces the former `tw-animate-css` dep,
|
|
647
|
+
* now removed). Only the three the library actually uses; `animate-spin` /
|
|
648
|
+
* `animate-pulse` come from Tailwind core. Registering via `@theme` generates
|
|
649
|
+
* the `animate-accordion-down` / `animate-accordion-up` / `animate-caret-blink`
|
|
650
|
+
* utilities. Accordion height runs on our motion tokens (`md` tier + the curve)
|
|
651
|
+
* and uses Base UI's `--accordion-panel-height` (the Radix var tw-animate
|
|
652
|
+
* targeted is never set under Base UI). Collapses under reduced motion via
|
|
653
|
+
* `--duration-md`. */
|
|
654
|
+
@theme {
|
|
655
|
+
--animate-accordion-down: accordion-down var(--duration-md) var(--ease);
|
|
656
|
+
--animate-accordion-up: accordion-up var(--duration-md) var(--ease);
|
|
657
|
+
--animate-caret-blink: caret-blink 1.25s ease-out infinite;
|
|
658
|
+
}
|
|
659
|
+
@keyframes accordion-down {
|
|
660
|
+
from { height: 0; }
|
|
661
|
+
to { height: var(--accordion-panel-height); }
|
|
662
|
+
}
|
|
663
|
+
@keyframes accordion-up {
|
|
664
|
+
from { height: var(--accordion-panel-height); }
|
|
665
|
+
to { height: 0; }
|
|
666
|
+
}
|
|
667
|
+
@keyframes caret-blink {
|
|
668
|
+
0%, 70%, 100% { opacity: 1; }
|
|
669
|
+
20%, 50% { opacity: 0; }
|
|
670
|
+
}
|