@justin_evo/evo-ui 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +3 -3
  2. package/dist/TopNav/TopNav.d.ts +19 -0
  3. package/dist/declarations.d.ts +6 -6
  4. package/dist/evo-ui.css +1 -1
  5. package/dist/index.cjs.js +1 -1
  6. package/dist/index.es.js +3301 -3197
  7. package/package.json +52 -52
  8. package/src/Alert/Alert.tsx +49 -49
  9. package/src/AutoComplete/AutoComplete.tsx +810 -810
  10. package/src/Badge/Badge.tsx +53 -53
  11. package/src/Breadcrumb/Breadcrumb.tsx +53 -53
  12. package/src/Button/Button.tsx +125 -125
  13. package/src/Card/Card.tsx +257 -257
  14. package/src/Checkbox/Checkbox.tsx +59 -59
  15. package/src/CommandPalette/CommandPalette.tsx +185 -185
  16. package/src/Container/Container.tsx +31 -31
  17. package/src/Divider/Divider.tsx +31 -31
  18. package/src/Form/Form.tsx +185 -185
  19. package/src/Grid/Grid.tsx +66 -66
  20. package/src/ImageCropper/ImageCropper.tsx +911 -911
  21. package/src/Input/Input.tsx +74 -74
  22. package/src/Modal/Modal.tsx +77 -77
  23. package/src/Nav/Nav.tsx +708 -708
  24. package/src/Notification/Notification.tsx +1503 -1503
  25. package/src/Pagination/Pagination.tsx +76 -76
  26. package/src/Radio/Radio.tsx +69 -69
  27. package/src/RichTextArea/RichTextArea.tsx +886 -869
  28. package/src/Select/Select.tsx +515 -515
  29. package/src/Skeleton/Skeleton.tsx +70 -70
  30. package/src/Stack/Stack.tsx +52 -52
  31. package/src/Table/Table.tsx +335 -335
  32. package/src/Tabs/Tabs.tsx +90 -90
  33. package/src/Theme/ThemeProvider.tsx +253 -253
  34. package/src/Theme/ThemeToggle.tsx +79 -79
  35. package/src/Toggle/Toggle.tsx +48 -48
  36. package/src/Tooltip/Tooltip.tsx +38 -38
  37. package/src/TopNav/TopNav.tsx +1163 -994
  38. package/src/TreeSelect/TreeSelect.tsx +825 -825
  39. package/src/css/alert.module.scss +93 -93
  40. package/src/css/autocomplete.module.scss +416 -416
  41. package/src/css/badge.module.scss +82 -82
  42. package/src/css/base/_color.scss +159 -159
  43. package/src/css/base/_theme.scss +237 -237
  44. package/src/css/base/_variables.scss +161 -161
  45. package/src/css/breadcrumb.module.scss +50 -50
  46. package/src/css/button.module.scss +385 -385
  47. package/src/css/card.module.scss +217 -217
  48. package/src/css/checkbox.module.scss +123 -120
  49. package/src/css/commandpalette.module.scss +211 -211
  50. package/src/css/container.module.scss +18 -18
  51. package/src/css/divider.module.scss +41 -41
  52. package/src/css/form.module.scss +245 -245
  53. package/src/css/imagecropper.module.scss +397 -397
  54. package/src/css/input.module.scss +89 -89
  55. package/src/css/modal.module.scss +105 -105
  56. package/src/css/nav.module.scss +494 -494
  57. package/src/css/notification.module.scss +691 -691
  58. package/src/css/pagination.module.scss +63 -63
  59. package/src/css/radio.module.scss +89 -89
  60. package/src/css/richtextarea.module.scss +307 -307
  61. package/src/css/select.module.scss +525 -525
  62. package/src/css/skeleton.module.scss +30 -30
  63. package/src/css/table.module.scss +386 -386
  64. package/src/css/tabs.module.scss +63 -63
  65. package/src/css/theme-toggle.module.scss +83 -83
  66. package/src/css/toggle.module.scss +54 -54
  67. package/src/css/tooltip.module.scss +97 -97
  68. package/src/css/topnav.module.scss +568 -396
  69. package/src/css/treeselect.module.scss +558 -558
  70. package/src/css/utilities/_borders.scss +111 -111
  71. package/src/css/utilities/_colors.scss +66 -66
  72. package/src/css/utilities/_effects.scss +216 -216
  73. package/src/css/utilities/_layout.scss +181 -181
  74. package/src/css/utilities/_position.scss +75 -75
  75. package/src/css/utilities/_sizing.scss +138 -138
  76. package/src/css/utilities/_spacing.scss +99 -99
  77. package/src/css/utilities/_typography.scss +121 -121
  78. package/src/css/utilities/index.scss +24 -24
  79. package/src/declarations.d.ts +6 -6
  80. package/src/index.ts +60 -60
