@marianmeres/stuic 3.0.0 → 3.0.2

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 (156) hide show
  1. package/dist/actions/index.d.ts +1 -0
  2. package/dist/actions/index.js +1 -0
  3. package/dist/actions/typeahead.svelte.d.ts +53 -0
  4. package/dist/actions/typeahead.svelte.js +328 -0
  5. package/dist/base.css +17 -0
  6. package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte +4 -3
  7. package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte.d.ts +4 -3
  8. package/dist/components/AlertConfirmPrompt/Current.svelte +1 -2
  9. package/dist/components/AlertConfirmPrompt/Current.svelte.d.ts +0 -1
  10. package/dist/components/AlertConfirmPrompt/index.css +47 -43
  11. package/dist/components/AssetsPreview/AssetsPreview.svelte +0 -1
  12. package/dist/components/AssetsPreview/AssetsPreview.svelte.d.ts +0 -1
  13. package/dist/components/AssetsPreview/index.css +31 -29
  14. package/dist/components/Avatar/Avatar.svelte +0 -1
  15. package/dist/components/Avatar/Avatar.svelte.d.ts +0 -1
  16. package/dist/components/Avatar/index.css +87 -85
  17. package/dist/components/Backdrop/Backdrop.svelte +0 -1
  18. package/dist/components/Backdrop/Backdrop.svelte.d.ts +0 -1
  19. package/dist/components/Backdrop/index.css +15 -13
  20. package/dist/components/Button/Button.svelte +0 -1
  21. package/dist/components/Button/Button.svelte.d.ts +0 -1
  22. package/dist/components/Button/index.css +431 -429
  23. package/dist/components/ButtonGroupRadio/ButtonGroupRadio.svelte +0 -1
  24. package/dist/components/ButtonGroupRadio/ButtonGroupRadio.svelte.d.ts +0 -1
  25. package/dist/components/ButtonGroupRadio/index.css +123 -117
  26. package/dist/components/Collapsible/index.css +17 -15
  27. package/dist/components/CommandMenu/CommandMenu.svelte +7 -4
  28. package/dist/components/CommandMenu/CommandMenu.svelte.d.ts +0 -1
  29. package/dist/components/CommandMenu/index.css +27 -25
  30. package/dist/components/DismissibleMessage/DismissibleMessage.svelte +0 -2
  31. package/dist/components/DismissibleMessage/DismissibleMessage.svelte.d.ts +0 -1
  32. package/dist/components/DismissibleMessage/index.css +116 -110
  33. package/dist/components/DropdownMenu/DropdownMenu.svelte +317 -74
  34. package/dist/components/DropdownMenu/DropdownMenu.svelte.d.ts +19 -1
  35. package/dist/components/DropdownMenu/index.css +236 -170
  36. package/dist/components/DropdownMenu/index.d.ts +1 -1
  37. package/dist/components/HoverExpandableWidth/HoverExpandableWidth.svelte +3 -1
  38. package/dist/components/HoverExpandableWidth/HoverExpandableWidth.svelte.d.ts +1 -0
  39. package/dist/components/Input/FieldInput.svelte +8 -0
  40. package/dist/components/Input/FieldInput.svelte.d.ts +2 -0
  41. package/dist/components/Input/FieldOptions.svelte +1 -1
  42. package/dist/components/Input/index.css +411 -398
  43. package/dist/components/KbdShortcut/KbdShortcut.svelte +4 -12
  44. package/dist/components/KbdShortcut/README.md +34 -0
  45. package/dist/components/KbdShortcut/index.css +55 -0
  46. package/dist/components/ListItemButton/ListItemButton.svelte +0 -1
  47. package/dist/components/ListItemButton/ListItemButton.svelte.d.ts +0 -1
  48. package/dist/components/ListItemButton/index.css +118 -116
  49. package/dist/components/Modal/Modal.svelte +0 -1
  50. package/dist/components/Modal/Modal.svelte.d.ts +0 -1
  51. package/dist/components/Modal/index.css +18 -16
  52. package/dist/components/ModalDialog/index.css +29 -27
  53. package/dist/components/Nav/Nav.svelte +732 -0
  54. package/dist/components/Nav/Nav.svelte.d.ts +110 -0
  55. package/dist/components/Nav/README.md +334 -0
  56. package/dist/components/Nav/index.css +318 -0
  57. package/dist/components/Nav/index.d.ts +1 -0
  58. package/dist/components/Nav/index.js +1 -0
  59. package/dist/components/Notifications/Notifications.svelte +2 -3
  60. package/dist/components/Notifications/Notifications.svelte.d.ts +0 -1
  61. package/dist/components/Notifications/index.css +158 -158
  62. package/dist/components/Notifications/notifications-stack.svelte.d.ts +4 -0
  63. package/dist/components/Notifications/notifications-stack.svelte.js +8 -0
  64. package/dist/components/Progress/Progress.svelte +4 -2
  65. package/dist/components/Progress/Progress.svelte.d.ts +1 -0
  66. package/dist/components/Progress/README.md +86 -15
  67. package/dist/components/Progress/_internal/Bar.svelte +4 -15
  68. package/dist/components/Progress/_internal/Bar.svelte.d.ts +1 -1
  69. package/dist/components/Progress/_internal/Circle.svelte +30 -2
  70. package/dist/components/Progress/_internal/Circle.svelte.d.ts +1 -0
  71. package/dist/components/Progress/index.css +47 -1
  72. package/dist/components/Skeleton/README.md +152 -0
  73. package/dist/components/Skeleton/Skeleton.svelte +6 -7
  74. package/dist/components/Skeleton/Skeleton.svelte.d.ts +0 -1
  75. package/dist/components/Skeleton/index.css +73 -43
  76. package/dist/components/Spinner/README.md +149 -37
  77. package/dist/components/Spinner/Spinner.svelte +14 -38
  78. package/dist/components/Spinner/Spinner.svelte.d.ts +2 -1
  79. package/dist/components/Spinner/SpinnerCircle.svelte +6 -34
  80. package/dist/components/Spinner/SpinnerCircle.svelte.d.ts +1 -0
  81. package/dist/components/Spinner/SpinnerCircleOscillate.svelte +10 -5
  82. package/dist/components/Spinner/SpinnerUnicode.svelte +3 -1
  83. package/dist/components/Spinner/SpinnerUnicode.svelte.d.ts +1 -0
  84. package/dist/components/Spinner/index.css +104 -0
  85. package/dist/components/Switch/README.md +34 -18
  86. package/dist/components/Switch/Switch.svelte +24 -46
  87. package/dist/components/Switch/Switch.svelte.d.ts +4 -2
  88. package/dist/components/Switch/index.css +120 -2
  89. package/dist/components/Switch/index.d.ts +1 -2
  90. package/dist/components/Switch/index.js +1 -2
  91. package/dist/components/TabbedMenu/README.md +28 -17
  92. package/dist/components/TabbedMenu/TabbedMenu.svelte +5 -46
  93. package/dist/components/TabbedMenu/TabbedMenu.svelte.d.ts +0 -1
  94. package/dist/components/TabbedMenu/index.css +85 -3
  95. package/dist/components/ThemePreview/ThemePreview.svelte +86 -33
  96. package/dist/components/ThemePreview/ThemePreview.svelte.d.ts +3 -1
  97. package/dist/components/ThemePreview/index.css +24 -8
  98. package/dist/components/TwCheck/README.md +32 -13
  99. package/dist/components/TwCheck/TwCheck.svelte +11 -9
  100. package/dist/components/TwCheck/TwCheck.svelte.d.ts +0 -1
  101. package/dist/components/TwCheck/index.css +14 -0
  102. package/dist/components/TypeaheadInput/TypeaheadInput.svelte +19 -187
  103. package/dist/components/TypeaheadInput/TypeaheadInput.svelte.d.ts +4 -2
  104. package/dist/icons/index.d.ts +1 -0
  105. package/dist/icons/index.js +1 -0
  106. package/dist/index.css +44 -39
  107. package/dist/index.d.ts +1 -0
  108. package/dist/index.js +1 -0
  109. package/dist/themes/blue-orange.css +246 -156
  110. package/dist/themes/blue-orange.js +24 -0
  111. package/dist/themes/cyan-red.css +246 -156
  112. package/dist/themes/cyan-red.js +24 -0
  113. package/dist/themes/cyan-slate.css +246 -156
  114. package/dist/themes/cyan-slate.js +25 -1
  115. package/dist/themes/emerald-pink.css +246 -156
  116. package/dist/themes/emerald-pink.js +25 -1
  117. package/dist/themes/fuchsia-emerald.css +246 -156
  118. package/dist/themes/fuchsia-emerald.js +25 -1
  119. package/dist/themes/gray.css +246 -156
  120. package/dist/themes/gray.js +24 -0
  121. package/dist/themes/indigo-amber.css +246 -156
  122. package/dist/themes/indigo-amber.js +26 -2
  123. package/dist/themes/neutral.css +246 -156
  124. package/dist/themes/neutral.js +24 -0
  125. package/dist/themes/pink-emerald.css +246 -156
  126. package/dist/themes/pink-emerald.js +25 -1
  127. package/dist/themes/pink-teal.css +253 -0
  128. package/dist/themes/pink-teal.d.ts +6 -0
  129. package/dist/themes/pink-teal.js +175 -0
  130. package/dist/themes/purple-yellow.css +246 -156
  131. package/dist/themes/purple-yellow.js +24 -0
  132. package/dist/themes/rainbow.css +246 -156
  133. package/dist/themes/rainbow.js +25 -1
  134. package/dist/themes/red-blue.css +246 -156
  135. package/dist/themes/red-blue.js +24 -0
  136. package/dist/themes/red-cyan.css +246 -156
  137. package/dist/themes/red-cyan.js +24 -0
  138. package/dist/themes/red-sky.css +253 -0
  139. package/dist/themes/red-sky.d.ts +6 -0
  140. package/dist/themes/red-sky.js +175 -0
  141. package/dist/themes/rose-teal.css +246 -156
  142. package/dist/themes/rose-teal.js +24 -0
  143. package/dist/themes/sky-amber.css +246 -156
  144. package/dist/themes/sky-amber.js +26 -2
  145. package/dist/themes/slate-cyan.css +246 -156
  146. package/dist/themes/slate-cyan.js +25 -1
  147. package/dist/themes/teal-rose.css +246 -156
  148. package/dist/themes/teal-rose.js +24 -0
  149. package/dist/themes/violet-lime.css +246 -156
  150. package/dist/themes/violet-lime.js +27 -3
  151. package/dist/utils/design-tokens.d.ts +1 -1
  152. package/dist/utils/design-tokens.js +44 -3
  153. package/dist/utils/storage-abstraction.js +1 -1
  154. package/package.json +11 -28
  155. package/dist/components/Switch/SwitchButton.svelte +0 -134
  156. package/dist/components/Switch/SwitchButton.svelte.d.ts +0 -21
