@salmexio/ui 0.3.1 → 1.0.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 (110) hide show
  1. package/README.md +52 -3
  2. package/dist/dialogs/ContextMenu/ContextMenu.svelte +96 -93
  3. package/dist/dialogs/ContextMenu/ContextMenu.svelte.d.ts +3 -2
  4. package/dist/dialogs/ContextMenu/ContextMenu.svelte.d.ts.map +1 -1
  5. package/dist/dialogs/Modal/Modal.svelte +112 -102
  6. package/dist/dialogs/Modal/Modal.svelte.d.ts +1 -1
  7. package/dist/feedback/Alert/Alert.svelte +115 -221
  8. package/dist/feedback/Alert/Alert.svelte.d.ts +1 -1
  9. package/dist/feedback/ProgressBar/ProgressBar.svelte +246 -0
  10. package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts +40 -0
  11. package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts.map +1 -0
  12. package/dist/feedback/ProgressBar/index.d.ts +2 -0
  13. package/dist/feedback/ProgressBar/index.d.ts.map +1 -0
  14. package/dist/feedback/ProgressBar/index.js +1 -0
  15. package/dist/feedback/Skeleton/Skeleton.svelte +153 -0
  16. package/dist/feedback/Skeleton/Skeleton.svelte.d.ts +37 -0
  17. package/dist/feedback/Skeleton/Skeleton.svelte.d.ts.map +1 -0
  18. package/dist/feedback/Skeleton/index.d.ts +2 -0
  19. package/dist/feedback/Skeleton/index.d.ts.map +1 -0
  20. package/dist/feedback/Skeleton/index.js +1 -0
  21. package/dist/feedback/Spinner/Spinner.svelte +88 -154
  22. package/dist/feedback/Spinner/Spinner.svelte.d.ts +5 -3
  23. package/dist/feedback/Spinner/Spinner.svelte.d.ts.map +1 -1
  24. package/dist/feedback/Toast/Toaster.svelte +431 -0
  25. package/dist/feedback/Toast/Toaster.svelte.d.ts +22 -0
  26. package/dist/feedback/Toast/Toaster.svelte.d.ts.map +1 -0
  27. package/dist/feedback/Toast/index.d.ts +4 -0
  28. package/dist/feedback/Toast/index.d.ts.map +1 -0
  29. package/dist/feedback/Toast/index.js +2 -0
  30. package/dist/feedback/Toast/toastStore.d.ts +34 -0
  31. package/dist/feedback/Toast/toastStore.d.ts.map +1 -0
  32. package/dist/feedback/Toast/toastStore.js +43 -0
  33. package/dist/feedback/index.d.ts +4 -0
  34. package/dist/feedback/index.d.ts.map +1 -1
  35. package/dist/feedback/index.js +3 -0
  36. package/dist/forms/Checkbox/Checkbox.svelte +82 -103
  37. package/dist/forms/Checkbox/Checkbox.svelte.d.ts +1 -1
  38. package/dist/forms/Select/Select.svelte +136 -177
  39. package/dist/forms/Select/Select.svelte.d.ts +1 -1
  40. package/dist/forms/Slider/Slider.svelte +356 -0
  41. package/dist/forms/Slider/Slider.svelte.d.ts +50 -0
  42. package/dist/forms/Slider/Slider.svelte.d.ts.map +1 -0
  43. package/dist/forms/Slider/index.d.ts +2 -0
  44. package/dist/forms/Slider/index.d.ts.map +1 -0
  45. package/dist/forms/Slider/index.js +1 -0
  46. package/dist/forms/TextInput/TextInput.svelte +148 -164
  47. package/dist/forms/TextInput/TextInput.svelte.d.ts +1 -1
  48. package/dist/forms/Textarea/Textarea.svelte +615 -0
  49. package/dist/forms/Textarea/Textarea.svelte.d.ts +47 -0
  50. package/dist/forms/Textarea/Textarea.svelte.d.ts.map +1 -0
  51. package/dist/forms/Textarea/index.d.ts +2 -0
  52. package/dist/forms/Textarea/index.d.ts.map +1 -0
  53. package/dist/forms/Textarea/index.js +1 -0
  54. package/dist/forms/Toggle/Toggle.svelte +239 -0
  55. package/dist/forms/Toggle/Toggle.svelte.d.ts +39 -0
  56. package/dist/forms/Toggle/Toggle.svelte.d.ts.map +1 -0
  57. package/dist/forms/Toggle/index.d.ts +2 -0
  58. package/dist/forms/Toggle/index.d.ts.map +1 -0
  59. package/dist/forms/Toggle/index.js +1 -0
  60. package/dist/forms/index.d.ts +3 -0
  61. package/dist/forms/index.d.ts.map +1 -1
  62. package/dist/forms/index.js +3 -0
  63. package/dist/index.d.ts +0 -1
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +0 -1
  66. package/dist/layout/Card/Card.svelte +64 -40
  67. package/dist/layout/Card/Card.svelte.d.ts +1 -1
  68. package/dist/layout/Card/Card.svelte.d.ts.map +1 -1
  69. package/dist/layout/Container/Container.svelte +71 -71
  70. package/dist/layout/Container/Container.svelte.d.ts +2 -2
  71. package/dist/navigation/CommandPalette/CommandPalette.svelte +410 -181
  72. package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts +8 -3
  73. package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts.map +1 -1
  74. package/dist/navigation/Tabs/Tabs.svelte +94 -178
  75. package/dist/navigation/Tabs/Tabs.svelte.d.ts +2 -2
  76. package/dist/primitives/Badge/Badge.svelte +85 -223
  77. package/dist/primitives/Badge/Badge.svelte.d.ts +2 -2
  78. package/dist/primitives/Badge/Badge.svelte.d.ts.map +1 -1
  79. package/dist/primitives/Button/Button.svelte +138 -208
  80. package/dist/primitives/Button/Button.svelte.d.ts +3 -3
  81. package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
  82. package/dist/primitives/Tooltip/Tooltip.svelte +260 -0
  83. package/dist/primitives/Tooltip/Tooltip.svelte.d.ts +36 -0
  84. package/dist/primitives/Tooltip/Tooltip.svelte.d.ts.map +1 -0
  85. package/dist/primitives/Tooltip/index.d.ts +2 -0
  86. package/dist/primitives/Tooltip/index.d.ts.map +1 -0
  87. package/dist/primitives/Tooltip/index.js +1 -0
  88. package/dist/primitives/index.d.ts +1 -0
  89. package/dist/primitives/index.d.ts.map +1 -1
  90. package/dist/primitives/index.js +1 -0
  91. package/dist/styles/tokens.css +200 -259
  92. package/package.json +5 -5
  93. package/dist/windowing/Window/Window.svelte +0 -602
  94. package/dist/windowing/Window/Window.svelte.d.ts +0 -65
  95. package/dist/windowing/Window/Window.svelte.d.ts.map +0 -1
  96. package/dist/windowing/Window/index.d.ts +0 -2
  97. package/dist/windowing/Window/index.d.ts.map +0 -1
  98. package/dist/windowing/Window/index.js +0 -1
  99. package/dist/windowing/WindowManager/WindowManager.svelte +0 -410
  100. package/dist/windowing/WindowManager/WindowManager.svelte.d.ts +0 -38
  101. package/dist/windowing/WindowManager/WindowManager.svelte.d.ts.map +0 -1
  102. package/dist/windowing/WindowManager/index.d.ts +0 -2
  103. package/dist/windowing/WindowManager/index.d.ts.map +0 -1
  104. package/dist/windowing/WindowManager/index.js +0 -1
  105. package/dist/windowing/index.d.ts +0 -5
  106. package/dist/windowing/index.d.ts.map +0 -1
  107. package/dist/windowing/index.js +0 -3
  108. package/dist/windowing/windowStore.svelte.d.ts +0 -49
  109. package/dist/windowing/windowStore.svelte.d.ts.map +0 -1
  110. package/dist/windowing/windowStore.svelte.js +0 -170
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  @component Select
3
3
 
