@salmexio/ui 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +1 -1
  2. package/dist/dialogs/ContextMenu/ContextMenu.svelte +6 -6
  3. package/dist/dialogs/ContextMenu/ContextMenu.svelte.d.ts +1 -1
  4. package/dist/dialogs/Modal/Modal.svelte +3 -3
  5. package/dist/dialogs/Modal/Modal.svelte.d.ts +1 -1
  6. package/dist/feedback/Alert/Alert.svelte +16 -11
  7. package/dist/feedback/Alert/Alert.svelte.d.ts +1 -1
  8. package/dist/feedback/ProgressBar/ProgressBar.svelte +23 -4
  9. package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts +1 -1
  10. package/dist/feedback/Skeleton/Skeleton.svelte +7 -3
  11. package/dist/feedback/Skeleton/Skeleton.svelte.d.ts +1 -1
  12. package/dist/feedback/Spinner/Spinner.svelte +3 -3
  13. package/dist/feedback/Spinner/Spinner.svelte.d.ts +2 -2
  14. package/dist/feedback/Toast/Toaster.svelte +10 -10
  15. package/dist/feedback/Toast/Toaster.svelte.d.ts +1 -1
  16. package/dist/forms/Checkbox/Checkbox.svelte +13 -8
  17. package/dist/forms/Checkbox/Checkbox.svelte.d.ts +1 -1
  18. package/dist/forms/Select/Select.svelte +11 -11
  19. package/dist/forms/Select/Select.svelte.d.ts +1 -1
  20. package/dist/forms/Slider/Slider.svelte +27 -27
  21. package/dist/forms/Slider/Slider.svelte.d.ts +1 -1
  22. package/dist/forms/TextInput/TextInput.svelte +16 -6
  23. package/dist/forms/TextInput/TextInput.svelte.d.ts +1 -1
  24. package/dist/forms/Textarea/Textarea.svelte +5 -5
  25. package/dist/forms/Textarea/Textarea.svelte.d.ts +1 -1
  26. package/dist/forms/Toggle/Toggle.svelte +8 -8
  27. package/dist/forms/Toggle/Toggle.svelte.d.ts +1 -1
  28. package/dist/layout/Card/Card.svelte +6 -4
  29. package/dist/layout/Card/Card.svelte.d.ts +1 -1
  30. package/dist/layout/Container/Container.svelte +1 -1
  31. package/dist/layout/Container/Container.svelte.d.ts +1 -1
  32. package/dist/layout/ThermalBackground/ThermalBackground.svelte +313 -0
  33. package/dist/layout/ThermalBackground/ThermalBackground.svelte.d.ts +16 -0
  34. package/dist/layout/ThermalBackground/ThermalBackground.svelte.d.ts.map +1 -0
  35. package/dist/layout/ThermalBackground/index.d.ts +2 -0
  36. package/dist/layout/ThermalBackground/index.d.ts.map +1 -0
  37. package/dist/layout/ThermalBackground/index.js +1 -0
  38. package/dist/layout/index.d.ts +1 -0
  39. package/dist/layout/index.d.ts.map +1 -1
  40. package/dist/layout/index.js +1 -0
  41. package/dist/navigation/CommandPalette/CommandPalette.svelte +8 -8
  42. package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts +1 -1
  43. package/dist/navigation/Tabs/Tabs.svelte +43 -10
  44. package/dist/navigation/Tabs/Tabs.svelte.d.ts +1 -1
  45. package/dist/primitives/Badge/Badge.svelte +16 -14
  46. package/dist/primitives/Badge/Badge.svelte.d.ts +1 -1
  47. package/dist/primitives/Button/Button.svelte +87 -16
  48. package/dist/primitives/Button/Button.svelte.d.ts +1 -1
  49. package/dist/primitives/Tooltip/Tooltip.svelte +1 -1
  50. package/dist/primitives/Tooltip/Tooltip.svelte.d.ts +1 -1
  51. package/dist/styles/tokens.css +201 -64
  52. package/package.json +3 -3
