@justin_evo/evo-ui 1.2.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 (77) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +70 -70
  3. package/dist/declarations.d.ts +6 -6
  4. package/package.json +52 -52
  5. package/src/Alert/Alert.tsx +49 -49
  6. package/src/AutoComplete/AutoComplete.tsx +810 -810
  7. package/src/Badge/Badge.tsx +53 -53
  8. package/src/Breadcrumb/Breadcrumb.tsx +53 -53
  9. package/src/Button/Button.tsx +125 -125
  10. package/src/Card/Card.tsx +257 -257
  11. package/src/Checkbox/Checkbox.tsx +59 -59
  12. package/src/CommandPalette/CommandPalette.tsx +185 -185
  13. package/src/Container/Container.tsx +31 -31
  14. package/src/Divider/Divider.tsx +31 -31
  15. package/src/Form/Form.tsx +185 -185
  16. package/src/Grid/Grid.tsx +66 -66
  17. package/src/ImageCropper/ImageCropper.tsx +911 -911
  18. package/src/Input/Input.tsx +74 -74
  19. package/src/Modal/Modal.tsx +77 -77
  20. package/src/Nav/Nav.tsx +708 -708
  21. package/src/Notification/Notification.tsx +1503 -1503
  22. package/src/Pagination/Pagination.tsx +76 -76
  23. package/src/Radio/Radio.tsx +69 -69
  24. package/src/RichTextArea/RichTextArea.tsx +886 -886
  25. package/src/Select/Select.tsx +515 -515
  26. package/src/Skeleton/Skeleton.tsx +70 -70
  27. package/src/Stack/Stack.tsx +52 -52
  28. package/src/Table/Table.tsx +335 -335
  29. package/src/Tabs/Tabs.tsx +90 -90
  30. package/src/Theme/ThemeProvider.tsx +253 -253
  31. package/src/Theme/ThemeToggle.tsx +79 -79
  32. package/src/Toggle/Toggle.tsx +48 -48
  33. package/src/Tooltip/Tooltip.tsx +38 -38
  34. package/src/TopNav/TopNav.tsx +1163 -1163
  35. package/src/TreeSelect/TreeSelect.tsx +825 -825
  36. package/src/css/alert.module.scss +93 -93
  37. package/src/css/autocomplete.module.scss +416 -416
  38. package/src/css/badge.module.scss +82 -82
  39. package/src/css/base/_color.scss +159 -159
  40. package/src/css/base/_theme.scss +237 -237
  41. package/src/css/base/_variables.scss +161 -161
  42. package/src/css/breadcrumb.module.scss +50 -50
  43. package/src/css/button.module.scss +385 -385
  44. package/src/css/card.module.scss +217 -217
  45. package/src/css/checkbox.module.scss +123 -123
  46. package/src/css/commandpalette.module.scss +211 -211
  47. package/src/css/container.module.scss +18 -18
  48. package/src/css/divider.module.scss +41 -41
  49. package/src/css/form.module.scss +245 -245
  50. package/src/css/imagecropper.module.scss +397 -397
  51. package/src/css/input.module.scss +89 -89
  52. package/src/css/modal.module.scss +105 -105
  53. package/src/css/nav.module.scss +494 -494
  54. package/src/css/notification.module.scss +691 -691
  55. package/src/css/pagination.module.scss +63 -63
  56. package/src/css/radio.module.scss +89 -89
  57. package/src/css/richtextarea.module.scss +307 -307
  58. package/src/css/select.module.scss +525 -525
  59. package/src/css/skeleton.module.scss +30 -30
  60. package/src/css/table.module.scss +386 -386
  61. package/src/css/tabs.module.scss +63 -63
  62. package/src/css/theme-toggle.module.scss +83 -83
  63. package/src/css/toggle.module.scss +54 -54
  64. package/src/css/tooltip.module.scss +97 -97
  65. package/src/css/topnav.module.scss +568 -568
  66. package/src/css/treeselect.module.scss +558 -558
  67. package/src/css/utilities/_borders.scss +111 -111
  68. package/src/css/utilities/_colors.scss +66 -66
  69. package/src/css/utilities/_effects.scss +216 -216
  70. package/src/css/utilities/_layout.scss +181 -181
  71. package/src/css/utilities/_position.scss +75 -75
  72. package/src/css/utilities/_sizing.scss +138 -138
  73. package/src/css/utilities/_spacing.scss +99 -99
  74. package/src/css/utilities/_typography.scss +121 -121
  75. package/src/css/utilities/index.scss +24 -24
  76. package/src/declarations.d.ts +6 -6
  77. 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
+ }