@@ -1,237 +1,237 @@
1
- // ==========================================================
2
- // EVO-UI THEME TOKENS
3
- // ----------------------------------------------------------
4
- // Semantic CSS custom properties for light & dark themes.
5
- //
6
- // Theme is controlled by a `data-theme` attribute on <html>:
7
- // <html data-theme="light"> → light tokens
8
- // <html data-theme="dark"> → dark tokens
9
- // (no attribute) → follows OS via prefers-color-scheme
10
- //
11
- // Developers can override any token at any scope:
12
- // :root { --evo-color-primary: #ff6b6b; }
13
- //
14
- // All themed component styles read these tokens, never raw
15
- // palette colors, so a single attribute flip re-themes the
16
- // entire UI without re-rendering React or reloading CSS.
17
- // ==========================================================
18
-
19
- @use './color' as *;
20
-
21
- // ---------- Light theme tokens ----------
22
- @mixin evo-theme-light {
23
- // Surfaces
24
- --evo-color-bg: #{$evo-white-100};
25
- --evo-color-bg-rgb: 255, 255, 255;
26
- --evo-color-surface: #{$evo-slate-50};
27
- --evo-color-surface-elevated: #{$evo-white-100};
28
- --evo-color-surface-sunken: #{$evo-slate-100};
29
- --evo-color-surface-hover: #{$evo-slate-100};
30
- --evo-color-surface-active: #{$evo-slate-200};
31
-
32
- // Borders
33
- --evo-color-border: #{$evo-slate-200};
34
- --evo-color-border-strong: #{$evo-slate-300};
35
- --evo-color-border-subtle: #{$evo-slate-100};
36
-
37
- // Text
38
- --evo-color-text: #{$evo-slate-900};
39
- --evo-color-text-secondary: #{$evo-slate-600};
40
- --evo-color-text-muted: #{$evo-slate-500};
41
- --evo-color-text-inverted: #{$evo-white-100};
42
-
43
- // Brand (primary)
44
- --evo-color-primary: #{$evo-cyan-600};
45
- --evo-color-primary-rgb: 8, 145, 178;
46
- --evo-color-primary-hover: #{$evo-cyan-700};
47
- --evo-color-primary-active: #{$evo-cyan-800};
48
- --evo-color-primary-focus: #{$evo-cyan-400};
49
- --evo-color-primary-fg: #{$evo-white-100};
50
- --evo-color-primary-soft: #{$evo-cyan-100};
51
- --evo-color-primary-soft-hover: #{$evo-cyan-200};
52
-
53
- // Secondary (neutral chrome)
54
- --evo-color-secondary: #{$evo-slate-100};
55
- --evo-color-secondary-hover: #{$evo-slate-200};
56
- --evo-color-secondary-active: #{$evo-slate-300};
57
- --evo-color-secondary-fg: #{$evo-slate-800};
58
- --evo-color-secondary-border: #{$evo-slate-300};
59
-
60
- // Status — Danger
61
- --evo-color-danger: #{$evo-rose-600};
62
- --evo-color-danger-rgb: 225, 29, 72;
63
- --evo-color-danger-hover: #{$evo-rose-700};
64
- --evo-color-danger-active: #{$evo-rose-800};
65
- --evo-color-danger-focus: #{$evo-rose-400};
66
- --evo-color-danger-fg: #{$evo-white-100};
67
- --evo-color-danger-soft: #{$evo-rose-100};
68
-
69
- // Status — Warning
70
- --evo-color-warning: #{$evo-amber-500};
71
- --evo-color-warning-rgb: 245, 158, 11;
72
- --evo-color-warning-hover: #{$evo-amber-600};
73
- --evo-color-warning-active: #{$evo-amber-700};
74
- --evo-color-warning-focus: #{$evo-amber-300};
75
- --evo-color-warning-fg: #{$evo-amber-900};
76
- --evo-color-warning-soft: #{$evo-amber-100};
77
-
78
- // Status — Success
79
- --evo-color-success: #{$evo-emerald-600};
80
- --evo-color-success-rgb: 5, 150, 105;
81
- --evo-color-success-hover: #{$evo-emerald-700};
82
- --evo-color-success-active: #{$evo-emerald-800};
83
- --evo-color-success-focus: #{$evo-emerald-400};
84
- --evo-color-success-fg: #{$evo-white-100};
85
- --evo-color-success-soft: #{$evo-emerald-100};
86
-
87
- // Status — Info
88
- --evo-color-info: #{$evo-violet-600};
89
- --evo-color-info-rgb: 124, 58, 237;
90
- --evo-color-info-hover: #{$evo-violet-700};
91
- --evo-color-info-active: #{$evo-violet-800};
92
- --evo-color-info-focus: #{$evo-violet-400};
93
- --evo-color-info-fg: #{$evo-white-100};
94
- --evo-color-info-soft: #{$evo-violet-100};
95
-
96
- // Overlays & effects
97
- --evo-color-overlay: rgba(15, 23, 42, 0.45);
98
- --evo-color-backdrop: rgba(15, 23, 42, 0.6);
99
- --evo-shadow-color: 0 0 0;
100
- --evo-shadow-strength: 0.08;
101
-
102
- // Skeleton / shimmer
103
- --evo-color-skeleton-base: #{$evo-slate-200};
104
- --evo-color-skeleton-highlight: #{$evo-slate-100};
105
-
106
- // Color scheme hint for native UI (scrollbars, form controls)
107
- color-scheme: light;
108
- }
109
-
110
- // ---------- Dark theme tokens ----------
111
- @mixin evo-theme-dark {
112
- // Surfaces — soft dark grays (not pure black) per 2026 best practice
113
- --evo-color-bg: #{$evo-slate-950};
114
- --evo-color-bg-rgb: 2, 6, 23;
115
- --evo-color-surface: #{$evo-slate-900};
116
- --evo-color-surface-elevated: #{$evo-slate-800};
117
- --evo-color-surface-sunken: #{$evo-slate-950};
118
- --evo-color-surface-hover: #{$evo-slate-800};
119
- --evo-color-surface-active: #{$evo-slate-700};
120
-
121
- // Borders
122
- --evo-color-border: #{$evo-slate-700};
123
- --evo-color-border-strong: #{$evo-slate-600};
124
- --evo-color-border-subtle: #{$evo-slate-800};
125
-
126
- // Text — off-white for less eye strain
127
- --evo-color-text: #{$evo-slate-50};
128
- --evo-color-text-secondary: #{$evo-slate-300};
129
- --evo-color-text-muted: #{$evo-slate-400};
130
- --evo-color-text-inverted: #{$evo-slate-900};
131
-
132
- // Brand (primary) — lighter, more luminous in dark mode
133
- --evo-color-primary: #{$evo-cyan-400};
134
- --evo-color-primary-rgb: 34, 211, 238;
135
- --evo-color-primary-hover: #{$evo-cyan-300};
136
- --evo-color-primary-active: #{$evo-cyan-500};
137
- --evo-color-primary-focus: #{$evo-cyan-300};
138
- --evo-color-primary-fg: #{$evo-slate-950};
139
- --evo-color-primary-soft: rgba(34, 211, 238, 0.12);
140
- --evo-color-primary-soft-hover: rgba(34, 211, 238, 0.18);
141
-
142
- // Secondary
143
- --evo-color-secondary: rgba(255, 255, 255, 0.06);
144
- --evo-color-secondary-hover: rgba(255, 255, 255, 0.10);
145
- --evo-color-secondary-active: rgba(255, 255, 255, 0.15);
146
- --evo-color-secondary-fg: #{$evo-slate-200};
147
- --evo-color-secondary-border: #{$evo-slate-600};
148
-
149
- // Status — Danger
150
- --evo-color-danger: #{$evo-rose-500};
151
- --evo-color-danger-rgb: 244, 63, 94;
152
- --evo-color-danger-hover: #{$evo-rose-400};
153
- --evo-color-danger-active: #{$evo-rose-600};
154
- --evo-color-danger-focus: #{$evo-rose-300};
155
- --evo-color-danger-fg: #{$evo-white-100};
156
- --evo-color-danger-soft: rgba(244, 63, 94, 0.12);
157
-
158
- // Status — Warning
159
- --evo-color-warning: #{$evo-amber-400};
160
- --evo-color-warning-rgb: 251, 191, 36;
161
- --evo-color-warning-hover: #{$evo-amber-300};
162
- --evo-color-warning-active: #{$evo-amber-500};
163
- --evo-color-warning-focus: #{$evo-amber-300};
164
- --evo-color-warning-fg: #{$evo-slate-950};
165
- --evo-color-warning-soft: rgba(251, 191, 36, 0.12);
166
-
167
- // Status — Success
168
- --evo-color-success: #{$evo-emerald-500};
169
- --evo-color-success-rgb: 16, 185, 129;
170
- --evo-color-success-hover: #{$evo-emerald-400};
171
- --evo-color-success-active: #{$evo-emerald-600};
172
- --evo-color-success-focus: #{$evo-emerald-300};
173
- --evo-color-success-fg: #{$evo-white-100};
174
- --evo-color-success-soft: rgba(16, 185, 129, 0.12);
175
-
176
- // Status — Info
177
- --evo-color-info: #{$evo-violet-500};
178
- --evo-color-info-rgb: 139, 92, 246;
179
- --evo-color-info-hover: #{$evo-violet-400};
180
- --evo-color-info-active: #{$evo-violet-600};
181
- --evo-color-info-focus: #{$evo-violet-300};
182
- --evo-color-info-fg: #{$evo-white-100};
183
- --evo-color-info-soft: rgba(139, 92, 246, 0.12);
184
-
185
- // Overlays & effects
186
- --evo-color-overlay: rgba(0, 0, 0, 0.65);
187
- --evo-color-backdrop: rgba(0, 0, 0, 0.75);
188
- --evo-shadow-color: 0 0 0;
189
- --evo-shadow-strength: 0.35;
190
-
191
- // Skeleton / shimmer
192
- --evo-color-skeleton-base: #{$evo-slate-800};
193
- --evo-color-skeleton-highlight: #{$evo-slate-700};
194
-
195
- color-scheme: dark;
196
- }
197
-
198
- // ---------- Apply themes ----------
199
- // 1. Explicit data-theme attribute wins (developer/user choice)
200
- :root,
201
- [data-theme='light'] {
202
- @include evo-theme-light;
203
- }
204
-
205
- [data-theme='dark'] {
206
- @include evo-theme-dark;
207
- }
208
-
209
- // 2. No data-theme attribute → follow OS preference automatically.
210
- // Only applies when the user/site hasn't set data-theme at all.
211
- @media (prefers-color-scheme: dark) {
212
- :root:not([data-theme]) {
213
- @include evo-theme-dark;
214
- }
215
- }
216
-
217
- // ---------- Smooth theme transitions ----------
218
- // Animate color changes on theme flip — but skip during the
219
- // initial paint and respect users who request reduced motion.
220
- :root[data-theme-transition='true'] *,
221
- :root[data-theme-transition='true'] *::before,
222
- :root[data-theme-transition='true'] *::after {
223
- transition: background-color 200ms ease,
224
- border-color 200ms ease,
225
- color 200ms ease,
226
- fill 200ms ease,
227
- stroke 200ms ease,
228
- box-shadow 200ms ease !important;
229
- }
230
-
231
- @media (prefers-reduced-motion: reduce) {
232
- :root[data-theme-transition='true'] *,
233
- :root[data-theme-transition='true'] *::before,
234
- :root[data-theme-transition='true'] *::after {
235
- transition: none !important;
236
- }
237
- }
1
+ // ==========================================================
2
+ // EVO-UI THEME TOKENS
3
+ // ----------------------------------------------------------
4
+ // Semantic CSS custom properties for light & dark themes.
5
+ //
6
+ // Theme is controlled by a `data-theme` attribute on <html>:
7
+ // <html data-theme="light"> → light tokens
8
+ // <html data-theme="dark"> → dark tokens
9
+ // (no attribute) → follows OS via prefers-color-scheme
10
+ //
11
+ // Developers can override any token at any scope:
12
+ // :root { --evo-color-primary: #ff6b6b; }
13
+ //
14
+ // All themed component styles read these tokens, never raw
15
+ // palette colors, so a single attribute flip re-themes the
16
+ // entire UI without re-rendering React or reloading CSS.
17
+ // ==========================================================
18
+
19
+ @use './color' as *;
20
+
21
+ // ---------- Light theme tokens ----------
22
+ @mixin evo-theme-light {
23
+ // Surfaces
24
+ --evo-color-bg: #{$evo-white-100};
25
+ --evo-color-bg-rgb: 255, 255, 255;
26
+ --evo-color-surface: #{$evo-slate-50};
27
+ --evo-color-surface-elevated: #{$evo-white-100};
28
+ --evo-color-surface-sunken: #{$evo-slate-100};
29
+ --evo-color-surface-hover: #{$evo-slate-100};
30
+ --evo-color-surface-active: #{$evo-slate-200};
31
+
32
+ // Borders
33
+ --evo-color-border: #{$evo-slate-200};
34
+ --evo-color-border-strong: #{$evo-slate-300};
35
+ --evo-color-border-subtle: #{$evo-slate-100};
36
+
37
+ // Text
38
+ --evo-color-text: #{$evo-slate-900};
39
+ --evo-color-text-secondary: #{$evo-slate-600};
40
+ --evo-color-text-muted: #{$evo-slate-500};
41
+ --evo-color-text-inverted: #{$evo-white-100};
42
+
43
+ // Brand (primary)
44
+ --evo-color-primary: #{$evo-cyan-600};
45
+ --evo-color-primary-rgb: 8, 145, 178;
46
+ --evo-color-primary-hover: #{$evo-cyan-700};
47
+ --evo-color-primary-active: #{$evo-cyan-800};
48
+ --evo-color-primary-focus: #{$evo-cyan-400};
49
+ --evo-color-primary-fg: #{$evo-white-100};
50
+ --evo-color-primary-soft: #{$evo-cyan-100};
51
+ --evo-color-primary-soft-hover: #{$evo-cyan-200};
52
+
53
+ // Secondary (neutral chrome)
54
+ --evo-color-secondary: #{$evo-slate-100};
55
+ --evo-color-secondary-hover: #{$evo-slate-200};
56
+ --evo-color-secondary-active: #{$evo-slate-300};
57
+ --evo-color-secondary-fg: #{$evo-slate-800};
58
+ --evo-color-secondary-border: #{$evo-slate-300};
59
+
60
+ // Status — Danger
61
+ --evo-color-danger: #{$evo-rose-600};
62
+ --evo-color-danger-rgb: 225, 29, 72;
63
+ --evo-color-danger-hover: #{$evo-rose-700};
64
+ --evo-color-danger-active: #{$evo-rose-800};
65
+ --evo-color-danger-focus: #{$evo-rose-400};
66
+ --evo-color-danger-fg: #{$evo-white-100};
67
+ --evo-color-danger-soft: #{$evo-rose-100};
68
+
69
+ // Status — Warning
70
+ --evo-color-warning: #{$evo-amber-500};
71
+ --evo-color-warning-rgb: 245, 158, 11;
72
+ --evo-color-warning-hover: #{$evo-amber-600};
73
+ --evo-color-warning-active: #{$evo-amber-700};
74
+ --evo-color-warning-focus: #{$evo-amber-300};
75
+ --evo-color-warning-fg: #{$evo-amber-900};
76
+ --evo-color-warning-soft: #{$evo-amber-100};
77
+
78
+ // Status — Success
79
+ --evo-color-success: #{$evo-emerald-600};
80
+ --evo-color-success-rgb: 5, 150, 105;
81
+ --evo-color-success-hover: #{$evo-emerald-700};
82
+ --evo-color-success-active: #{$evo-emerald-800};
83
+ --evo-color-success-focus: #{$evo-emerald-400};
84
+ --evo-color-success-fg: #{$evo-white-100};
85
+ --evo-color-success-soft: #{$evo-emerald-100};
86
+
87
+ // Status — Info
88
+ --evo-color-info: #{$evo-violet-600};
89
+ --evo-color-info-rgb: 124, 58, 237;
90
+ --evo-color-info-hover: #{$evo-violet-700};
91
+ --evo-color-info-active: #{$evo-violet-800};
92
+ --evo-color-info-focus: #{$evo-violet-400};
93
+ --evo-color-info-fg: #{$evo-white-100};
94
+ --evo-color-info-soft: #{$evo-violet-100};
95
+
96
+ // Overlays & effects
97
+ --evo-color-overlay: rgba(15, 23, 42, 0.45);
98
+ --evo-color-backdrop: rgba(15, 23, 42, 0.6);
99
+ --evo-shadow-color: 0 0 0;
100
+ --evo-shadow-strength: 0.08;
101
+
102
+ // Skeleton / shimmer
103
+ --evo-color-skeleton-base: #{$evo-slate-200};
104
+ --evo-color-skeleton-highlight: #{$evo-slate-100};
105
+
106
+ // Color scheme hint for native UI (scrollbars, form controls)
107
+ color-scheme: light;
108
+ }
109
+
110
+ // ---------- Dark theme tokens ----------
111
+ @mixin evo-theme-dark {
112
+ // Surfaces — soft dark grays (not pure black) per 2026 best practice
113
+ --evo-color-bg: #{$evo-slate-950};
114
+ --evo-color-bg-rgb: 2, 6, 23;
115
+ --evo-color-surface: #{$evo-slate-900};
116
+ --evo-color-surface-elevated: #{$evo-slate-800};
117
+ --evo-color-surface-sunken: #{$evo-slate-950};
118
+ --evo-color-surface-hover: #{$evo-slate-800};
119
+ --evo-color-surface-active: #{$evo-slate-700};
120
+
121
+ // Borders
122
+ --evo-color-border: #{$evo-slate-700};
123
+ --evo-color-border-strong: #{$evo-slate-600};
124
+ --evo-color-border-subtle: #{$evo-slate-800};
125
+
126
+ // Text — off-white for less eye strain
127
+ --evo-color-text: #{$evo-slate-50};
128
+ --evo-color-text-secondary: #{$evo-slate-300};
129
+ --evo-color-text-muted: #{$evo-slate-400};
130
+ --evo-color-text-inverted: #{$evo-slate-900};
131
+
132
+ // Brand (primary) — lighter, more luminous in dark mode
133
+ --evo-color-primary: #{$evo-cyan-400};
134
+ --evo-color-primary-rgb: 34, 211, 238;
135
+ --evo-color-primary-hover: #{$evo-cyan-300};
136
+ --evo-color-primary-active: #{$evo-cyan-500};
137
+ --evo-color-primary-focus: #{$evo-cyan-300};
138
+ --evo-color-primary-fg: #{$evo-slate-950};
139
+ --evo-color-primary-soft: rgba(34, 211, 238, 0.12);
140
+ --evo-color-primary-soft-hover: rgba(34, 211, 238, 0.18);
141
+
142
+ // Secondary
143
+ --evo-color-secondary: rgba(255, 255, 255, 0.06);
144
+ --evo-color-secondary-hover: rgba(255, 255, 255, 0.10);
145
+ --evo-color-secondary-active: rgba(255, 255, 255, 0.15);
146
+ --evo-color-secondary-fg: #{$evo-slate-200};
147
+ --evo-color-secondary-border: #{$evo-slate-600};
148
+
149
+ // Status — Danger
150
+ --evo-color-danger: #{$evo-rose-500};
151
+ --evo-color-danger-rgb: 244, 63, 94;
152
+ --evo-color-danger-hover: #{$evo-rose-400};
153
+ --evo-color-danger-active: #{$evo-rose-600};
154
+ --evo-color-danger-focus: #{$evo-rose-300};
155
+ --evo-color-danger-fg: #{$evo-white-100};
156
+ --evo-color-danger-soft: rgba(244, 63, 94, 0.12);
157
+
158
+ // Status — Warning
159
+ --evo-color-warning: #{$evo-amber-400};
160
+ --evo-color-warning-rgb: 251, 191, 36;
161
+ --evo-color-warning-hover: #{$evo-amber-300};
162
+ --evo-color-warning-active: #{$evo-amber-500};
163
+ --evo-color-warning-focus: #{$evo-amber-300};
164
+ --evo-color-warning-fg: #{$evo-slate-950};
165
+ --evo-color-warning-soft: rgba(251, 191, 36, 0.12);
166
+
167
+ // Status — Success
168
+ --evo-color-success: #{$evo-emerald-500};
169
+ --evo-color-success-rgb: 16, 185, 129;
170
+ --evo-color-success-hover: #{$evo-emerald-400};
171
+ --evo-color-success-active: #{$evo-emerald-600};
172
+ --evo-color-success-focus: #{$evo-emerald-300};
173
+ --evo-color-success-fg: #{$evo-white-100};
174
+ --evo-color-success-soft: rgba(16, 185, 129, 0.12);
175
+
176
+ // Status — Info
177
+ --evo-color-info: #{$evo-violet-500};
178
+ --evo-color-info-rgb: 139, 92, 246;
179
+ --evo-color-info-hover: #{$evo-violet-400};
180
+ --evo-color-info-active: #{$evo-violet-600};
181
+ --evo-color-info-focus: #{$evo-violet-300};
182
+ --evo-color-info-fg: #{$evo-white-100};
183
+ --evo-color-info-soft: rgba(139, 92, 246, 0.12);
184
+
185
+ // Overlays & effects
186
+ --evo-color-overlay: rgba(0, 0, 0, 0.65);
187
+ --evo-color-backdrop: rgba(0, 0, 0, 0.75);
188
+ --evo-shadow-color: 0 0 0;
189
+ --evo-shadow-strength: 0.35;
190
+
191
+ // Skeleton / shimmer
192
+ --evo-color-skeleton-base: #{$evo-slate-800};
193
+ --evo-color-skeleton-highlight: #{$evo-slate-700};
194
+
195
+ color-scheme: dark;
196
+ }
197
+
198
+ // ---------- Apply themes ----------
199
+ // 1. Explicit data-theme attribute wins (developer/user choice)
200
+ :root,
201
+ [data-theme='light'] {
202
+ @include evo-theme-light;
203
+ }
204
+
205
+ [data-theme='dark'] {
206
+ @include evo-theme-dark;
207
+ }
208
+
209
+ // 2. No data-theme attribute → follow OS preference automatically.
210
+ // Only applies when the user/site hasn't set data-theme at all.
211
+ @media (prefers-color-scheme: dark) {
212
+ :root:not([data-theme]) {
213
+ @include evo-theme-dark;
214
+ }
215
+ }
216
+
217
+ // ---------- Smooth theme transitions ----------
218
+ // Animate color changes on theme flip — but skip during the
219
+ // initial paint and respect users who request reduced motion.
220
+ :root[data-theme-transition='true'] *,
221
+ :root[data-theme-transition='true'] *::before,
222
+ :root[data-theme-transition='true'] *::after {
223
+ transition: background-color 200ms ease,
224
+ border-color 200ms ease,
225
+ color 200ms ease,
226
+ fill 200ms ease,
227
+ stroke 200ms ease,
228
+ box-shadow 200ms ease !important;
229
+ }
230
+
231
+ @media (prefers-reduced-motion: reduce) {
232
+ :root[data-theme-transition='true'] *,
233
+ :root[data-theme-transition='true'] *::before,
234
+ :root[data-theme-transition='true'] *::after {
235
+ transition: none !important;
236
+ }
237
+ }