@@ -0,0 +1,16 @@
1
+ interface Props {
2
+ /** Show film grain overlay */
3
+ grain?: boolean;
4
+ /** Show radar sweep line */
5
+ sweep?: boolean;
6
+ /** Blob intensity: low = barely visible, default = subtle, high = pronounced */
7
+ intensity?: 'low' | 'default' | 'high';
8
+ /** Additional CSS class */
9
+ class?: string;
10
+ /** Test ID */
11
+ testId?: string;
12
+ }
13
+ declare const ThermalBackground: import("svelte").Component<Props, {}, "">;
14
+ type ThermalBackground = ReturnType<typeof ThermalBackground>;
15
+ export default ThermalBackground;
16
+ //# sourceMappingURL=ThermalBackground.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThermalBackground.svelte.d.ts","sourceRoot":"","sources":["../../../src/layout/ThermalBackground/ThermalBackground.svelte.ts"],"names":[],"mappings":"AAGC,UAAU,KAAK;IACd,8BAA8B;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gFAAgF;IAChF,SAAS,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAuCF,QAAA,MAAM,iBAAiB,2CAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as ThermalBackground } from './ThermalBackground.svelte';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/layout/ThermalBackground/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1 @@
1
+ export { default as ThermalBackground } from './ThermalBackground.svelte';
@@ -1,3 +1,4 @@
1
1
  export { Card } from './Card/index.js';
2
2
  export { Container } from './Container/index.js';
3
+ export { ThermalBackground } from './ThermalBackground/index.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export { Card } from './Card/index.js';
2
2
  export { Container } from './Container/index.js';
3
+ export { ThermalBackground } from './ThermalBackground/index.js';
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  @component CommandPalette
3
3
 
4
- Neo-Brutalist Dark — Premium keyboard-first command launcher.
4
+ INFRARED — Premium keyboard-first command launcher.
5
5
  Glass backdrop, entrance animations, fuzzy search with match highlighting,
6
6
  categorised results, shortcut display, live result count announcements.
7
7
 