@@ -46,433 +46,435 @@
46
46
  --stuic-button-raised-color: rgb(0 0 0 / 0.8);
47
47
  }
48
48
 
49
- /* ============================================================================
50
- BASE STYLES
51
- ============================================================================ */
52
-
53
- .stuic-button {
54
- /* Layout */
55
- display: inline-flex;
56
- align-items: center;
57
- justify-content: center;
58
- gap: 0.5rem;
59
-
60
- /* Typography */
61
- font-family: var(--stuic-button-font-family);
62
- font-weight: var(--stuic-button-font-weight);
63
- line-height: 1;
64
- text-align: center;
65
- text-decoration: none;
66
- white-space: nowrap;
67
-
68
- /* Box model */
69
- border-width: 1px;
70
- border-style: solid;
71
- border-radius: var(--stuic-button-radius);
72
-
73
- /* Interaction */
74
- cursor: pointer;
75
- user-select: none;
76
- -webkit-tap-highlight-color: transparent; /* Remove iOS tap highlight */
77
- touch-action: manipulation; /* Disable double-tap zoom for faster response */
78
- transition:
79
- background var(--stuic-button-transition),
80
- color var(--stuic-button-transition),
81
- border-color var(--stuic-button-transition),
82
- opacity var(--stuic-button-transition);
83
-
84
- /* Colors - use internal vars set by intent/variant */
85
- background: var(--_bg);
86
- color: var(--_text);
87
- border-color: var(--_border);
88
- }
89
-
90
- /* Focus styles */
91
- .stuic-button:focus-visible {
92
- outline: var(--stuic-button-ring-width) solid
93
- var(--_ring, var(--stuic-button-ring-color));
94
- outline-offset: var(--stuic-button-ring-offset);
95
- }
96
-
97
- /* Hover state */
98
- .stuic-button:hover:not(:disabled) {
99
- background: var(--_bg-hover);
100
- color: var(--_text-hover);
101
- border-color: var(--_border-hover);
102
- }
103
-
104
- /* Active state */
105
- .stuic-button:active:not(:disabled) {
106
- background: var(--_bg-active);
107
- color: var(--_text-active);
108
- border-color: var(--_border-active);
109
- }
110
-
111
- /* Disabled state */
112
- .stuic-button:disabled {
113
- opacity: 0.5;
114
- cursor: not-allowed;
115
- }
116
-
117
- /* ============================================================================
118
- SIZE VARIANTS
119
- ============================================================================ */
120
-
121
- .stuic-button[data-size="sm"] {
122
- padding: var(--stuic-button-padding-y-sm) var(--stuic-button-padding-x-sm);
123
- font-size: var(--stuic-button-font-size-sm);
124
- min-height: var(--stuic-button-min-height-sm);
125
- }
126
-
127
- .stuic-button[data-size="md"] {
128
- padding: var(--stuic-button-padding-y-md) var(--stuic-button-padding-x-md);
129
- font-size: var(--stuic-button-font-size-md);
130
- min-height: var(--stuic-button-min-height-md);
131
- }
132
-
133
- .stuic-button[data-size="lg"] {
134
- padding: var(--stuic-button-padding-y-lg) var(--stuic-button-padding-x-lg);
135
- font-size: var(--stuic-button-font-size-lg);
136
- min-height: var(--stuic-button-min-height-lg);
137
- }
138
-
139
- .stuic-button[data-size="xl"] {
140
- padding: var(--stuic-button-padding-y-xl) var(--stuic-button-padding-x-xl);
141
- font-size: var(--stuic-button-font-size-xl);
142
- min-height: var(--stuic-button-min-height-xl);
143
- }
144
-
145
- /* ============================================================================
146
- INTENT COLOR MAPPING
147
- Each intent sets the color palette via internal CSS vars.
148
- ============================================================================ */
149
-
150
- /* Default (no intent): neutral gray (no blue undertone) */
151
- .stuic-button:not([data-intent]) {
152
- --_color: var(--color-neutral-200);
153
- --_color-hover: var(--color-neutral-300);
154
- --_color-active: var(--color-neutral-400);
155
- --_fg: var(--color-neutral-800);
156
- --_fg-hover: var(--color-neutral-800);
157
- --_fg-active: var(--color-neutral-800);
158
- }
159
-
160
- .stuic-button[data-intent="primary"] {
161
- --_color: var(--stuic-color-primary);
162
- --_color-hover: var(--stuic-color-primary-hover);
163
- --_color-active: var(--stuic-color-primary-active);
164
- --_fg: var(--stuic-color-primary-foreground);
165
- --_fg-hover: var(--stuic-color-primary-foreground-hover);
166
- --_fg-active: var(--stuic-color-primary-foreground-active);
167
- }
168
-
169
- .stuic-button[data-intent="accent"] {
170
- --_color: var(--stuic-color-accent);
171
- --_color-hover: var(--stuic-color-accent-hover);
172
- --_color-active: var(--stuic-color-accent-active);
173
- --_fg: var(--stuic-color-accent-foreground);
174
- --_fg-hover: var(--stuic-color-accent-foreground-hover);
175
- --_fg-active: var(--stuic-color-accent-foreground-active);
176
- }
177
-
178
- .stuic-button[data-intent="destructive"] {
179
- --_color: var(--stuic-color-destructive);
180
- --_color-hover: var(--stuic-color-destructive-hover);
181
- --_color-active: var(--stuic-color-destructive-active);
182
- --_fg: var(--stuic-color-destructive-foreground);
183
- --_fg-hover: var(--stuic-color-destructive-foreground-hover);
184
- --_fg-active: var(--stuic-color-destructive-foreground-active);
185
- }
186
-
187
- .stuic-button[data-intent="warning"] {
188
- --_color: var(--stuic-color-warning);
189
- --_color-hover: var(--stuic-color-warning-hover);
190
- --_color-active: var(--stuic-color-warning-active);
191
- --_fg: var(--stuic-color-warning-foreground);
192
- --_fg-hover: var(--stuic-color-warning-foreground-hover);
193
- --_fg-active: var(--stuic-color-warning-foreground-active);
194
- }
195
-
196
- .stuic-button[data-intent="success"] {
197
- --_color: var(--stuic-color-success);
198
- --_color-hover: var(--stuic-color-success-hover);
199
- --_color-active: var(--stuic-color-success-active);
200
- --_fg: var(--stuic-color-success-foreground);
201
- --_fg-hover: var(--stuic-color-success-foreground-hover);
202
- --_fg-active: var(--stuic-color-success-foreground-active);
203
- }
204
-
205
- .stuic-button[data-intent="info"] {
206
- --_color: var(--stuic-color-info);
207
- --_color-hover: var(--stuic-color-info-hover);
208
- --_color-active: var(--stuic-color-info-active);
209
- --_fg: var(--stuic-color-info-foreground);
210
- --_fg-hover: var(--stuic-color-info-foreground-hover);
211
- --_fg-active: var(--stuic-color-info-foreground-active);
212
- }
213
-
214
- /* ============================================================================
215
- VARIANT STYLES
216
- Each variant determines HOW the color palette is applied.
217
- ============================================================================ */
218
-
219
- /* Solid (default): filled background with contrasting text */
220
- .stuic-button[data-variant="solid"],
221
- .stuic-button:not([data-variant]) {
222
- --_bg: var(--_color);
223
- --_bg-hover: var(--_color-hover);
224
- --_bg-active: var(--_color-active);
225
- --_text: var(--_fg);
226
- --_text-hover: var(--_fg-hover);
227
- --_text-active: var(--_fg-active);
228
- --_border: var(--_color);
229
- --_border-hover: var(--_color-hover);
230
- --_border-active: var(--_color-active);
231
- }
232
-
233
- /* Outline: transparent background with colored border and text */
234
- .stuic-button[data-variant="outline"] {
235
- --_bg: transparent;
236
- --_bg-hover: color-mix(in srgb, var(--_color) 10%, transparent);
237
- --_bg-active: color-mix(in srgb, var(--_color) 20%, transparent);
238
- --_text: var(--_color);
239
- --_text-hover: var(--_color-hover);
240
- --_text-active: var(--_color-active);
241
- --_border: var(--_color);
242
- --_border-hover: var(--_color-hover);
243
- --_border-active: var(--_color-active);
244
- }
245
-
246
- /* Ghost: transparent background, colored text, subtle hover state */
247
- .stuic-button[data-variant="ghost"] {
248
- --_bg: transparent;
249
- --_bg-hover: color-mix(in srgb, var(--_color) 10%, transparent);
250
- --_bg-active: color-mix(in srgb, var(--_color) 20%, transparent);
251
- --_text: var(--_color);
252
- --_text-hover: var(--_color-hover);
253
- --_text-active: var(--_color-active);
254
- --_border: transparent;
255
- --_border-hover: transparent;
256
- --_border-active: transparent;
257
- }
258
-
259
- /* Soft: muted/translucent background tint with colored text */
260
- .stuic-button[data-variant="soft"] {
261
- --_bg: color-mix(in srgb, var(--_color) 15%, transparent);
262
- --_bg-hover: color-mix(in srgb, var(--_color) 25%, transparent);
263
- --_bg-active: color-mix(in srgb, var(--_color) 35%, transparent);
264
- --_text: var(--_color);
265
- --_text-hover: var(--_color-hover);
266
- --_text-active: var(--_color-active);
267
- --_border: transparent;
268
- --_border-hover: transparent;
269
- --_border-active: transparent;
270
- }
271
-
272
- /* Link: appears as inline text link, minimal styling */
273
- .stuic-button[data-variant="link"] {
274
- --_bg: transparent;
275
- --_bg-hover: transparent;
276
- --_bg-active: transparent;
277
- --_text: var(--_color);
278
- --_text-hover: var(--_color-hover);
279
- --_text-active: var(--_color-active);
280
- --_border: transparent;
281
- --_border-hover: transparent;
282
- --_border-active: transparent;
283
- text-decoration: underline;
284
- text-underline-offset: 2px;
285
- min-height: auto;
286
- padding: 0;
287
- position: relative;
288
- }
289
-
290
- .stuic-button[data-variant="link"]::before {
291
- content: "";
292
- position: absolute;
293
- inset: -12px -8px; /* expands tap area */
294
- }
295
-
296
- /* ============================================================================
297
- DEFAULT INTENT OVERRIDES
298
- The default intent uses light surface colors - we need visible borders
299
- for solid and visible text/borders for other variants.
300
- ============================================================================ */
301
-
302
- /* Default solid: add visible border */
303
- .stuic-button:not([data-intent])[data-variant="solid"],
304
- .stuic-button:not([data-intent]):not([data-variant]) {
305
- --_border: var(--color-neutral-400);
306
- --_border-hover: var(--color-neutral-500);
307
- --_border-active: var(--color-neutral-500);
308
- }
309
-
310
- .stuic-button:not([data-intent])[data-variant="outline"] {
311
- --_text: var(--color-neutral-800);
312
- --_text-hover: var(--color-neutral-900);
313
- --_text-active: var(--color-neutral-900);
314
- --_border: var(--color-neutral-400);
315
- --_border-hover: var(--color-neutral-400);
316
- --_border-active: var(--color-neutral-500);
317
- --_bg-hover: var(--color-neutral-100);
318
- --_bg-active: var(--color-neutral-200);
319
- }
320
-
321
- .stuic-button:not([data-intent])[data-variant="ghost"] {
322
- --_text: var(--color-neutral-800);
323
- --_text-hover: var(--color-neutral-900);
324
- --_text-active: var(--color-neutral-900);
325
- --_bg-hover: var(--color-neutral-100);
326
- --_bg-active: var(--color-neutral-200);
327
- }
328
-
329
- .stuic-button:not([data-intent])[data-variant="soft"] {
330
- --_text: var(--color-neutral-800);
331
- --_text-hover: var(--color-neutral-900);
332
- --_text-active: var(--color-neutral-900);
333
- --_bg: var(--color-neutral-100);
334
- --_bg-hover: var(--color-neutral-200);
335
- --_bg-active: var(--color-neutral-300);
336
- }
337
-
338
- .stuic-button:not([data-intent])[data-variant="link"] {
339
- --_text: var(--color-neutral-700);
340
- --_text-hover: var(--color-neutral-900);
341
- --_text-active: var(--color-neutral-900);
342
- }
343
-
344
- /* ============================================================================
345
- DEFAULT INTENT DARK MODE OVERRIDES
346
- ============================================================================ */
347
-
348
- /* Default (no intent) in dark mode: lighter neutral colors */
349
- .dark .stuic-button:not([data-intent]) {
350
- --_color: var(--color-neutral-700);
351
- --_color-hover: var(--color-neutral-600);
352
- --_color-active: var(--color-neutral-500);
353
- --_fg: var(--color-neutral-100);
354
- --_fg-hover: var(--color-neutral-100);
355
- --_fg-active: var(--color-neutral-100);
356
- }
357
-
358
- /* Default solid in dark mode */
359
- .dark .stuic-button:not([data-intent])[data-variant="solid"],
360
- .dark .stuic-button:not([data-intent]):not([data-variant]) {
361
- --_border: var(--color-neutral-500);
362
- --_border-hover: var(--color-neutral-400);
363
- --_border-active: var(--color-neutral-400);
364
- }
365
-
366
- /* Default outline in dark mode */
367
- .dark .stuic-button:not([data-intent])[data-variant="outline"] {
368
- --_text: var(--color-neutral-200);
369
- --_text-hover: var(--color-neutral-100);
370
- --_text-active: var(--color-neutral-100);
371
- --_border: var(--color-neutral-500);
372
- --_border-hover: var(--color-neutral-400);
373
- --_border-active: var(--color-neutral-400);
374
- --_bg-hover: var(--color-neutral-800);
375
- --_bg-active: var(--color-neutral-700);
376
- }
377
-
378
- /* Default ghost in dark mode */
379
- .dark .stuic-button:not([data-intent])[data-variant="ghost"] {
380
- --_text: var(--color-neutral-200);
381
- --_text-hover: var(--color-neutral-100);
382
- --_text-active: var(--color-neutral-100);
383
- --_bg-hover: var(--color-neutral-800);
384
- --_bg-active: var(--color-neutral-700);
385
- }
386
-
387
- /* Default soft in dark mode */
388
- .dark .stuic-button:not([data-intent])[data-variant="soft"] {
389
- --_text: var(--color-neutral-200);
390
- --_text-hover: var(--color-neutral-100);
391
- --_text-active: var(--color-neutral-100);
392
- --_bg: var(--color-neutral-800);
393
- --_bg-hover: var(--color-neutral-700);
394
- --_bg-active: var(--color-neutral-600);
395
- }
396
-
397
- /* Default link in dark mode */
398
- .dark .stuic-button:not([data-intent])[data-variant="link"] {
399
- --_text: var(--color-neutral-300);
400
- --_text-hover: var(--color-neutral-100);
401
- --_text-active: var(--color-neutral-100);
402
- }
403
-
404
- /* ============================================================================
405
- MUTED MODIFIER
406
- ============================================================================ */
407
-
408
- .stuic-button[data-muted="true"] {
409
- opacity: 0.7;
410
- }
411
-
412
- .stuic-button[data-muted="true"]:hover:not(:disabled) {
413
- opacity: 0.85;
414
- }
415
-
416
- /* ============================================================================
417
- RAISED (3D PUSH) EFFECT
418
- Override globally: :root { --stuic-button-raised-offset: 4px; }
419
- Override locally: <Button raised style="--stuic-button-raised-offset: 5px;">
420
- ============================================================================ */
421
-
422
- .stuic-button[data-raised] {
423
- box-shadow: var(--stuic-button-raised-offset) var(--stuic-button-raised-offset) 0 0
424
- var(--stuic-button-raised-color);
425
- transition:
426
- background var(--stuic-button-transition),
427
- color var(--stuic-button-transition),
428
- border-color var(--stuic-button-transition),
429
- opacity var(--stuic-button-transition),
430
- box-shadow var(--stuic-button-transition),
431
- transform var(--stuic-button-transition);
432
- }
433
-
434
- .stuic-button[data-raised]:active:not(:disabled) {
435
- box-shadow: none;
436
- transform: translate(
437
- var(--stuic-button-raised-offset),
438
- var(--stuic-button-raised-offset)
439
- );
440
- }
441
-
442
- /* ============================================================================
443
- ROUNDED FULL
444
- ============================================================================ */
445
- .stuic-button[data-rounded-full] {
446
- --stuic-button-radius: 9999px;
447
- }
448
-
449
- /* ============================================================================
450
- SQUARED (1:1 aspect ratio)
451
- ============================================================================ */
452
- .stuic-button[data-aspect1] {
453
- aspect-ratio: 1;
454
- }
455
-
456
- .stuic-button[data-aspect1][data-size="sm"] {
457
- min-width: var(--stuic-button-min-height-sm);
458
- min-height: var(--stuic-button-min-height-sm);
459
- padding: var(--stuic-button-padding-y-sm);
460
- }
461
-
462
- .stuic-button[data-aspect1][data-size="md"] {
463
- min-width: var(--stuic-button-min-height-md);
464
- min-height: var(--stuic-button-min-height-md);
465
- padding: var(--stuic-button-padding-y-md);
466
- }
467
-
468
- .stuic-button[data-aspect1][data-size="lg"] {
469
- min-width: var(--stuic-button-min-height-lg);
470
- min-height: var(--stuic-button-min-height-lg);
471
- padding: var(--stuic-button-padding-y-lg);
472
- }
473
-
474
- .stuic-button[data-aspect1][data-size="xl"] {
475
- min-width: var(--stuic-button-min-height-xl);
476
- min-height: var(--stuic-button-min-height-xl);
477
- padding: var(--stuic-button-padding-y-xl);
49
+ @layer components {
50
+ /* ============================================================================
51
+ BASE STYLES
52
+ ============================================================================ */
53
+
54
+ .stuic-button {
55
+ /* Layout */
56
+ display: inline-flex;
57
+ align-items: center;
58
+ justify-content: center;
59
+ gap: 0.5rem;
60
+
61
+ /* Typography */
62
+ font-family: var(--stuic-button-font-family);
63
+ font-weight: var(--stuic-button-font-weight);
64
+ line-height: 1;
65
+ text-align: center;
66
+ text-decoration: none;
67
+ white-space: nowrap;
68
+
69
+ /* Box model */
70
+ border-width: 1px;
71
+ border-style: solid;
72
+ border-radius: var(--stuic-button-radius);
73
+
74
+ /* Interaction */
75
+ cursor: pointer;
76
+ user-select: none;
77
+ -webkit-tap-highlight-color: transparent; /* Remove iOS tap highlight */
78
+ touch-action: manipulation; /* Disable double-tap zoom for faster response */
79
+ transition:
80
+ background var(--stuic-button-transition),
81
+ color var(--stuic-button-transition),
82
+ border-color var(--stuic-button-transition),
83
+ opacity var(--stuic-button-transition);
84
+
85
+ /* Colors - use internal vars set by intent/variant */
86
+ background: var(--_bg);
87
+ color: var(--_text);
88
+ border-color: var(--_border);
89
+ }
90
+
91
+ /* Focus styles */
92
+ .stuic-button:focus-visible {
93
+ outline: var(--stuic-button-ring-width) solid
94
+ var(--_ring, var(--stuic-button-ring-color));
95
+ outline-offset: var(--stuic-button-ring-offset);
96
+ }
97
+
98
+ /* Hover state */
99
+ .stuic-button:hover:not(:disabled) {
100
+ background: var(--_bg-hover);
101
+ color: var(--_text-hover);
102
+ border-color: var(--_border-hover);
103
+ }
104
+
105
+ /* Active state */
106
+ .stuic-button:active:not(:disabled) {
107
+ background: var(--_bg-active);
108
+ color: var(--_text-active);
109
+ border-color: var(--_border-active);
110
+ }
111
+
112
+ /* Disabled state */
113
+ .stuic-button:disabled {
114
+ opacity: 0.5;
115
+ cursor: not-allowed;
116
+ }
117
+
118
+ /* ============================================================================
119
+ SIZE VARIANTS
120
+ ============================================================================ */
121
+
122
+ .stuic-button[data-size="sm"] {
123
+ padding: var(--stuic-button-padding-y-sm) var(--stuic-button-padding-x-sm);
124
+ font-size: var(--stuic-button-font-size-sm);
125
+ min-height: var(--stuic-button-min-height-sm);
126
+ }
127
+
128
+ .stuic-button[data-size="md"] {
129
+ padding: var(--stuic-button-padding-y-md) var(--stuic-button-padding-x-md);
130
+ font-size: var(--stuic-button-font-size-md);
131
+ min-height: var(--stuic-button-min-height-md);
132
+ }
133
+
134
+ .stuic-button[data-size="lg"] {
135
+ padding: var(--stuic-button-padding-y-lg) var(--stuic-button-padding-x-lg);
136
+ font-size: var(--stuic-button-font-size-lg);
137
+ min-height: var(--stuic-button-min-height-lg);
138
+ }
139
+
140
+ .stuic-button[data-size="xl"] {
141
+ padding: var(--stuic-button-padding-y-xl) var(--stuic-button-padding-x-xl);
142
+ font-size: var(--stuic-button-font-size-xl);
143
+ min-height: var(--stuic-button-min-height-xl);
144
+ }
145
+
146
+ /* ============================================================================
147
+ INTENT COLOR MAPPING
148
+ Each intent sets the color palette via internal CSS vars.
149
+ ============================================================================ */
150
+
151
+ /* Default (no intent): neutral gray (no blue undertone) */
152
+ .stuic-button:not([data-intent]) {
153
+ --_color: var(--color-neutral-200);
154
+ --_color-hover: var(--color-neutral-300);
155
+ --_color-active: var(--color-neutral-400);
156
+ --_fg: var(--color-neutral-800);
157
+ --_fg-hover: var(--color-neutral-800);
158
+ --_fg-active: var(--color-neutral-800);
159
+ }
160
+
161
+ .stuic-button[data-intent="primary"] {
162
+ --_color: var(--stuic-color-primary);
163
+ --_color-hover: var(--stuic-color-primary-hover);
164
+ --_color-active: var(--stuic-color-primary-active);
165
+ --_fg: var(--stuic-color-primary-foreground);
166
+ --_fg-hover: var(--stuic-color-primary-foreground-hover);
167
+ --_fg-active: var(--stuic-color-primary-foreground-active);
168
+ }
169
+
170
+ .stuic-button[data-intent="accent"] {
171
+ --_color: var(--stuic-color-accent);
172
+ --_color-hover: var(--stuic-color-accent-hover);
173
+ --_color-active: var(--stuic-color-accent-active);
174
+ --_fg: var(--stuic-color-accent-foreground);
175
+ --_fg-hover: var(--stuic-color-accent-foreground-hover);
176
+ --_fg-active: var(--stuic-color-accent-foreground-active);
177
+ }
178
+
179
+ .stuic-button[data-intent="destructive"] {
180
+ --_color: var(--stuic-color-destructive);
181
+ --_color-hover: var(--stuic-color-destructive-hover);
182
+ --_color-active: var(--stuic-color-destructive-active);
183
+ --_fg: var(--stuic-color-destructive-foreground);
184
+ --_fg-hover: var(--stuic-color-destructive-foreground-hover);
185
+ --_fg-active: var(--stuic-color-destructive-foreground-active);
186
+ }
187
+
188
+ .stuic-button[data-intent="warning"] {
189
+ --_color: var(--stuic-color-warning);
190
+ --_color-hover: var(--stuic-color-warning-hover);
191
+ --_color-active: var(--stuic-color-warning-active);
192
+ --_fg: var(--stuic-color-warning-foreground);
193
+ --_fg-hover: var(--stuic-color-warning-foreground-hover);
194
+ --_fg-active: var(--stuic-color-warning-foreground-active);
195
+ }
196
+
197
+ .stuic-button[data-intent="success"] {
198
+ --_color: var(--stuic-color-success);
199
+ --_color-hover: var(--stuic-color-success-hover);
200
+ --_color-active: var(--stuic-color-success-active);
201
+ --_fg: var(--stuic-color-success-foreground);
202
+ --_fg-hover: var(--stuic-color-success-foreground-hover);
203
+ --_fg-active: var(--stuic-color-success-foreground-active);
204
+ }
205
+
206
+ .stuic-button[data-intent="info"] {
207
+ --_color: var(--stuic-color-info);
208
+ --_color-hover: var(--stuic-color-info-hover);
209
+ --_color-active: var(--stuic-color-info-active);
210
+ --_fg: var(--stuic-color-info-foreground);
211
+ --_fg-hover: var(--stuic-color-info-foreground-hover);
212
+ --_fg-active: var(--stuic-color-info-foreground-active);
213
+ }
214
+
215
+ /* ============================================================================
216
+ VARIANT STYLES
217
+ Each variant determines HOW the color palette is applied.
218
+ ============================================================================ */
219
+
220
+ /* Solid (default): filled background with contrasting text */
221
+ .stuic-button[data-variant="solid"],
222
+ .stuic-button:not([data-variant]) {
223
+ --_bg: var(--_color);
224
+ --_bg-hover: var(--_color-hover);
225
+ --_bg-active: var(--_color-active);
226
+ --_text: var(--_fg);
227
+ --_text-hover: var(--_fg-hover);
228
+ --_text-active: var(--_fg-active);
229
+ --_border: var(--_color);
230
+ --_border-hover: var(--_color-hover);
231
+ --_border-active: var(--_color-active);
232
+ }
233
+
234
+ /* Outline: transparent background with colored border and text */
235
+ .stuic-button[data-variant="outline"] {
236
+ --_bg: transparent;
237
+ --_bg-hover: color-mix(in srgb, var(--_color) 10%, var(--stuic-color-background));
238
+ --_bg-active: color-mix(in srgb, var(--_color) 20%, var(--stuic-color-background));
239
+ --_text: var(--_color);
240
+ --_text-hover: var(--_color-hover);
241
+ --_text-active: var(--_color-active);
242
+ --_border: var(--_color);
243
+ --_border-hover: var(--_color-hover);
244
+ --_border-active: var(--_color-active);
245
+ }
246
+
247
+ /* Ghost: transparent background, colored text, subtle hover state */
248
+ .stuic-button[data-variant="ghost"] {
249
+ --_bg: transparent;
250
+ --_bg-hover: color-mix(in srgb, var(--_color) 10%, var(--stuic-color-background));
251
+ --_bg-active: color-mix(in srgb, var(--_color) 20%, var(--stuic-color-background));
252
+ --_text: var(--_color);
253
+ --_text-hover: var(--_color-hover);
254
+ --_text-active: var(--_color-active);
255
+ --_border: transparent;
256
+ --_border-hover: transparent;
257
+ --_border-active: transparent;
258
+ }
259
+
260
+ /* Soft: muted/translucent background tint with colored text */
261
+ .stuic-button[data-variant="soft"] {
262
+ --_bg: color-mix(in srgb, var(--_color) 15%, var(--stuic-color-background));
263
+ --_bg-hover: color-mix(in srgb, var(--_color) 25%, var(--stuic-color-background));
264
+ --_bg-active: color-mix(in srgb, var(--_color) 35%, var(--stuic-color-background));
265
+ --_text: var(--_color);
266
+ --_text-hover: var(--_color-hover);
267
+ --_text-active: var(--_color-active);
268
+ --_border: transparent;
269
+ --_border-hover: transparent;
270
+ --_border-active: transparent;
271
+ }
272
+
273
+ /* Link: appears as inline text link, minimal styling */
274
+ .stuic-button[data-variant="link"] {
275
+ --_bg: transparent;
276
+ --_bg-hover: transparent;
277
+ --_bg-active: transparent;
278
+ --_text: var(--_color);
279
+ --_text-hover: var(--_color-hover);
280
+ --_text-active: var(--_color-active);
281
+ --_border: transparent;
282
+ --_border-hover: transparent;
283
+ --_border-active: transparent;
284
+ text-decoration: underline;
285
+ text-underline-offset: 2px;
286
+ min-height: auto;
287
+ padding: 0;
288
+ position: relative;
289
+ }
290
+
291
+ .stuic-button[data-variant="link"]::before {
292
+ content: "";
293
+ position: absolute;
294
+ inset: -12px -8px; /* expands tap area */
295
+ }
296
+
297
+ /* ============================================================================
298
+ DEFAULT INTENT OVERRIDES
299
+ The default intent uses light surface colors - we need visible borders
300
+ for solid and visible text/borders for other variants.
301
+ ============================================================================ */
302
+
303
+ /* Default solid: add visible border */
304
+ .stuic-button:not([data-intent])[data-variant="solid"],
305
+ .stuic-button:not([data-intent]):not([data-variant]) {
306
+ --_border: var(--color-neutral-400);
307
+ --_border-hover: var(--color-neutral-500);
308
+ --_border-active: var(--color-neutral-500);
309
+ }
310
+
311
+ .stuic-button:not([data-intent])[data-variant="outline"] {
312
+ --_text: var(--color-neutral-800);
313
+ --_text-hover: var(--color-neutral-900);
314
+ --_text-active: var(--color-neutral-900);
315
+ --_border: var(--color-neutral-400);
316
+ --_border-hover: var(--color-neutral-400);
317
+ --_border-active: var(--color-neutral-500);
318
+ --_bg-hover: var(--color-neutral-100);
319
+ --_bg-active: var(--color-neutral-200);
320
+ }
321
+
322
+ .stuic-button:not([data-intent])[data-variant="ghost"] {
323
+ --_text: var(--color-neutral-800);
324
+ --_text-hover: var(--color-neutral-900);
325
+ --_text-active: var(--color-neutral-900);
326
+ --_bg-hover: var(--color-neutral-100);
327
+ --_bg-active: var(--color-neutral-200);
328
+ }
329
+
330
+ .stuic-button:not([data-intent])[data-variant="soft"] {
331
+ --_text: var(--color-neutral-800);
332
+ --_text-hover: var(--color-neutral-900);
333
+ --_text-active: var(--color-neutral-900);
334
+ --_bg: var(--color-neutral-100);
335
+ --_bg-hover: var(--color-neutral-200);
336
+ --_bg-active: var(--color-neutral-300);
337
+ }
338
+
339
+ .stuic-button:not([data-intent])[data-variant="link"] {
340
+ --_text: var(--color-neutral-700);
341
+ --_text-hover: var(--color-neutral-900);
342
+ --_text-active: var(--color-neutral-900);
343
+ }
344
+
345
+ /* ============================================================================
346
+ DEFAULT INTENT DARK MODE OVERRIDES
347
+ ============================================================================ */
348
+
349
+ /* Default (no intent) in dark mode: lighter neutral colors */
350
+ .dark .stuic-button:not([data-intent]) {
351
+ --_color: var(--color-neutral-700);
352
+ --_color-hover: var(--color-neutral-600);
353
+ --_color-active: var(--color-neutral-500);
354
+ --_fg: var(--color-neutral-100);
355
+ --_fg-hover: var(--color-neutral-100);
356
+ --_fg-active: var(--color-neutral-100);
357
+ }
358
+
359
+ /* Default solid in dark mode */
360
+ .dark .stuic-button:not([data-intent])[data-variant="solid"],
361
+ .dark .stuic-button:not([data-intent]):not([data-variant]) {
362
+ --_border: var(--color-neutral-500);
363
+ --_border-hover: var(--color-neutral-400);
364
+ --_border-active: var(--color-neutral-400);
365
+ }
366
+
367
+ /* Default outline in dark mode */
368
+ .dark .stuic-button:not([data-intent])[data-variant="outline"] {
369
+ --_text: var(--color-neutral-200);
370
+ --_text-hover: var(--color-neutral-100);
371
+ --_text-active: var(--color-neutral-100);
372
+ --_border: var(--color-neutral-500);
373
+ --_border-hover: var(--color-neutral-400);
374
+ --_border-active: var(--color-neutral-400);
375
+ --_bg-hover: var(--color-neutral-800);
376
+ --_bg-active: var(--color-neutral-700);
377
+ }
378
+
379
+ /* Default ghost in dark mode */
380
+ .dark .stuic-button:not([data-intent])[data-variant="ghost"] {
381
+ --_text: var(--color-neutral-200);
382
+ --_text-hover: var(--color-neutral-100);
383
+ --_text-active: var(--color-neutral-100);
384
+ --_bg-hover: var(--color-neutral-800);
385
+ --_bg-active: var(--color-neutral-700);
386
+ }
387
+
388
+ /* Default soft in dark mode */
389
+ .dark .stuic-button:not([data-intent])[data-variant="soft"] {
390
+ --_text: var(--color-neutral-200);
391
+ --_text-hover: var(--color-neutral-100);
392
+ --_text-active: var(--color-neutral-100);
393
+ --_bg: var(--color-neutral-800);
394
+ --_bg-hover: var(--color-neutral-700);
395
+ --_bg-active: var(--color-neutral-600);
396
+ }
397
+
398
+ /* Default link in dark mode */
399
+ .dark .stuic-button:not([data-intent])[data-variant="link"] {
400
+ --_text: var(--color-neutral-300);
401
+ --_text-hover: var(--color-neutral-100);
402
+ --_text-active: var(--color-neutral-100);
403
+ }
404
+
405
+ /* ============================================================================
406
+ MUTED MODIFIER
407
+ ============================================================================ */
408
+
409
+ .stuic-button[data-muted="true"] {
410
+ opacity: 0.7;
411
+ }
412
+
413
+ .stuic-button[data-muted="true"]:hover:not(:disabled) {
414
+ opacity: 0.85;
415
+ }
416
+
417
+ /* ============================================================================
418
+ RAISED (3D PUSH) EFFECT
419
+ Override globally: :root { --stuic-button-raised-offset: 4px; }
420
+ Override locally: <Button raised style="--stuic-button-raised-offset: 5px;">
421
+ ============================================================================ */
422
+
423
+ .stuic-button[data-raised] {
424
+ box-shadow: var(--stuic-button-raised-offset) var(--stuic-button-raised-offset) 0 0
425
+ var(--stuic-button-raised-color);
426
+ transition:
427
+ background var(--stuic-button-transition),
428
+ color var(--stuic-button-transition),
429
+ border-color var(--stuic-button-transition),
430
+ opacity var(--stuic-button-transition),
431
+ box-shadow var(--stuic-button-transition),
432
+ transform var(--stuic-button-transition);
433
+ }
434
+
435
+ .stuic-button[data-raised]:active:not(:disabled) {
436
+ box-shadow: none;
437
+ transform: translate(
438
+ var(--stuic-button-raised-offset),
439
+ var(--stuic-button-raised-offset)
440
+ );
441
+ }
442
+
443
+ /* ============================================================================
444
+ ROUNDED FULL
445
+ ============================================================================ */
446
+ .stuic-button[data-rounded-full] {
447
+ --stuic-button-radius: 9999px;
448
+ }
449
+
450
+ /* ============================================================================
451
+ SQUARED (1:1 aspect ratio)
452
+ ============================================================================ */
453
+ .stuic-button[data-aspect1] {
454
+ aspect-ratio: 1;
455
+ }
456
+
457
+ .stuic-button[data-aspect1][data-size="sm"] {
458
+ min-width: var(--stuic-button-min-height-sm);
459
+ min-height: var(--stuic-button-min-height-sm);
460
+ padding: var(--stuic-button-padding-y-sm);
461
+ }
462
+
463
+ .stuic-button[data-aspect1][data-size="md"] {
464
+ min-width: var(--stuic-button-min-height-md);
465
+ min-height: var(--stuic-button-min-height-md);
466
+ padding: var(--stuic-button-padding-y-md);
467
+ }
468
+
469
+ .stuic-button[data-aspect1][data-size="lg"] {
470
+ min-width: var(--stuic-button-min-height-lg);
471
+ min-height: var(--stuic-button-min-height-lg);
472
+ padding: var(--stuic-button-padding-y-lg);
473
+ }
474
+
475
+ .stuic-button[data-aspect1][data-size="xl"] {
476
+ min-width: var(--stuic-button-min-height-xl);
477
+ min-height: var(--stuic-button-min-height-xl);
478
+ padding: var(--stuic-button-padding-y-xl);
479
+ }
478
480
  }