@salmexio/ui 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/dialogs/ContextMenu/ContextMenu.svelte +17 -7
- package/dist/dialogs/ContextMenu/ContextMenu.svelte.d.ts +1 -1
- package/dist/dialogs/Modal/Modal.svelte +37 -4
- package/dist/dialogs/Modal/Modal.svelte.d.ts +1 -1
- package/dist/feedback/Alert/Alert.svelte +67 -19
- package/dist/feedback/Alert/Alert.svelte.d.ts +1 -1
- package/dist/feedback/ProgressBar/ProgressBar.svelte +33 -11
- package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts +3 -3
- package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts.map +1 -1
- package/dist/feedback/Skeleton/Skeleton.svelte +12 -4
- package/dist/feedback/Skeleton/Skeleton.svelte.d.ts +1 -1
- package/dist/feedback/Spinner/Spinner.svelte +5 -3
- package/dist/feedback/Spinner/Spinner.svelte.d.ts +2 -2
- package/dist/feedback/Toast/Toaster.svelte +45 -13
- package/dist/feedback/Toast/Toaster.svelte.d.ts +1 -1
- package/dist/forms/Checkbox/Checkbox.svelte +37 -9
- package/dist/forms/Checkbox/Checkbox.svelte.d.ts +1 -1
- package/dist/forms/Select/Select.svelte +28 -12
- package/dist/forms/Select/Select.svelte.d.ts +1 -1
- package/dist/forms/Slider/Slider.svelte +66 -38
- package/dist/forms/Slider/Slider.svelte.d.ts +2 -2
- package/dist/forms/Slider/Slider.svelte.d.ts.map +1 -1
- package/dist/forms/TextInput/TextInput.svelte +35 -7
- package/dist/forms/TextInput/TextInput.svelte.d.ts +1 -1
- package/dist/forms/Textarea/Textarea.svelte +22 -7
- package/dist/forms/Textarea/Textarea.svelte.d.ts +1 -1
- package/dist/forms/Toggle/Toggle.svelte +71 -12
- package/dist/forms/Toggle/Toggle.svelte.d.ts +1 -1
- package/dist/layout/Card/Card.svelte +128 -5
- package/dist/layout/Card/Card.svelte.d.ts +4 -1
- package/dist/layout/Card/Card.svelte.d.ts.map +1 -1
- package/dist/layout/Container/Container.svelte +1 -1
- package/dist/layout/Container/Container.svelte.d.ts +1 -1
- package/dist/layout/ThermalBackground/ThermalBackground.svelte +275 -0
- package/dist/layout/ThermalBackground/ThermalBackground.svelte.d.ts +14 -0
- package/dist/layout/ThermalBackground/ThermalBackground.svelte.d.ts.map +1 -0
- package/dist/layout/ThermalBackground/index.d.ts +2 -0
- package/dist/layout/ThermalBackground/index.d.ts.map +1 -0
- package/dist/layout/ThermalBackground/index.js +1 -0
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +1 -0
- package/dist/navigation/CommandPalette/CommandPalette.svelte +45 -11
- package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts +1 -1
- package/dist/navigation/NavMenu/NavMenu.svelte +800 -0
- package/dist/navigation/NavMenu/NavMenu.svelte.d.ts +81 -0
- package/dist/navigation/NavMenu/NavMenu.svelte.d.ts.map +1 -0
- package/dist/navigation/NavMenu/index.d.ts +3 -0
- package/dist/navigation/NavMenu/index.d.ts.map +1 -0
- package/dist/navigation/NavMenu/index.js +1 -0
- package/dist/navigation/Tabs/Tabs.svelte +73 -11
- package/dist/navigation/Tabs/Tabs.svelte.d.ts +1 -1
- package/dist/navigation/index.d.ts +2 -0
- package/dist/navigation/index.d.ts.map +1 -1
- package/dist/navigation/index.js +1 -0
- package/dist/primitives/Badge/Badge.svelte +68 -21
- package/dist/primitives/Badge/Badge.svelte.d.ts +1 -1
- package/dist/primitives/Button/Button.svelte +254 -34
- package/dist/primitives/Button/Button.svelte.d.ts +1 -1
- package/dist/primitives/Tooltip/Tooltip.svelte +10 -2
- package/dist/primitives/Tooltip/Tooltip.svelte.d.ts +1 -1
- package/dist/styles/tokens.css +202 -64
- package/package.json +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component TextInput
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
INFRARED — Clean text field with subtle borders and vermilion accents.
|
|
5
5
|
Label, error, hint, prefix/suffix, clearable, password toggle. Full a11y.
|
|
6
6
|
-->
|
|
7
7
|
<script lang="ts">
|
|
@@ -326,6 +326,7 @@ function handleKeyDown(e: KeyboardEvent) {
|
|
|
326
326
|
border: 0;
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
+
/* Field wrapper — recessed channel carved into the surface */
|
|
329
330
|
.sx-input-field-wrapper {
|
|
330
331
|
position: relative;
|
|
331
332
|
display: flex;
|
|
@@ -334,30 +335,48 @@ function handleKeyDown(e: KeyboardEvent) {
|
|
|
334
335
|
border: 1px solid var(--sx-color-border-strong);
|
|
335
336
|
border-radius: var(--sx-radius-md);
|
|
336
337
|
transition: border-color var(--sx-transition-fast), box-shadow var(--sx-transition-fast);
|
|
338
|
+
|
|
339
|
+
/* Recessed inset — input sits below the surface */
|
|
340
|
+
box-shadow:
|
|
341
|
+
inset 0 1px 3px rgba(0, 0, 0, 0.3),
|
|
342
|
+
inset 0 0 0 1px rgba(0, 0, 0, 0.06);
|
|
337
343
|
}
|
|
338
344
|
|
|
339
345
|
.sx-input-field-wrapper:hover:not(.sx-input-disabled-wrap):not(.sx-input-focused):not(.sx-input-error) {
|
|
340
346
|
border-color: var(--sx-color-border-hover);
|
|
341
347
|
}
|
|
342
348
|
|
|
349
|
+
/* Focus — forge glow ring replaces flat ring */
|
|
343
350
|
.sx-input-focused {
|
|
344
|
-
border-color: var(--sx-color-
|
|
345
|
-
box-shadow:
|
|
351
|
+
border-color: var(--sx-color-primary);
|
|
352
|
+
box-shadow:
|
|
353
|
+
inset 0 1px 2px rgba(0, 0, 0, 0.2),
|
|
354
|
+
0 0 0 3px var(--sx-color-primary-ring),
|
|
355
|
+
0 0 12px -4px rgba(255, 107, 53, 0.15);
|
|
356
|
+
animation: sx-focus-breathe 2s ease-in-out infinite;
|
|
346
357
|
}
|
|
347
358
|
|
|
348
359
|
.sx-input-error {
|
|
349
360
|
border-color: var(--sx-color-red);
|
|
350
|
-
box-shadow:
|
|
361
|
+
box-shadow:
|
|
362
|
+
inset 0 1px 2px rgba(0, 0, 0, 0.2),
|
|
363
|
+
0 0 0 3px var(--sx-color-red-ring),
|
|
364
|
+
0 0 10px -4px rgba(220, 38, 38, 0.15);
|
|
365
|
+
animation: sx-error-shake 300ms ease-out;
|
|
351
366
|
}
|
|
352
367
|
|
|
353
368
|
.sx-input-valid {
|
|
354
369
|
border-color: var(--sx-color-green);
|
|
370
|
+
box-shadow:
|
|
371
|
+
inset 0 1px 2px rgba(0, 0, 0, 0.2),
|
|
372
|
+
0 0 8px -4px rgba(74, 222, 128, 0.15);
|
|
355
373
|
}
|
|
356
374
|
|
|
357
375
|
.sx-input-disabled-wrap {
|
|
358
376
|
opacity: 0.5;
|
|
359
377
|
cursor: not-allowed;
|
|
360
378
|
background: var(--sx-color-surface-2);
|
|
379
|
+
box-shadow: none;
|
|
361
380
|
}
|
|
362
381
|
|
|
363
382
|
.sx-input-prefix,
|
|
@@ -476,7 +495,7 @@ function handleKeyDown(e: KeyboardEvent) {
|
|
|
476
495
|
.sx-input-loading {
|
|
477
496
|
display: flex;
|
|
478
497
|
align-items: center;
|
|
479
|
-
color: var(--sx-color-
|
|
498
|
+
color: var(--sx-color-primary);
|
|
480
499
|
}
|
|
481
500
|
|
|
482
501
|
.sx-input-spinner {
|
|
@@ -513,7 +532,7 @@ function handleKeyDown(e: KeyboardEvent) {
|
|
|
513
532
|
|
|
514
533
|
.sx-input-clear:focus-visible,
|
|
515
534
|
.sx-input-password-toggle:focus-visible {
|
|
516
|
-
outline: 2px solid var(--sx-color-
|
|
535
|
+
outline: 2px solid var(--sx-color-primary);
|
|
517
536
|
outline-offset: 2px;
|
|
518
537
|
}
|
|
519
538
|
|
|
@@ -549,12 +568,21 @@ function handleKeyDown(e: KeyboardEvent) {
|
|
|
549
568
|
}
|
|
550
569
|
|
|
551
570
|
.sx-input-charcount-warn {
|
|
552
|
-
color: var(--sx-color-
|
|
571
|
+
color: var(--sx-color-secondary);
|
|
553
572
|
}
|
|
554
573
|
|
|
555
574
|
@media (prefers-reduced-motion: reduce) {
|
|
556
575
|
.sx-input-spinner {
|
|
557
576
|
animation: none;
|
|
558
577
|
}
|
|
578
|
+
|
|
579
|
+
.sx-input-focused {
|
|
580
|
+
animation: none;
|
|
581
|
+
box-shadow: 0 0 0 3px var(--sx-color-primary-ring);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
.sx-input-error {
|
|
585
|
+
animation: none;
|
|
586
|
+
}
|
|
559
587
|
}
|
|
560
588
|
</style>
|
|
@@ -41,7 +41,7 @@ interface Props extends Omit<HTMLInputAttributes, 'class' | 'size' | 'inputmode'
|
|
|
41
41
|
/**
|
|
42
42
|
* TextInput
|
|
43
43
|
*
|
|
44
|
-
*
|
|
44
|
+
* INFRARED — Clean text field with subtle borders and vermilion accents.
|
|
45
45
|
* Label, error, hint, prefix/suffix, clearable, password toggle. Full a11y.
|
|
46
46
|
*/
|
|
47
47
|
declare const TextInput: import("svelte").Component<Props, {}, "value">;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component Textarea
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
INFRARED — Multi-line text input with custom resize handle,
|
|
5
5
|
auto-resize, character count, validation states, and full accessibility.
|
|
6
6
|
Follows TextInput visual patterns.
|
|
7
7
|
|
|
@@ -368,7 +368,7 @@ onMount(() => {
|
|
|
368
368
|
border: 0;
|
|
369
369
|
}
|
|
370
370
|
|
|
371
|
-
/* Field wrapper */
|
|
371
|
+
/* Field wrapper — recessed channel carved into the surface */
|
|
372
372
|
.sx-textarea-field-wrapper {
|
|
373
373
|
position: relative;
|
|
374
374
|
display: flex;
|
|
@@ -380,6 +380,11 @@ onMount(() => {
|
|
|
380
380
|
transition:
|
|
381
381
|
border-color var(--sx-transition-fast),
|
|
382
382
|
box-shadow var(--sx-transition-fast);
|
|
383
|
+
|
|
384
|
+
/* Recessed inset */
|
|
385
|
+
box-shadow:
|
|
386
|
+
inset 0 1px 3px rgba(0, 0, 0, 0.3),
|
|
387
|
+
inset 0 0 0 1px rgba(0, 0, 0, 0.06);
|
|
383
388
|
}
|
|
384
389
|
|
|
385
390
|
.sx-textarea-resizable {
|
|
@@ -391,23 +396,33 @@ onMount(() => {
|
|
|
391
396
|
}
|
|
392
397
|
|
|
393
398
|
.sx-textarea-focused {
|
|
394
|
-
border-color: var(--sx-color-
|
|
395
|
-
box-shadow:
|
|
399
|
+
border-color: var(--sx-color-primary);
|
|
400
|
+
box-shadow:
|
|
401
|
+
inset 0 1px 2px rgba(0, 0, 0, 0.2),
|
|
402
|
+
0 0 0 3px var(--sx-color-primary-ring),
|
|
403
|
+
0 0 12px -4px rgba(255, 107, 53, 0.15);
|
|
396
404
|
}
|
|
397
405
|
|
|
398
406
|
.sx-textarea-error-state {
|
|
399
407
|
border-color: var(--sx-color-red);
|
|
400
|
-
box-shadow:
|
|
408
|
+
box-shadow:
|
|
409
|
+
inset 0 1px 2px rgba(0, 0, 0, 0.2),
|
|
410
|
+
0 0 0 3px var(--sx-color-red-ring),
|
|
411
|
+
0 0 10px -4px rgba(220, 38, 38, 0.15);
|
|
401
412
|
}
|
|
402
413
|
|
|
403
414
|
.sx-textarea-success-state {
|
|
404
415
|
border-color: var(--sx-color-green);
|
|
416
|
+
box-shadow:
|
|
417
|
+
inset 0 1px 2px rgba(0, 0, 0, 0.2),
|
|
418
|
+
0 0 8px -4px rgba(74, 222, 128, 0.15);
|
|
405
419
|
}
|
|
406
420
|
|
|
407
421
|
.sx-textarea-disabled {
|
|
408
422
|
opacity: 0.5;
|
|
409
423
|
cursor: not-allowed;
|
|
410
424
|
background: var(--sx-color-surface-2);
|
|
425
|
+
box-shadow: none;
|
|
411
426
|
}
|
|
412
427
|
|
|
413
428
|
.sx-textarea-dragging {
|
|
@@ -480,7 +495,7 @@ onMount(() => {
|
|
|
480
495
|
}
|
|
481
496
|
|
|
482
497
|
.sx-textarea-handle-active {
|
|
483
|
-
color: var(--sx-color-
|
|
498
|
+
color: var(--sx-color-primary);
|
|
484
499
|
}
|
|
485
500
|
|
|
486
501
|
/* Vertical: bar along the bottom edge */
|
|
@@ -580,7 +595,7 @@ onMount(() => {
|
|
|
580
595
|
}
|
|
581
596
|
|
|
582
597
|
.sx-textarea-charcount-warning {
|
|
583
|
-
color: var(--sx-color-
|
|
598
|
+
color: var(--sx-color-secondary);
|
|
584
599
|
}
|
|
585
600
|
|
|
586
601
|
.sx-textarea-charcount-exceeded {
|
|
@@ -32,7 +32,7 @@ interface Props {
|
|
|
32
32
|
/**
|
|
33
33
|
* Textarea
|
|
34
34
|
*
|
|
35
|
-
*
|
|
35
|
+
* INFRARED — Multi-line text input with custom resize handle,
|
|
36
36
|
* auto-resize, character count, validation states, and full accessibility.
|
|
37
37
|
* Follows TextInput visual patterns.
|
|
38
38
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component Toggle
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
INFRARED — Accessible toggle switch with on/off states,
|
|
5
5
|
label positioning, size variants, and keyboard support.
|
|
6
6
|
Uses role="switch" with aria-checked for screen readers.
|
|
7
7
|
|
|
@@ -115,7 +115,7 @@ function toggle() {
|
|
|
115
115
|
pointer-events: none;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
/* Track */
|
|
118
|
+
/* Track — recessed channel for the physical switch */
|
|
119
119
|
.sx-toggle-track {
|
|
120
120
|
position: relative;
|
|
121
121
|
flex-shrink: 0;
|
|
@@ -130,7 +130,13 @@ function toggle() {
|
|
|
130
130
|
cursor: pointer;
|
|
131
131
|
transition:
|
|
132
132
|
background var(--sx-transition-fast),
|
|
133
|
-
border-color var(--sx-transition-fast)
|
|
133
|
+
border-color var(--sx-transition-fast),
|
|
134
|
+
box-shadow var(--sx-transition-fast);
|
|
135
|
+
|
|
136
|
+
/* Recessed inset — the track sits below the surface */
|
|
137
|
+
box-shadow:
|
|
138
|
+
inset 0 1px 3px rgba(0, 0, 0, 0.4),
|
|
139
|
+
inset 0 0 0 1px rgba(0, 0, 0, 0.1);
|
|
134
140
|
}
|
|
135
141
|
|
|
136
142
|
.sx-toggle-track:hover:not(:disabled) {
|
|
@@ -139,32 +145,80 @@ function toggle() {
|
|
|
139
145
|
|
|
140
146
|
.sx-toggle-track:focus-visible {
|
|
141
147
|
outline: none;
|
|
142
|
-
box-shadow:
|
|
148
|
+
box-shadow:
|
|
149
|
+
inset 0 1px 3px rgba(0, 0, 0, 0.4),
|
|
150
|
+
0 0 0 3px var(--sx-color-primary-ring);
|
|
143
151
|
}
|
|
144
152
|
|
|
153
|
+
/* Active track — forge glow fills the channel */
|
|
145
154
|
.sx-toggle-checked {
|
|
146
|
-
background:
|
|
147
|
-
|
|
155
|
+
background:
|
|
156
|
+
linear-gradient(
|
|
157
|
+
135deg,
|
|
158
|
+
#FF6B35 0%,
|
|
159
|
+
#C8A84E 50%,
|
|
160
|
+
#3D8B8B 100%
|
|
161
|
+
);
|
|
162
|
+
background-size: 200% 200%;
|
|
163
|
+
border-color: rgba(255, 107, 53, 0.4);
|
|
164
|
+
animation: sx-toggle-drift 6s ease-in-out infinite;
|
|
165
|
+
box-shadow:
|
|
166
|
+
inset 0 1px 2px rgba(0, 0, 0, 0.2),
|
|
167
|
+
0 0 12px -3px rgba(255, 107, 53, 0.3);
|
|
148
168
|
}
|
|
149
169
|
|
|
150
170
|
.sx-toggle-checked:hover:not(:disabled) {
|
|
151
|
-
border-color:
|
|
152
|
-
|
|
171
|
+
border-color: rgba(255, 107, 53, 0.5);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@keyframes sx-toggle-drift {
|
|
175
|
+
0%, 100% { background-position: 0% 50%; }
|
|
176
|
+
50% { background-position: 100% 50%; }
|
|
153
177
|
}
|
|
154
178
|
|
|
155
|
-
/* Thumb */
|
|
179
|
+
/* Thumb — physical raised knob with 3D depth */
|
|
156
180
|
.sx-toggle-thumb {
|
|
157
181
|
display: block;
|
|
158
182
|
width: var(--sx-toggle-thumb, 18px);
|
|
159
183
|
height: var(--sx-toggle-thumb, 18px);
|
|
160
184
|
border-radius: var(--sx-radius-full);
|
|
161
|
-
background:
|
|
162
|
-
|
|
163
|
-
|
|
185
|
+
background:
|
|
186
|
+
linear-gradient(
|
|
187
|
+
180deg,
|
|
188
|
+
rgba(255, 255, 255, 0.15) 0%,
|
|
189
|
+
transparent 50%,
|
|
190
|
+
rgba(0, 0, 0, 0.1) 100%
|
|
191
|
+
),
|
|
192
|
+
var(--sx-gray-200);
|
|
193
|
+
transition: transform 200ms var(--sx-ease-spring),
|
|
194
|
+
box-shadow 200ms var(--sx-ease-spring);
|
|
195
|
+
position: relative;
|
|
196
|
+
|
|
197
|
+
/* 3D extrusion — raised knob */
|
|
198
|
+
box-shadow:
|
|
199
|
+
0 1px 0 0 rgba(255, 255, 255, 0.2),
|
|
200
|
+
0 1px 0 0 rgba(0, 0, 0, 0.15),
|
|
201
|
+
0 2px 0 0 rgba(0, 0, 0, 0.1),
|
|
202
|
+
0 3px 4px -1px rgba(0, 0, 0, 0.3);
|
|
164
203
|
}
|
|
165
204
|
|
|
166
205
|
.sx-toggle-checked .sx-toggle-thumb {
|
|
167
206
|
transform: translateX(calc(var(--sx-toggle-w, 44px) - var(--sx-toggle-thumb, 18px) - 6px));
|
|
207
|
+
|
|
208
|
+
/* Active knob glows with forge warmth */
|
|
209
|
+
box-shadow:
|
|
210
|
+
0 1px 0 0 rgba(255, 200, 150, 0.3),
|
|
211
|
+
0 1px 0 0 rgba(0, 0, 0, 0.15),
|
|
212
|
+
0 2px 0 0 rgba(0, 0, 0, 0.1),
|
|
213
|
+
0 3px 4px -1px rgba(0, 0, 0, 0.3),
|
|
214
|
+
0 0 8px -2px rgba(255, 107, 53, 0.25);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* Press — knob pushes down */
|
|
218
|
+
.sx-toggle-track:active:not(:disabled) .sx-toggle-thumb {
|
|
219
|
+
box-shadow:
|
|
220
|
+
0 1px 0 0 rgba(0, 0, 0, 0.1),
|
|
221
|
+
0 1px 2px -1px rgba(0, 0, 0, 0.2);
|
|
168
222
|
}
|
|
169
223
|
|
|
170
224
|
/* Size variants */
|
|
@@ -216,6 +270,11 @@ function toggle() {
|
|
|
216
270
|
.sx-toggle-thumb {
|
|
217
271
|
transition: none;
|
|
218
272
|
}
|
|
273
|
+
|
|
274
|
+
.sx-toggle-checked {
|
|
275
|
+
animation: none;
|
|
276
|
+
background: var(--sx-color-primary);
|
|
277
|
+
}
|
|
219
278
|
}
|
|
220
279
|
|
|
221
280
|
@media (forced-colors: active) {
|
|
@@ -24,7 +24,7 @@ interface Props {
|
|
|
24
24
|
/**
|
|
25
25
|
* Toggle
|
|
26
26
|
*
|
|
27
|
-
*
|
|
27
|
+
* INFRARED — Accessible toggle switch with on/off states,
|
|
28
28
|
* label positioning, size variants, and keyboard support.
|
|
29
29
|
* Uses role="switch" with aria-checked for screen readers.
|
|
30
30
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component Card
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
INFRARED — Glassmorphic panel with frosted background, subtle borders.
|
|
5
5
|
Optional header/footer, semantic element support.
|
|
6
6
|
|
|
7
7
|
@example
|
|
@@ -13,9 +13,12 @@ import type { Snippet } from 'svelte';
|
|
|
13
13
|
import { cn } from '../../utils/cn.js';
|
|
14
14
|
|
|
15
15
|
type CardPadding = 'sm' | 'md' | 'lg';
|
|
16
|
+
type CardAccent = 'none' | 'primary' | 'success' | 'warning' | 'error' | 'info' | 'neutral';
|
|
16
17
|
|
|
17
18
|
interface Props {
|
|
18
19
|
padding?: CardPadding;
|
|
20
|
+
/** Left accent border color */
|
|
21
|
+
accent?: CardAccent;
|
|
19
22
|
as?: 'div' | 'article' | 'section';
|
|
20
23
|
id?: string;
|
|
21
24
|
ariaLabelledby?: string;
|
|
@@ -30,6 +33,7 @@ interface Props {
|
|
|
30
33
|
|
|
31
34
|
let {
|
|
32
35
|
padding = 'md',
|
|
36
|
+
accent = 'none',
|
|
33
37
|
as = 'div',
|
|
34
38
|
id,
|
|
35
39
|
ariaLabelledby,
|
|
@@ -82,6 +86,7 @@ const currentPadding = $derived(paddingValues[padding]);
|
|
|
82
86
|
class={cn(
|
|
83
87
|
'sx-card',
|
|
84
88
|
`sx-card-padding-${padding}`,
|
|
89
|
+
accent !== 'none' && `sx-card-accent sx-card-accent-${accent}`,
|
|
85
90
|
onclick && 'sx-card-clickable',
|
|
86
91
|
className
|
|
87
92
|
)}
|
|
@@ -112,6 +117,30 @@ const currentPadding = $derived(paddingValues[padding]);
|
|
|
112
117
|
-webkit-backdrop-filter: var(--sx-glass-blur);
|
|
113
118
|
transition: var(--sx-transition-base);
|
|
114
119
|
transition-property: transform, border-color, box-shadow;
|
|
120
|
+
|
|
121
|
+
/* 3D extrusion — subtle panel depth */
|
|
122
|
+
box-shadow:
|
|
123
|
+
0 1px 0 0 rgba(255, 255, 255, 0.03),
|
|
124
|
+
0 1px 0 0 rgba(0, 0, 0, 0.2),
|
|
125
|
+
0 2px 0 0 rgba(0, 0, 0, 0.15),
|
|
126
|
+
0 4px 8px -2px rgba(0, 0, 0, 0.3);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* Top-lit bevel — overhead light simulation */
|
|
130
|
+
.sx-card::before {
|
|
131
|
+
content: '';
|
|
132
|
+
position: absolute;
|
|
133
|
+
inset: 0;
|
|
134
|
+
border-radius: inherit;
|
|
135
|
+
pointer-events: none;
|
|
136
|
+
z-index: 0;
|
|
137
|
+
background:
|
|
138
|
+
linear-gradient(
|
|
139
|
+
180deg,
|
|
140
|
+
rgba(255, 255, 255, 0.04) 0%,
|
|
141
|
+
transparent 40%,
|
|
142
|
+
rgba(0, 0, 0, 0.06) 100%
|
|
143
|
+
);
|
|
115
144
|
}
|
|
116
145
|
|
|
117
146
|
.sx-card-clickable {
|
|
@@ -119,16 +148,100 @@ const currentPadding = $derived(paddingValues[padding]);
|
|
|
119
148
|
}
|
|
120
149
|
|
|
121
150
|
.sx-card-clickable:hover {
|
|
122
|
-
transform: translateY(-
|
|
123
|
-
border-color:
|
|
124
|
-
|
|
151
|
+
transform: translateY(-3px);
|
|
152
|
+
border-color: rgba(255, 107, 53, 0.18);
|
|
153
|
+
|
|
154
|
+
/* Hover lifts the panel — deeper extrusion + vermilion glow */
|
|
155
|
+
box-shadow:
|
|
156
|
+
0 1px 0 0 rgba(255, 255, 255, 0.04),
|
|
157
|
+
0 1px 0 0 rgba(0, 0, 0, 0.2),
|
|
158
|
+
0 2px 0 0 rgba(0, 0, 0, 0.15),
|
|
159
|
+
0 3px 0 0 rgba(0, 0, 0, 0.1),
|
|
160
|
+
0 8px 20px -4px rgba(0, 0, 0, 0.4),
|
|
161
|
+
0 0 28px -8px rgba(255, 107, 53, 0.1);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.sx-card-clickable:active {
|
|
165
|
+
transform: translateY(0);
|
|
166
|
+
box-shadow:
|
|
167
|
+
0 1px 0 0 rgba(0, 0, 0, 0.15),
|
|
168
|
+
0 2px 4px -1px rgba(0, 0, 0, 0.2);
|
|
169
|
+
transition: transform 60ms ease, box-shadow 60ms ease;
|
|
125
170
|
}
|
|
126
171
|
|
|
127
172
|
.sx-card-clickable:focus-visible {
|
|
128
|
-
outline: 2px solid var(--sx-color-
|
|
173
|
+
outline: 2px solid var(--sx-color-primary);
|
|
129
174
|
outline-offset: 2px;
|
|
130
175
|
}
|
|
131
176
|
|
|
177
|
+
/* ========================================
|
|
178
|
+
ACCENT — Left colored border with tinted extrusion
|
|
179
|
+
======================================== */
|
|
180
|
+
|
|
181
|
+
.sx-card-accent {
|
|
182
|
+
border-left: 3px solid var(--sx-color-border-strong);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Primary — vermilion */
|
|
186
|
+
.sx-card-accent-primary {
|
|
187
|
+
border-left-color: var(--sx-color-primary);
|
|
188
|
+
box-shadow:
|
|
189
|
+
0 1px 0 0 rgba(255, 255, 255, 0.03),
|
|
190
|
+
0 1px 0 0 rgba(200, 85, 30, 0.2),
|
|
191
|
+
0 2px 0 0 rgba(160, 65, 20, 0.12),
|
|
192
|
+
0 4px 8px -2px rgba(0, 0, 0, 0.3),
|
|
193
|
+
0 0 8px -4px rgba(255, 107, 53, 0.1);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* Success — green */
|
|
197
|
+
.sx-card-accent-success {
|
|
198
|
+
border-left-color: var(--sx-color-green);
|
|
199
|
+
box-shadow:
|
|
200
|
+
0 1px 0 0 rgba(255, 255, 255, 0.03),
|
|
201
|
+
0 1px 0 0 rgba(34, 120, 69, 0.2),
|
|
202
|
+
0 2px 0 0 rgba(34, 120, 69, 0.12),
|
|
203
|
+
0 4px 8px -2px rgba(0, 0, 0, 0.3),
|
|
204
|
+
0 0 8px -4px rgba(34, 197, 94, 0.1);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Warning — brass */
|
|
208
|
+
.sx-card-accent-warning {
|
|
209
|
+
border-left-color: var(--sx-color-secondary);
|
|
210
|
+
box-shadow:
|
|
211
|
+
0 1px 0 0 rgba(255, 255, 255, 0.03),
|
|
212
|
+
0 1px 0 0 rgba(160, 134, 62, 0.2),
|
|
213
|
+
0 2px 0 0 rgba(130, 108, 50, 0.12),
|
|
214
|
+
0 4px 8px -2px rgba(0, 0, 0, 0.3),
|
|
215
|
+
0 0 8px -4px rgba(200, 168, 78, 0.1);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Error — crimson */
|
|
219
|
+
.sx-card-accent-error {
|
|
220
|
+
border-left-color: var(--sx-color-red);
|
|
221
|
+
box-shadow:
|
|
222
|
+
0 1px 0 0 rgba(255, 255, 255, 0.03),
|
|
223
|
+
0 1px 0 0 rgba(180, 30, 30, 0.2),
|
|
224
|
+
0 2px 0 0 rgba(140, 20, 20, 0.12),
|
|
225
|
+
0 4px 8px -2px rgba(0, 0, 0, 0.3),
|
|
226
|
+
0 0 8px -4px rgba(220, 38, 38, 0.1);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* Info — teal */
|
|
230
|
+
.sx-card-accent-info {
|
|
231
|
+
border-left-color: var(--sx-color-teal);
|
|
232
|
+
box-shadow:
|
|
233
|
+
0 1px 0 0 rgba(255, 255, 255, 0.03),
|
|
234
|
+
0 1px 0 0 rgba(30, 80, 80, 0.2),
|
|
235
|
+
0 2px 0 0 rgba(30, 80, 80, 0.12),
|
|
236
|
+
0 4px 8px -2px rgba(0, 0, 0, 0.3),
|
|
237
|
+
0 0 8px -4px rgba(61, 139, 139, 0.1);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* Neutral */
|
|
241
|
+
.sx-card-accent-neutral {
|
|
242
|
+
border-left-color: var(--sx-color-border-strong);
|
|
243
|
+
}
|
|
244
|
+
|
|
132
245
|
@media (prefers-reduced-motion: reduce) {
|
|
133
246
|
.sx-card {
|
|
134
247
|
transition: none;
|
|
@@ -137,6 +250,10 @@ const currentPadding = $derived(paddingValues[padding]);
|
|
|
137
250
|
.sx-card-clickable:hover {
|
|
138
251
|
transform: none;
|
|
139
252
|
}
|
|
253
|
+
|
|
254
|
+
.sx-card-clickable:active {
|
|
255
|
+
transform: none;
|
|
256
|
+
}
|
|
140
257
|
}
|
|
141
258
|
|
|
142
259
|
.sx-card-padding-sm {
|
|
@@ -155,13 +272,19 @@ const currentPadding = $derived(paddingValues[padding]);
|
|
|
155
272
|
border-bottom: 1px solid var(--sx-color-border);
|
|
156
273
|
font-weight: 700;
|
|
157
274
|
letter-spacing: 0.3px;
|
|
275
|
+
position: relative;
|
|
276
|
+
z-index: 1;
|
|
158
277
|
}
|
|
159
278
|
|
|
160
279
|
.sx-card-footer {
|
|
161
280
|
border-top: 1px solid var(--sx-color-border);
|
|
281
|
+
position: relative;
|
|
282
|
+
z-index: 1;
|
|
162
283
|
}
|
|
163
284
|
|
|
164
285
|
.sx-card-content {
|
|
165
286
|
display: block;
|
|
287
|
+
position: relative;
|
|
288
|
+
z-index: 1;
|
|
166
289
|
}
|
|
167
290
|
</style>
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
type CardPadding = 'sm' | 'md' | 'lg';
|
|
3
|
+
type CardAccent = 'none' | 'primary' | 'success' | 'warning' | 'error' | 'info' | 'neutral';
|
|
3
4
|
interface Props {
|
|
4
5
|
padding?: CardPadding;
|
|
6
|
+
/** Left accent border color */
|
|
7
|
+
accent?: CardAccent;
|
|
5
8
|
as?: 'div' | 'article' | 'section';
|
|
6
9
|
id?: string;
|
|
7
10
|
ariaLabelledby?: string;
|
|
@@ -16,7 +19,7 @@ interface Props {
|
|
|
16
19
|
/**
|
|
17
20
|
* Card
|
|
18
21
|
*
|
|
19
|
-
*
|
|
22
|
+
* INFRARED — Glassmorphic panel with frosted background, subtle borders.
|
|
20
23
|
* Optional header/footer, semantic element support.
|
|
21
24
|
*
|
|
22
25
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.svelte.d.ts","sourceRoot":"","sources":["../../../src/layout/Card/Card.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAItC,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"Card.svelte.d.ts","sourceRoot":"","sources":["../../../src/layout/Card/Card.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAItC,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACtC,KAAK,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAE5F,UAAU,KAAK;IACd,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,EAAE,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAwED;;;;;;;;;GASG;AACH,QAAA,MAAM,IAAI,2CAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component Container
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
INFRARED — Responsive layout wrapper. Max-width, padding, optional centering.
|
|
5
5
|
Pure layout utility; supports semantic elements.
|
|
6
6
|
-->
|
|
7
7
|
<script lang="ts">
|
|
@@ -16,7 +16,7 @@ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'class'> {
|
|
|
16
16
|
/**
|
|
17
17
|
* Container
|
|
18
18
|
*
|
|
19
|
-
*
|
|
19
|
+
* INFRARED — Responsive layout wrapper. Max-width, padding, optional centering.
|
|
20
20
|
* Pure layout utility; supports semantic elements.
|
|
21
21
|
*/
|
|
22
22
|
declare const Container: import("svelte").Component<Props, {}, "">;
|