4
- Win2K × Basquiat — Dropdown select with sunken trigger field, raised panel,
4
+ Neo-Brutalist Dark — Dropdown select with clean trigger field, glass-blur panel,
5
5
  keyboard-first navigation, type-ahead search, option groups, and multi-select.
6
6
 
7
7
  Follows WAI-ARIA APG Select-Only Combobox pattern: DOM focus stays on
@@ -219,7 +219,7 @@ function scrollActiveIntoView() {
219
219
  if (!listboxEl || activeIndex < 0) return;
220
220
  const active = listboxEl.querySelector(`[data-option-index="${activeIndex}"]`) as HTMLElement;
221
221
  if (!active) return;
222
- // Manual scroll math only scrolls the listbox, never the page
222
+ // Manual scroll math -- only scrolls the listbox, never the page
223
223
  const listTop = listboxEl.scrollTop;
224
224
  const listHeight = listboxEl.clientHeight;
225
225
  const elTop = active.offsetTop;
@@ -430,29 +430,29 @@ onMount(() => {
430
430
  </script>
431
431
 
432
432
  <div
433
- class={cn('salmex-select-wrapper', `salmex-select-${size}`, className)}
433
+ class={cn('sx-select-wrapper', `sx-select-${size}`, className)}
434
434
  data-testid={testId}
435
435
  >
436
436
  <!-- Label -->
437
437
  <label
438
438
  id={labelId}
439
439
  for={id}
440
- class={cn('salmex-select-label', hideLabel && 'salmex-sr-only')}
440
+ class={cn('sx-select-label', hideLabel && 'sx-sr-only')}
441
441
  >
442
442
  {label}
443
- {#if required}<span class="salmex-select-required" aria-hidden="true">*</span>{/if}
443
+ {#if required}<span class="sx-select-required" aria-hidden="true">*</span>{/if}
444
444
  </label>
445
445
 
446
- <!-- Trigger button DOM focus always stays here -->
446
+ <!-- Trigger button -- DOM focus always stays here -->
447
447
  <button
448
448
  bind:this={triggerEl}
449
449
  {id}
450
450
  type="button"
451
451
  class={cn(
452
- 'salmex-select-trigger',
453
- isOpen && 'salmex-select-trigger-open',
454
- showError && 'salmex-select-trigger-error',
455
- disabled && 'salmex-select-trigger-disabled'
452
+ 'sx-select-trigger',
453
+ isOpen && 'sx-select-trigger-open',
454
+ showError && 'sx-select-trigger-error',
455
+ disabled && 'sx-select-trigger-disabled'
456
456
  )}
457
457
  role="combobox"
458
458
  aria-expanded={isOpen}
@@ -467,10 +467,10 @@ onMount(() => {
467
467
  onclick={toggle}
468
468
  onkeydown={handleKeydown}
469
469
  >
470
- <span class="salmex-select-value" class:salmex-select-placeholder={!selectedOption && selectedLabels.length === 0}>
470
+ <span class="sx-select-value" class:sx-select-placeholder={!selectedOption && selectedLabels.length === 0}>
471
471
  {displayText}
472
472
  </span>
473
- <span class="salmex-select-chevron" aria-hidden="true">
473
+ <span class="sx-select-chevron" aria-hidden="true">
474
474
  <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round">
475
475
  <path d="M3 4.5L6 7.5L9 4.5" />
476
476
  </svg>
@@ -478,22 +478,22 @@ onMount(() => {
478
478
  </button>
479
479
 
480
480
  <!-- Footer: error / hint -->
481
- <div class="salmex-select-footer">
481
+ <div class="sx-select-footer">
482
482
  {#if showError}
483
- <p id={errorId} class="salmex-select-error" role="alert" aria-live="assertive">{error}</p>
483
+ <p id={errorId} class="sx-select-error" role="alert" aria-live="assertive">{error}</p>
484
484
  {:else if hint}
485
- <p id={hintId} class="salmex-select-hint">{hint}</p>
485
+ <p id={hintId} class="sx-select-hint">{hint}</p>
486
486
  {/if}
487
487
  </div>
488
488
  </div>
489
489
 
490
- <!-- Dropdown panel fixed positioning to escape overflow/stacking contexts -->
490
+ <!-- Dropdown panel -- fixed positioning to escape overflow/stacking contexts -->
491
491
  {#if isOpen}
492
492
  <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
493
493
  <div
494
494
  bind:this={listboxEl}
495
495
  id={listboxId}
496
- class="salmex-select-panel"
496
+ class="sx-select-panel"
497
497
  style="position:fixed;left:{panelLeft}px;{placeAbove ? `bottom:${window.innerHeight - panelTop}px` : `top:${panelTop}px`};width:{panelWidth}px;max-height:{panelMaxHeight}px;"
498
498
  role="listbox"
499
499
  aria-labelledby={labelId}
@@ -504,7 +504,7 @@ onMount(() => {
504
504
  {#if groups.length > 0}
505
505
  {#each groups as group, gi}
506
506
  <div role="group" aria-label={group.label}>
507
- <div class="salmex-select-group-label">{group.label}</div>
507
+ <div class="sx-select-group-label">{group.label}</div>
508
508
  {#each group.options as opt, oi}
509
509
  {@const globalIdx = getGlobalIndex(gi, oi)}
510
510
  {@const isActive = globalIdx === activeIndex}
@@ -513,10 +513,10 @@ onMount(() => {
513
513
  <div
514
514
  id={getOptionId(globalIdx)}
515
515
  class={cn(
516
- 'salmex-select-option',
517
- isActive && 'salmex-select-option-active',
518
- isSelected && 'salmex-select-option-selected',
519
- opt.disabled && 'salmex-select-option-disabled'
516
+ 'sx-select-option',
517
+ isActive && 'sx-select-option-active',
518
+ isSelected && 'sx-select-option-selected',
519
+ opt.disabled && 'sx-select-option-disabled'
520
520
  )}
521
521
  role="option"
522
522
  tabindex="-1"
@@ -527,15 +527,15 @@ onMount(() => {
527
527
  onmousedown={(e) => handleOptionMouseDown(e, opt)}
528
528
  >
529
529
  {#if multiple}
530
- <span class="salmex-select-check" aria-hidden="true">
530
+ <span class="sx-select-check" aria-hidden="true">
531
531
  {#if isSelected}
532
532
  <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M2.5 6L5 8.5L9.5 3.5" /></svg>
533
533
  {/if}
534
534
  </span>
535
535
  {/if}
536
- <span class="salmex-select-option-label">{opt.label}</span>
536
+ <span class="sx-select-option-label">{opt.label}</span>
537
537
  {#if !multiple && isSelected}
538
- <span class="salmex-select-checkmark" aria-hidden="true">
538
+ <span class="sx-select-checkmark" aria-hidden="true">
539
539
  <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M2.5 6L5 8.5L9.5 3.5" /></svg>
540
540
  </span>
541
541
  {/if}
@@ -551,10 +551,10 @@ onMount(() => {
551
551
  <div
552
552
  id={getOptionId(i)}
553
553
  class={cn(
554
- 'salmex-select-option',
555
- isActive && 'salmex-select-option-active',
556
- isSelected && 'salmex-select-option-selected',
557
- opt.disabled && 'salmex-select-option-disabled'
554
+ 'sx-select-option',
555
+ isActive && 'sx-select-option-active',
556
+ isSelected && 'sx-select-option-selected',
557
+ opt.disabled && 'sx-select-option-disabled'
558
558
  )}
559
559
  role="option"
560
560
  tabindex="-1"
@@ -565,15 +565,15 @@ onMount(() => {
565
565
  onmousedown={(e) => handleOptionMouseDown(e, opt)}
566
566
  >
567
567
  {#if multiple}
568
- <span class="salmex-select-check" aria-hidden="true">
568
+ <span class="sx-select-check" aria-hidden="true">
569
569
  {#if isSelected}
570
570
  <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M2.5 6L5 8.5L9.5 3.5" /></svg>
571
571
  {/if}
572
572
  </span>
573
573
  {/if}
574
- <span class="salmex-select-option-label">{opt.label}</span>
574
+ <span class="sx-select-option-label">{opt.label}</span>
575
575
  {#if !multiple && isSelected}
576
- <span class="salmex-select-checkmark" aria-hidden="true">
576
+ <span class="sx-select-checkmark" aria-hidden="true">
577
577
  <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M2.5 6L5 8.5L9.5 3.5" /></svg>
578
578
  </span>
579
579
  {/if}
@@ -587,30 +587,28 @@ onMount(() => {
587
587
  /* ========================================
588
588
  WRAPPER
589
589
  ======================================== */
590
- .salmex-select-wrapper {
590
+ .sx-select-wrapper {
591
591
  display: flex;
592
592
  flex-direction: column;
593
- gap: var(--salmex-space-1);
594
- font-family: var(--salmex-font-system);
593
+ gap: var(--sx-space-1);
594
+ font-family: var(--sx-font-body);
595
595
  }
596
596
 
597
597
  /* ========================================
598
598
  LABEL
599
599
  ======================================== */
600
- .salmex-select-label {
601
- font-size: var(--salmex-font-size-sm);
602
- font-weight: 700;
603
- text-transform: uppercase;
604
- letter-spacing: 0.3px;
605
- color: rgb(var(--salmex-text-primary));
600
+ .sx-select-label {
601
+ font-size: var(--sx-text-sm);
602
+ font-weight: 500;
603
+ color: var(--sx-color-text-secondary);
606
604
  }
607
605
 
608
- .salmex-select-required {
609
- color: rgb(var(--salmex-street-red));
606
+ .sx-select-required {
607
+ color: var(--sx-color-red);
610
608
  margin-left: 2px;
611
609
  }
612
610
 
613
- .salmex-sr-only {
611
+ .sx-sr-only {
614
612
  position: absolute;
615
613
  width: 1px;
616
614
  height: 1px;
@@ -623,175 +621,146 @@ onMount(() => {
623
621
  }
624
622
 
625
623
  /* ========================================
626
- TRIGGER Sunken field matching TextInput
624
+ TRIGGER -- Same style as TextInput
627
625
  ======================================== */
628
- .salmex-select-trigger {
626
+ .sx-select-trigger {
629
627
  display: flex;
630
628
  align-items: center;
631
629
  justify-content: space-between;
632
- gap: var(--salmex-space-2);
630
+ gap: var(--sx-space-2);
633
631
  width: 100%;
634
- border: 2px solid rgb(var(--salmex-border-dark));
635
- background: rgb(var(--salmex-bg-primary));
636
- color: rgb(var(--salmex-text-primary));
637
- font-family: var(--salmex-font-system);
638
- font-weight: 600;
632
+ border: 1px solid var(--sx-color-border-strong);
633
+ border-radius: var(--sx-radius-md);
634
+ background: var(--sx-color-surface);
635
+ color: var(--sx-color-text);
636
+ font-family: var(--sx-font-body);
637
+ font-weight: 500;
639
638
  cursor: pointer;
640
639
  text-align: left;
641
- transition: all var(--salmex-transition-fast);
642
- /* Sunken inset — same as TextInput */
643
- box-shadow:
644
- inset 2px 2px 0 rgb(var(--salmex-button-shadow)),
645
- inset -1px -1px 0 rgb(var(--salmex-button-highlight));
640
+ transition: border-color var(--sx-transition-fast), box-shadow var(--sx-transition-fast);
646
641
  }
647
642
 
648
- .salmex-select-trigger:hover:not(:disabled) {
649
- border-color: rgb(var(--salmex-text-primary));
643
+ .sx-select-trigger:hover:not(:disabled) {
644
+ border-color: var(--sx-color-border-hover);
650
645
  }
651
646
 
652
- .salmex-select-trigger:focus-visible {
647
+ .sx-select-trigger:focus-visible {
653
648
  outline: none;
654
- border-color: rgb(var(--salmex-text-primary));
655
- box-shadow:
656
- inset 2px 2px 0 rgb(var(--salmex-button-shadow)),
657
- inset -1px -1px 0 rgb(var(--salmex-button-highlight)),
658
- 0 0 0 2px rgb(var(--salmex-midnight-black)),
659
- 0 0 0 5px rgb(var(--salmex-crown-yellow));
649
+ border-color: var(--sx-color-cyan);
650
+ box-shadow: 0 0 0 3px var(--sx-color-cyan-ring);
660
651
  }
661
652
 
662
- :global([data-theme='dark']) .salmex-select-trigger:focus-visible {
663
- box-shadow:
664
- inset 2px 2px 0 rgb(var(--salmex-button-shadow)),
665
- inset -1px -1px 0 rgb(var(--salmex-button-highlight)),
666
- 0 0 0 3px rgb(var(--salmex-crown-yellow));
653
+ .sx-select-trigger-open {
654
+ border-color: var(--sx-color-cyan);
655
+ box-shadow: 0 0 0 3px var(--sx-color-cyan-ring);
667
656
  }
668
657
 
669
- .salmex-select-trigger-open {
670
- border-color: rgb(var(--salmex-text-primary));
658
+ .sx-select-trigger-error {
659
+ border-color: var(--sx-color-red);
660
+ box-shadow: 0 0 0 3px var(--sx-color-red-ring);
671
661
  }
672
662
 
673
- .salmex-select-trigger-error {
674
- border-color: rgb(var(--salmex-street-red));
675
- }
676
-
677
- .salmex-select-trigger-disabled {
663
+ .sx-select-trigger-disabled {
678
664
  opacity: 0.5;
679
665
  cursor: not-allowed;
680
- filter: grayscale(0.5);
681
666
  }
682
667
 
683
668
  /* ========================================
684
669
  SIZES
685
670
  ======================================== */
686
- .salmex-select-sm .salmex-select-trigger {
687
- min-height: 28px;
688
- padding: 0 var(--salmex-space-3);
689
- font-size: var(--salmex-font-size-xs);
671
+ .sx-select-sm .sx-select-trigger {
672
+ min-height: 32px;
673
+ padding: 0 var(--sx-space-3);
674
+ font-size: var(--sx-text-xs);
690
675
  }
691
676
 
692
- .salmex-select-md .salmex-select-trigger {
693
- min-height: 36px;
694
- padding: 0 var(--salmex-space-4);
695
- font-size: var(--salmex-font-size-base);
677
+ .sx-select-md .sx-select-trigger {
678
+ min-height: 40px;
679
+ padding: 0 var(--sx-space-4);
680
+ font-size: var(--sx-text-sm);
696
681
  }
697
682
 
698
- .salmex-select-lg .salmex-select-trigger {
699
- min-height: 44px;
700
- padding: 0 var(--salmex-space-5);
701
- font-size: var(--salmex-font-size-md);
683
+ .sx-select-lg .sx-select-trigger {
684
+ min-height: 48px;
685
+ padding: 0 var(--sx-space-5);
686
+ font-size: var(--sx-text-base);
702
687
  }
703
688
 
704
689
  /* ========================================
705
690
  VALUE DISPLAY
706
691
  ======================================== */
707
- .salmex-select-value {
692
+ .sx-select-value {
708
693
  flex: 1;
709
694
  overflow: hidden;
710
695
  text-overflow: ellipsis;
711
696
  white-space: nowrap;
712
697
  }
713
698
 
714
- .salmex-select-placeholder {
715
- color: rgb(var(--salmex-text-disabled));
699
+ .sx-select-placeholder {
700
+ color: var(--sx-color-text-disabled);
716
701
  }
717
702
 
718
- .salmex-select-chevron {
703
+ .sx-select-chevron {
719
704
  flex-shrink: 0;
720
705
  display: flex;
721
706
  align-items: center;
722
- transition: transform var(--salmex-transition-fast);
723
- color: rgb(var(--salmex-text-secondary));
707
+ transition: transform var(--sx-transition-fast);
708
+ color: var(--sx-color-text-secondary);
724
709
  }
725
710
 
726
- .salmex-select-trigger-open .salmex-select-chevron {
711
+ .sx-select-trigger-open .sx-select-chevron {
727
712
  transform: rotate(180deg);
728
713
  }
729
714
 
730
715
  /* ========================================
731
- DROPDOWN PANEL Raised, bold shadow, fixed position
716
+ DROPDOWN PANEL -- Glass surface, shadow, blur
732
717
  ======================================== */
733
- .salmex-select-panel {
734
- z-index: var(--salmex-z-dropdown);
718
+ .sx-select-panel {
719
+ z-index: var(--sx-z-dropdown);
735
720
  overflow-y: auto;
736
721
  overflow-x: hidden;
737
- background: rgb(var(--salmex-bg-primary));
738
- border: 3px solid rgb(var(--salmex-border-dark));
739
- box-shadow:
740
- inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
741
- inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
742
- 5px 5px 0 rgb(0 0 0 / 0.35);
722
+ background: var(--sx-color-surface-2);
723
+ border: 1px solid var(--sx-color-border-strong);
724
+ border-radius: var(--sx-radius-md);
725
+ box-shadow: var(--sx-shadow-lg);
726
+ backdrop-filter: var(--sx-glass-blur);
727
+ -webkit-backdrop-filter: var(--sx-glass-blur);
743
728
  outline: none;
744
- padding: var(--salmex-space-1) 0;
745
- font-family: var(--salmex-font-system);
746
- }
747
-
748
- :global([data-theme='dark']) .salmex-select-panel {
749
- box-shadow:
750
- inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
751
- inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
752
- 5px 5px 0 rgb(0 0 0 / 0.7);
729
+ padding: var(--sx-space-1) 0;
730
+ font-family: var(--sx-font-body);
753
731
  }
754
732
 
755
733
  /* ========================================
756
734
  OPTION
757
735
  ======================================== */
758
- .salmex-select-option {
736
+ .sx-select-option {
759
737
  display: flex;
760
738
  align-items: center;
761
- gap: var(--salmex-space-2);
762
- padding: var(--salmex-space-2) var(--salmex-space-4);
763
- font-size: var(--salmex-font-size-sm);
764
- font-weight: 600;
765
- color: rgb(var(--salmex-text-primary));
739
+ gap: var(--sx-space-2);
740
+ padding: var(--sx-space-2) var(--sx-space-4);
741
+ font-size: var(--sx-text-sm);
742
+ font-weight: 500;
743
+ color: var(--sx-color-text);
766
744
  cursor: pointer;
767
745
  user-select: none;
768
- transition: background var(--salmex-transition-fast);
769
- }
770
-
771
- .salmex-select-option-active {
772
- background: rgb(var(--salmex-electric-blue));
773
- color: rgb(var(--salmex-chalk-white));
746
+ transition: background var(--sx-transition-fast), color var(--sx-transition-fast);
774
747
  }
775
748
 
776
- :global([data-theme='dark']) .salmex-select-option-active {
777
- background: rgb(var(--salmex-primary-light));
778
- color: rgb(var(--salmex-midnight-black));
749
+ .sx-select-option-active {
750
+ background: var(--sx-color-cyan-hover);
751
+ color: var(--sx-color-cyan);
779
752
  }
780
753
 
781
- .salmex-select-option-selected:not(.salmex-select-option-active) {
782
- background: rgb(var(--salmex-electric-blue) / 0.1);
754
+ .sx-select-option-selected:not(.sx-select-option-active) {
755
+ background: var(--sx-color-cyan-subtle);
783
756
  }
784
757
 
785
- :global([data-theme='dark']) .salmex-select-option-selected:not(.salmex-select-option-active) {
786
- background: rgb(var(--salmex-primary-light) / 0.15);
787
- }
788
-
789
- .salmex-select-option-disabled {
758
+ .sx-select-option-disabled {
790
759
  opacity: 0.4;
791
760
  cursor: not-allowed;
792
761
  }
793
762
 
794
- .salmex-select-option-label {
763
+ .sx-select-option-label {
795
764
  flex: 1;
796
765
  overflow: hidden;
797
766
  text-overflow: ellipsis;
@@ -799,74 +768,64 @@ onMount(() => {
799
768
  }
800
769
 
801
770
  /* Checkmark for single select */
802
- .salmex-select-checkmark {
771
+ .sx-select-checkmark {
803
772
  flex-shrink: 0;
804
773
  display: flex;
805
774
  align-items: center;
806
- color: rgb(var(--salmex-electric-blue));
807
- }
808
-
809
- .salmex-select-option-active .salmex-select-checkmark {
810
- color: rgb(var(--salmex-chalk-white));
775
+ color: var(--sx-color-cyan);
811
776
  }
812
777
 
813
- :global([data-theme='dark']) .salmex-select-option-active .salmex-select-checkmark {
814
- color: rgb(var(--salmex-midnight-black));
778
+ .sx-select-option-active .sx-select-checkmark {
779
+ color: var(--sx-color-cyan);
815
780
  }
816
781
 
817
782
  /* Checkbox square for multi select */
818
- .salmex-select-check {
783
+ .sx-select-check {
819
784
  flex-shrink: 0;
820
785
  display: flex;
821
786
  align-items: center;
822
787
  justify-content: center;
823
788
  width: 16px;
824
789
  height: 16px;
825
- border: 2px solid rgb(var(--salmex-border-dark));
826
- background: rgb(var(--salmex-bg-primary));
827
- box-shadow:
828
- inset 1px 1px 0 rgb(var(--salmex-button-shadow)),
829
- inset -1px -1px 0 rgb(var(--salmex-button-highlight));
790
+ border: 1px solid var(--sx-color-border-strong);
791
+ border-radius: var(--sx-radius-sm);
792
+ background: var(--sx-color-surface);
830
793
  }
831
794
 
832
- .salmex-select-option-active .salmex-select-check {
833
- border-color: rgb(var(--salmex-chalk-white));
834
- }
835
-
836
- :global([data-theme='dark']) .salmex-select-option-active .salmex-select-check {
837
- border-color: rgb(var(--salmex-midnight-black));
795
+ .sx-select-option-active .sx-select-check {
796
+ border-color: var(--sx-color-cyan);
838
797
  }
839
798
 
840
799
  /* ========================================
841
800
  GROUP LABELS
842
801
  ======================================== */
843
- .salmex-select-group-label {
844
- padding: var(--salmex-space-2) var(--salmex-space-4) var(--salmex-space-1);
845
- font-size: var(--salmex-font-size-xs);
846
- font-weight: 700;
802
+ .sx-select-group-label {
803
+ padding: var(--sx-space-2) var(--sx-space-4) var(--sx-space-1);
804
+ font-size: var(--sx-text-xs);
805
+ font-weight: 600;
806
+ letter-spacing: 0.05em;
847
807
  text-transform: uppercase;
848
- letter-spacing: 0.4px;
849
- color: rgb(var(--salmex-text-secondary));
808
+ color: var(--sx-color-text-disabled);
850
809
  user-select: none;
851
810
  }
852
811
 
853
812
  /* ========================================
854
- FOOTER Error / Hint
813
+ FOOTER -- Error / Hint
855
814
  ======================================== */
856
- .salmex-select-footer {
815
+ .sx-select-footer {
857
816
  min-height: 18px;
858
817
  }
859
818
 
860
- .salmex-select-error {
861
- font-size: var(--salmex-font-size-xs);
862
- font-weight: 600;
863
- color: rgb(var(--salmex-street-red));
819
+ .sx-select-error {
820
+ font-size: var(--sx-text-xs);
821
+ font-weight: 500;
822
+ color: var(--sx-color-red);
864
823
  margin: 0;
865
824
  }
866
825
 
867
- .salmex-select-hint {
868
- font-size: var(--salmex-font-size-xs);
869
- color: rgb(var(--salmex-text-secondary));
826
+ .sx-select-hint {
827
+ font-size: var(--sx-text-xs);
828
+ color: var(--sx-color-text-secondary);
870
829
  margin: 0;
871
830
  }
872
831
 
@@ -874,9 +833,9 @@ onMount(() => {
874
833
  REDUCED MOTION
875
834
  ======================================== */
876
835
  @media (prefers-reduced-motion: reduce) {
877
- .salmex-select-trigger,
878
- .salmex-select-option,
879
- .salmex-select-chevron {
836
+ .sx-select-trigger,
837
+ .sx-select-option,
838
+ .sx-select-chevron {
880
839
  transition: none;
881
840
  }
882
841
  }
@@ -47,7 +47,7 @@ interface Props {
47
47
  /**
48
48
  * Select
49
49
  *
50
- * Win2K × Basquiat — Dropdown select with sunken trigger field, raised panel,
50
+ * Neo-Brutalist Dark — Dropdown select with clean trigger field, glass-blur panel,
51
51
  * keyboard-first navigation, type-ahead search, option groups, and multi-select.
52
52
  *
53
53
  * Follows WAI-ARIA APG Select-Only Combobox pattern: DOM focus stays on