@@ -515,7 +515,7 @@ function getItemId(itemId: string): string {
515
515
  .sx-command-search-icon {
516
516
  flex-shrink: 0;
517
517
  display: flex;
518
- color: var(--sx-color-cyan);
518
+ color: var(--sx-color-primary);
519
519
  opacity: 0.7;
520
520
  }
521
521
 
@@ -639,13 +639,13 @@ function getItemId(itemId: string): string {
639
639
  }
640
640
 
641
641
  .sx-command-item-active {
642
- background: var(--sx-color-cyan-hover);
642
+ background: var(--sx-color-primary-hover);
643
643
  color: var(--sx-color-text);
644
- border-left-color: var(--sx-color-cyan);
644
+ border-left-color: var(--sx-color-primary);
645
645
  }
646
646
 
647
647
  .sx-command-item:active:not(.sx-command-item-disabled) {
648
- background: var(--sx-color-cyan-active);
648
+ background: var(--sx-color-primary-active);
649
649
  }
650
650
 
651
651
  .sx-command-item-disabled {
@@ -664,7 +664,7 @@ function getItemId(itemId: string): string {
664
664
  }
665
665
 
666
666
  .sx-command-item-active .sx-command-item-icon {
667
- color: var(--sx-color-cyan);
667
+ color: var(--sx-color-primary);
668
668
  }
669
669
 
670
670
  .sx-command-item-content {
@@ -691,12 +691,12 @@ function getItemId(itemId: string): string {
691
691
  /* Match highlighting */
692
692
  .sx-command-match {
693
693
  background: none;
694
- color: var(--sx-color-cyan);
694
+ color: var(--sx-color-primary);
695
695
  font-weight: 700;
696
696
  }
697
697
 
698
698
  .sx-command-item-active .sx-command-match {
699
- color: var(--sx-color-cyan);
699
+ color: var(--sx-color-primary);
700
700
  }
701
701
 
702
702
  .sx-command-item-desc {
@@ -30,7 +30,7 @@ interface Props {
30
30
  /**
31
31
  * CommandPalette
32
32
  *
33
- * Neo-Brutalist Dark — Premium keyboard-first command launcher.
33
+ * INFRARED — Premium keyboard-first command launcher.
34
34
  * Glass backdrop, entrance animations, fuzzy search with match highlighting,
35
35
  * categorised results, shortcut display, live result count announcements.
36
36
  *
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  @component Tabs
3
3
 
4
- Neo-Brutalist Dark tabbed interface with underline indicator.
4
+ INFRARED tabbed interface with underline indicator.
5
5
  Clean structure, dark surfaces, world-class accessibility.
6
6
 
7
7
  @example
@@ -266,23 +266,52 @@ function handleKeydown(event: KeyboardEvent, currentIndex: number) {
266
266
 
267
267
  .sx-tab:hover:not(.sx-tab-disabled):not(.sx-tab-selected) {
268
268
  color: var(--sx-color-text);
269
- background: var(--sx-color-cyan-subtle);
269
+ background: var(--sx-color-primary-subtle);
270
270
  }
271
271
 
272
272
  .sx-tab:active:not(.sx-tab-disabled):not(.sx-tab-selected) {
273
- background: var(--sx-color-cyan-hover);
273
+ background: var(--sx-color-primary-hover);
274
274
  }
275
275
 
276
- /* Selected tab — underline indicator */
276
+ /* Selected tab — underline indicator via ::after for smooth transitions */
277
277
  .sx-tab-selected {
278
278
  color: var(--sx-color-text);
279
279
  font-weight: 600;
280
- border-bottom-color: var(--sx-color-cyan);
280
+ border-bottom-color: transparent;
281
281
  }
282
282
 
283
- /* Focuscyan ring */
283
+ /* Animated underline scales in horizontally on select */
284
+ .sx-tab::after {
285
+ content: '';
286
+ position: absolute;
287
+ bottom: 0;
288
+ left: var(--sx-space-4);
289
+ right: var(--sx-space-4);
290
+ height: 2px;
291
+ background: var(--sx-color-primary);
292
+ border-radius: 1px;
293
+ transform: scaleX(0);
294
+ transform-origin: center;
295
+ transition: transform var(--sx-duration-base) var(--sx-ease-out);
296
+ }
297
+
298
+ .sx-tab-sm::after {
299
+ left: var(--sx-space-3);
300
+ right: var(--sx-space-3);
301
+ }
302
+
303
+ .sx-tab-lg::after {
304
+ left: var(--sx-space-5);
305
+ right: var(--sx-space-5);
306
+ }
307
+
308
+ .sx-tab-selected::after {
309
+ transform: scaleX(1);
310
+ }
311
+
312
+ /* Focus — primary ring */
284
313
  .sx-tab:focus-visible {
285
- outline: 2px solid var(--sx-color-cyan);
314
+ outline: 2px solid var(--sx-color-primary);
286
315
  outline-offset: -2px;
287
316
  border-radius: var(--sx-radius-sm);
288
317
  }
@@ -313,16 +342,16 @@ function handleKeydown(event: KeyboardEvent, currentIndex: number) {
313
342
  min-width: 18px;
314
343
  height: 18px;
315
344
  padding: 0 var(--sx-space-1-5);
316
- background: var(--sx-color-cyan-active);
345
+ background: var(--sx-color-primary-active);
317
346
  border: none;
318
347
  font-size: var(--sx-text-xs);
319
348
  font-weight: 600;
320
- color: var(--sx-color-cyan);
349
+ color: var(--sx-color-primary);
321
350
  border-radius: var(--sx-radius-full);
322
351
  }
323
352
 
324
353
  .sx-tab-selected .sx-tab-badge {
325
- background: rgba(0, 212, 255, 0.18);
354
+ background: rgba(255, 107, 53, 0.18);
326
355
  }
327
356
 
328
357
  /* ========================================
@@ -371,5 +400,9 @@ function handleKeydown(event: KeyboardEvent, currentIndex: number) {
371
400
  .sx-tab {
372
401
  transition: none;
373
402
  }
403
+
404
+ .sx-tab::after {
405
+ transition: none;
406
+ }
374
407
  }
375
408
  </style>
@@ -41,7 +41,7 @@ interface Props {
41
41
  /**
42
42
  * Tabs
43
43
  *
44
- * Neo-Brutalist Dark tabbed interface with underline indicator.
44
+ * INFRARED tabbed interface with underline indicator.
45
45
  * Clean structure, dark surfaces, world-class accessibility.
46
46
  *
47
47
  * @example
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  @component Badge
3
3
 
4
- Neo-Brutalist Dark — Status badge for labels, counts, and states.
4
+ INFRARED — Status badge for labels, counts, and states.
5
5
  Pill-shaped, translucent backgrounds, role="status" for screen readers.
6
6
 
7
7
  @example
@@ -90,6 +90,7 @@ let {
90
90
  transition: box-shadow var(--sx-transition-fast);
91
91
  border: 1px solid transparent;
92
92
  box-shadow: none;
93
+ animation: sx-badge-pop 200ms var(--sx-ease-spring) both;
93
94
  }
94
95
 
95
96
  /* Pill shape for all non-dot badges */
@@ -153,7 +154,7 @@ let {
153
154
  }
154
155
 
155
156
  /* ========================================
156
- STATUS VARIANTS - Neo-Brutalist Dark
157
+ STATUS VARIANTS - INFRARED
157
158
  ======================================== */
158
159
 
159
160
  /* Neutral */
@@ -167,14 +168,14 @@ let {
167
168
  border: none;
168
169
  }
169
170
 
170
- /* Primary — cyan */
171
+ /* Primary — vermilion */
171
172
  .sx-badge-primary {
172
- background: var(--sx-color-cyan-active);
173
- color: var(--sx-color-cyan);
173
+ background: var(--sx-color-primary-active);
174
+ color: var(--sx-color-primary);
174
175
  }
175
176
 
176
177
  .sx-badge-dot.sx-badge-primary {
177
- background: var(--sx-color-cyan);
178
+ background: var(--sx-color-primary);
178
179
  border: none;
179
180
  }
180
181
 
@@ -189,14 +190,14 @@ let {
189
190
  border: none;
190
191
  }
191
192
 
192
- /* Warning — gold */
193
+ /* Warning — brass */
193
194
  .sx-badge-warning {
194
- background: var(--sx-color-gold-subtle);
195
- color: var(--sx-color-gold);
195
+ background: var(--sx-color-brass-subtle);
196
+ color: var(--sx-color-secondary);
196
197
  }
197
198
 
198
199
  .sx-badge-dot.sx-badge-warning {
199
- background: var(--sx-color-gold);
200
+ background: var(--sx-color-secondary);
200
201
  border: none;
201
202
  }
202
203
 
@@ -211,14 +212,14 @@ let {
211
212
  border: none;
212
213
  }
213
214
 
214
- /* Info — purple */
215
+ /* Info — teal */
215
216
  .sx-badge-info {
216
- background: var(--sx-color-purple-subtle);
217
- color: var(--sx-color-purple);
217
+ background: var(--sx-color-teal-subtle);
218
+ color: var(--sx-color-teal);
218
219
  }
219
220
 
220
221
  .sx-badge-dot.sx-badge-info {
221
- background: var(--sx-color-purple);
222
+ background: var(--sx-color-teal);
222
223
  border: none;
223
224
  }
224
225
 
@@ -237,6 +238,7 @@ let {
237
238
  @media (prefers-reduced-motion: reduce) {
238
239
  .sx-badge {
239
240
  transition: none;
241
+ animation: none;
240
242
  }
241
243
  }
242
244
  </style>
@@ -20,7 +20,7 @@ interface Props {
20
20
  /**
21
21
  * Badge
22
22
  *
23
- * Neo-Brutalist Dark — Status badge for labels, counts, and states.
23
+ * INFRARED — Status badge for labels, counts, and states.
24
24
  * Pill-shaped, translucent backgrounds, role="status" for screen readers.
25
25
  *
26
26
  * @example
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  @component Button
3
3
 
4
- Neo-Brutalist Dark — Glassmorphism button with glow effects.
4
+ INFRARED — Glassmorphism button with glow effects.
5
5
  Clean geometry, expressive energy, world-class accessibility.
6
6
 
7
7
  @example
@@ -107,7 +107,7 @@ const isDisabled = $derived(disabled);
107
107
 
108
108
  <style>
109
109
  /* ========================================
110
- BASE BUTTON - Neo-Brutalist Dark
110
+ BASE BUTTON - INFRARED
111
111
  ======================================== */
112
112
  .sx-btn {
113
113
  position: relative;
@@ -134,11 +134,11 @@ const isDisabled = $derived(disabled);
134
134
 
135
135
  /* Focus */
136
136
  .sx-btn:focus-visible {
137
- outline: 2px solid var(--sx-color-cyan);
137
+ outline: 2px solid var(--sx-color-primary);
138
138
  outline-offset: 2px;
139
139
  }
140
140
 
141
- /* Primary focus needs white outline since cyan-on-cyan is invisible */
141
+ /* Primary focus needs white outline since vermilion-on-vermilion is invisible */
142
142
  .sx-btn-primary:focus-visible {
143
143
  outline-color: var(--sx-white);
144
144
  }
@@ -206,7 +206,7 @@ const isDisabled = $derived(disabled);
206
206
  }
207
207
 
208
208
  /* ========================================
209
- VARIANT STYLES - Neo-Brutalist Dark
209
+ VARIANT STYLES - INFRARED
210
210
  ======================================== */
211
211
 
212
212
  /* Default variant */
@@ -216,22 +216,86 @@ const isDisabled = $derived(disabled);
216
216
  border: 1px solid var(--sx-color-border-strong);
217
217
  }
218
218
 
219
- /* Primary variant — cyan glow */
219
+ /* Primary variant — Aurora grain.
220
+ Two-layer background: mostly-opaque vermilion on top with slight
221
+ edge transparency, a slow-drifting brass/teal/vermilion aurora
222
+ underneath that bleeds through at the margins. SVG noise grain
223
+ overlay for tactile feel. Breathing glow pulse at rest. */
220
224
  .sx-btn-primary {
221
- background: var(--sx-color-cyan);
225
+ background:
226
+ radial-gradient(
227
+ ellipse at center,
228
+ rgba(255, 107, 53, 0.97) 25%,
229
+ rgba(255, 107, 53, 0.82) 100%
230
+ ),
231
+ linear-gradient(
232
+ 135deg,
233
+ #C8A84E 0%,
234
+ #3D8B8B 35%,
235
+ #FF6B35 65%,
236
+ #C8A84E 100%
237
+ );
238
+ background-size: 100% 100%, 280% 280%;
222
239
  color: var(--sx-color-text-inverse);
223
240
  border: none;
224
241
  font-weight: 600;
242
+ overflow: hidden;
243
+ animation:
244
+ sx-primary-aurora 10s ease-in-out infinite,
245
+ sx-primary-glow 4s ease-in-out infinite;
246
+ }
247
+
248
+ /* Grain texture — SVG feTurbulence noise at low opacity */
249
+ .sx-btn-primary::after {
250
+ content: '';
251
+ position: absolute;
252
+ inset: 0;
253
+ border-radius: inherit;
254
+ pointer-events: none;
255
+ opacity: 0.06;
256
+ mix-blend-mode: overlay;
257
+ background: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
258
+ }
259
+
260
+ /* Aurora drift — moves the underlayer gradient position */
261
+ @keyframes sx-primary-aurora {
262
+ 0%, 100% { background-position: center, 0% 50%; }
263
+ 33% { background-position: center, 100% 0%; }
264
+ 66% { background-position: center, 50% 100%; }
265
+ }
266
+
267
+ /* Breathing glow pulse */
268
+ @keyframes sx-primary-glow {
269
+ 0%, 100% {
270
+ box-shadow:
271
+ var(--sx-shadow-sm),
272
+ 0 0 12px -3px rgba(255, 107, 53, 0.3);
273
+ }
274
+ 50% {
275
+ box-shadow:
276
+ var(--sx-shadow-sm),
277
+ 0 0 20px -2px rgba(255, 107, 53, 0.5);
278
+ }
225
279
  }
226
280
 
227
281
  .sx-btn-primary:hover:not(:disabled) {
228
282
  transform: translateY(-2px);
229
- box-shadow: var(--sx-shadow-glow-cyan);
283
+ animation:
284
+ sx-primary-aurora 10s ease-in-out infinite;
285
+ box-shadow:
286
+ var(--sx-shadow-md),
287
+ 0 0 24px -3px rgba(255, 107, 53, 0.55);
230
288
  }
231
289
 
232
290
  .sx-btn-primary:active:not(:disabled) {
233
291
  transform: translateY(0);
234
- box-shadow: var(--sx-shadow-sm);
292
+ box-shadow:
293
+ var(--sx-shadow-sm),
294
+ 0 0 8px -2px rgba(255, 107, 53, 0.2);
295
+ }
296
+
297
+ .sx-btn-primary:disabled {
298
+ animation-play-state: paused;
235
299
  }
236
300
 
237
301
  /* Ghost variant — transparent, subtle */
@@ -259,14 +323,14 @@ const isDisabled = $derived(disabled);
259
323
  .sx-btn-danger {
260
324
  background: var(--sx-color-red-hover);
261
325
  color: var(--sx-color-red);
262
- border: 1px solid rgba(255, 59, 59, 0.2);
326
+ border: 1px solid rgba(220, 38, 38, 0.2);
263
327
  }
264
328
 
265
329
  .sx-btn-danger:hover:not(:disabled) {
266
- background: rgba(255, 59, 59, 0.2);
330
+ background: rgba(220, 38, 38, 0.2);
267
331
  transform: translateY(-2px);
268
332
  box-shadow: var(--sx-shadow-glow-red);
269
- border-color: rgba(255, 59, 59, 0.4);
333
+ border-color: rgba(220, 38, 38, 0.4);
270
334
  }
271
335
 
272
336
  .sx-btn-danger:active:not(:disabled) {
@@ -302,15 +366,15 @@ const isDisabled = $derived(disabled);
302
366
  border-radius: var(--sx-radius-sm);
303
367
  }
304
368
 
305
- /* Shortcut on primary: white text on darker translucent bg */
369
+ /* Shortcut on primary: semi-transparent against the vermilion fill */
306
370
  .sx-btn-primary .sx-btn-shortcut {
307
- background: rgba(0, 0, 0, 0.3);
308
- color: var(--sx-white);
371
+ background: rgba(0, 0, 0, 0.15);
372
+ color: var(--sx-color-text-inverse);
309
373
  }
310
374
 
311
375
  /* Shortcut on danger: match the red text */
312
376
  .sx-btn-danger .sx-btn-shortcut {
313
- background: rgba(255, 59, 59, 0.15);
377
+ background: rgba(220, 38, 38, 0.15);
314
378
  color: var(--sx-color-red);
315
379
  }
316
380
 
@@ -335,5 +399,12 @@ const isDisabled = $derived(disabled);
335
399
  .sx-btn:active:not(:disabled) {
336
400
  transform: none;
337
401
  }
402
+
403
+ /* Fallback: solid vermilion, no aurora/glow animation */
404
+ .sx-btn-primary {
405
+ animation: none;
406
+ background: var(--sx-color-primary);
407
+ box-shadow: var(--sx-shadow-sm);
408
+ }
338
409
  }
339
410
  </style>
@@ -27,7 +27,7 @@ interface Props extends Omit<HTMLButtonAttributes, 'class'> {
27
27
  /**
28
28
  * Button
29
29
  *
30
- * Neo-Brutalist Dark — Glassmorphism button with glow effects.
30
+ * INFRARED — Glassmorphism button with glow effects.
31
31
  * Clean geometry, expressive energy, world-class accessibility.
32
32
  *
33
33
  * @example
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  @component Tooltip
3
3
 
4
- Neo-Brutalist Dark — Accessible tooltip with configurable placement,
4
+ INFRARED — Accessible tooltip with configurable placement,
5
5
  keyboard support, hover/focus triggers, and arrow indicator.
6
6
  Uses fixed positioning with smart viewport-aware flipping.
7
7
 
@@ -18,7 +18,7 @@ interface Props {
18
18
  /**
19
19
  * Tooltip
20
20
  *
21
- * Neo-Brutalist Dark — Accessible tooltip with configurable placement,
21
+ * INFRARED — Accessible tooltip with configurable placement,
22
22
  * keyboard support, hover/focus triggers, and arrow indicator.
23
23
  * Uses fixed positioning with smart viewport-aware flipping.
24
24
  *