soltana-ui 0.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 (104) hide show
  1. package/README.md +158 -0
  2. package/dist/config/index.d.ts +3 -0
  3. package/dist/config/index.js +7 -0
  4. package/dist/config/register.d.ts +27 -0
  5. package/dist/config/stylesheet.d.ts +13 -0
  6. package/dist/config/types.d.ts +177 -0
  7. package/dist/config/types.js +7 -0
  8. package/dist/config/validation.d.ts +29 -0
  9. package/dist/config/validation.js +59 -0
  10. package/dist/enhancers/accordion.d.ts +19 -0
  11. package/dist/enhancers/carousel.d.ts +21 -0
  12. package/dist/enhancers/collapsible.d.ts +14 -0
  13. package/dist/enhancers/color-picker.d.ts +20 -0
  14. package/dist/enhancers/combobox.d.ts +17 -0
  15. package/dist/enhancers/context-menu.d.ts +19 -0
  16. package/dist/enhancers/date-picker.d.ts +8 -0
  17. package/dist/enhancers/drawer.d.ts +11 -0
  18. package/dist/enhancers/dropdown.d.ts +17 -0
  19. package/dist/enhancers/hover-card.d.ts +15 -0
  20. package/dist/enhancers/index.d.ts +42 -0
  21. package/dist/enhancers/modal.d.ts +16 -0
  22. package/dist/enhancers/scroll-area.d.ts +14 -0
  23. package/dist/enhancers/tabs.d.ts +26 -0
  24. package/dist/enhancers/test-helpers.d.ts +20 -0
  25. package/dist/enhancers/test-utils.d.ts +10 -0
  26. package/dist/enhancers/toast.d.ts +24 -0
  27. package/dist/enhancers/tooltip.d.ts +15 -0
  28. package/dist/enhancers/tree.d.ts +24 -0
  29. package/dist/enhancers/utils/click-away.d.ts +7 -0
  30. package/dist/enhancers/utils/create-overlay-enhancer.d.ts +14 -0
  31. package/dist/enhancers/utils/focus-trap.d.ts +9 -0
  32. package/dist/enhancers/utils/generate-id.d.ts +6 -0
  33. package/dist/enhancers/utils/keyboard-nav.d.ts +21 -0
  34. package/dist/enhancers/utils/position.d.ts +30 -0
  35. package/dist/fonts/index.d.ts +20 -0
  36. package/dist/index.d.ts +9 -0
  37. package/dist/init.d.ts +16 -0
  38. package/dist/plugins/index.d.ts +2 -0
  39. package/dist/plugins/index.js +1 -0
  40. package/dist/plugins/postcss-soltana-treeshake.d.ts +10 -0
  41. package/dist/plugins/postcss-soltana-treeshake.js +149 -0
  42. package/dist/plugins/types.d.ts +9 -0
  43. package/dist/plugins/types.js +4 -0
  44. package/dist/soltana-ui.css +1 -0
  45. package/dist/soltana-ui.js +1702 -0
  46. package/dist/soltana-ui.umd.cjs +1 -0
  47. package/package.json +90 -0
  48. package/src/styles/_variables.scss +348 -0
  49. package/src/styles/base/_accessibility.scss +146 -0
  50. package/src/styles/base/_index.scss +12 -0
  51. package/src/styles/base/_register.scss +84 -0
  52. package/src/styles/base/_relief-system.scss +53 -0
  53. package/src/styles/base/_scrollbar.scss +40 -0
  54. package/src/styles/base/_transitions.scss +75 -0
  55. package/src/styles/base/_typography.scss +442 -0
  56. package/src/styles/components/_alert-dialogs.scss +75 -0
  57. package/src/styles/components/_badges.scss +215 -0
  58. package/src/styles/components/_buttons.scss +293 -0
  59. package/src/styles/components/_callouts.scss +99 -0
  60. package/src/styles/components/_cards.scss +97 -0
  61. package/src/styles/components/_carousels.scss +108 -0
  62. package/src/styles/components/_closes.scss +63 -0
  63. package/src/styles/components/_code.scss +75 -0
  64. package/src/styles/components/_collapsibles.scss +61 -0
  65. package/src/styles/components/_color-pickers.scss +211 -0
  66. package/src/styles/components/_comboboxes.scss +88 -0
  67. package/src/styles/components/_context-menus.scss +82 -0
  68. package/src/styles/components/_date-pickers.scss +165 -0
  69. package/src/styles/components/_feedback.scss +354 -0
  70. package/src/styles/components/_figures.scss +52 -0
  71. package/src/styles/components/_heros.scss +83 -0
  72. package/src/styles/components/_hover-cards.scss +55 -0
  73. package/src/styles/components/_images.scss +71 -0
  74. package/src/styles/components/_index.scss +41 -0
  75. package/src/styles/components/_indicators.scss +403 -0
  76. package/src/styles/components/_inputs.scss +409 -0
  77. package/src/styles/components/_layouts.scss +139 -0
  78. package/src/styles/components/_lists.scss +135 -0
  79. package/src/styles/components/_menus.scss +195 -0
  80. package/src/styles/components/_navigation.scss +325 -0
  81. package/src/styles/components/_overlays.scss +233 -0
  82. package/src/styles/components/_scroll-areas.scss +53 -0
  83. package/src/styles/components/_segmented-controls.scss +75 -0
  84. package/src/styles/components/_tables.scss +137 -0
  85. package/src/styles/components/_toasts.scss +111 -0
  86. package/src/styles/components/_toggles.scss +57 -0
  87. package/src/styles/components/_trees.scss +123 -0
  88. package/src/styles/decorative/_classical.scss +196 -0
  89. package/src/styles/decorative/_index.scss +7 -0
  90. package/src/styles/finishes/_index.scss +55 -0
  91. package/src/styles/index.scss +30 -0
  92. package/src/styles/reliefs/_index.scss +66 -0
  93. package/src/styles/reliefs/_neumorphic-tables.scss +92 -0
  94. package/src/styles/themes/_dark.scss +130 -0
  95. package/src/styles/themes/_index.scss +3 -0
  96. package/src/styles/themes/_light.scss +122 -0
  97. package/src/styles/themes/_sepia.scss +121 -0
  98. package/src/styles/utilities/_index.scss +13 -0
  99. package/src/styles/utilities/_layout.scss +100 -0
  100. package/src/styles/utilities/_mixins.scss +410 -0
  101. package/src/styles/utilities/_responsive.scss +46 -0
  102. package/src/styles/utilities/_sizing.scss +62 -0
  103. package/src/styles/utilities/_spacing.scss +12 -0
  104. package/src/styles/utilities/_visual.scss +436 -0
@@ -0,0 +1,233 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Overlay Components
3
+ // ---------------------------------------------------------------------------
4
+ // Modals, drawers, and backdrop styles.
5
+ // Uses --relief-* variables for automatic relief switching.
6
+ // ---------------------------------------------------------------------------
7
+
8
+ @use '../base/register' as *;
9
+
10
+ // ============================================================================
11
+ // SHARED OVERLAY PLACEHOLDERS
12
+ // ============================================================================
13
+
14
+ %overlay-backdrop {
15
+ position: fixed;
16
+ inset: 0;
17
+ background: var(--overlay-backdrop-bg);
18
+ backdrop-filter: blur(var(--finish-blur, 8px));
19
+ opacity: 0;
20
+ pointer-events: none;
21
+ transition: opacity var(--transition-slow) var(--easing-in-out);
22
+
23
+ &.active {
24
+ opacity: 1;
25
+ pointer-events: auto;
26
+ }
27
+ }
28
+
29
+ %overlay-header {
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: space-between;
33
+ padding: 1.25rem 1.5rem;
34
+ border-bottom: 1px solid var(--border-default);
35
+ font-weight: var(--font-bold);
36
+ font-size: var(--text-lg);
37
+ letter-spacing: var(--tracking-elegant);
38
+ }
39
+
40
+ %overlay-body {
41
+ padding: 1.5rem;
42
+ }
43
+
44
+ %overlay-footer {
45
+ display: flex;
46
+ justify-content: flex-end;
47
+ gap: 0.75rem;
48
+ padding: 1rem 1.5rem;
49
+ border-top: 1px solid var(--border-default);
50
+ }
51
+
52
+ // ============================================================================
53
+ // MODAL SCROLL LOCK
54
+ // ============================================================================
55
+
56
+ .sol-modal-open {
57
+ overflow: hidden;
58
+ }
59
+
60
+ // ============================================================================
61
+ // MODAL BACKDROP
62
+ // ============================================================================
63
+
64
+ .modal-backdrop {
65
+ @extend %overlay-backdrop;
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ z-index: var(--z-modal);
70
+ }
71
+
72
+ // ============================================================================
73
+ // MODAL
74
+ // ============================================================================
75
+
76
+ .modal {
77
+ position: relative;
78
+ @include relief-container((var(--relief-shadow), 0 24px 64px rgb(var(--shadow-color) / 30%)));
79
+ outline: 1px solid var(--border-subtle);
80
+ outline-offset: 4px;
81
+ border-radius: var(--radius-2xl);
82
+ @include finish-surface(var(--modal-bg));
83
+ width: 100%;
84
+ max-width: 32rem;
85
+ max-height: 85vh;
86
+ overflow-y: auto;
87
+ transform: scale(0.95) translateY(10px);
88
+ transition: transform var(--transition-slow) var(--easing-in-out);
89
+
90
+ &.active {
91
+ transform: scale(1) translateY(0);
92
+ }
93
+ }
94
+
95
+ .modal-header {
96
+ @extend %overlay-header;
97
+ }
98
+
99
+ .modal-body {
100
+ @extend %overlay-body;
101
+ }
102
+
103
+ .modal-footer {
104
+ @extend %overlay-footer;
105
+ }
106
+
107
+ // ============================================================================
108
+ // MODAL SIZES
109
+ // ============================================================================
110
+
111
+ .modal-sm {
112
+ max-width: 28rem;
113
+ }
114
+
115
+ .modal-lg {
116
+ max-width: 48rem;
117
+ }
118
+
119
+ // ============================================================================
120
+ // DRAWER BACKDROP
121
+ // ============================================================================
122
+
123
+ .drawer-backdrop {
124
+ @extend %overlay-backdrop;
125
+ z-index: var(--z-drawer);
126
+ }
127
+
128
+ // ============================================================================
129
+ // DRAWER
130
+ // ============================================================================
131
+
132
+ .drawer {
133
+ position: fixed;
134
+ z-index: var(--z-drawer);
135
+ @include finish-surface(var(--drawer-bg));
136
+ box-shadow: var(--relief-shadow-lg);
137
+ overflow-y: auto;
138
+ transition: transform var(--transition-slow) var(--easing-in-out);
139
+ }
140
+
141
+ // ---- Slide directions ----
142
+
143
+ .drawer-start {
144
+ top: 0;
145
+ left: 0;
146
+ bottom: 0;
147
+ width: 20rem;
148
+ max-width: 85vw;
149
+ transform: translateX(-100%);
150
+
151
+ &.active {
152
+ transform: translateX(0);
153
+ }
154
+ }
155
+
156
+ .drawer-end {
157
+ top: 0;
158
+ right: 0;
159
+ bottom: 0;
160
+ width: 20rem;
161
+ max-width: 85vw;
162
+ transform: translateX(100%);
163
+
164
+ &.active {
165
+ transform: translateX(0);
166
+ }
167
+ }
168
+
169
+ .drawer-top {
170
+ top: 0;
171
+ left: 0;
172
+ right: 0;
173
+ height: 20rem;
174
+ max-height: 85vh;
175
+ transform: translateY(-100%);
176
+
177
+ &.active {
178
+ transform: translateY(0);
179
+ }
180
+ }
181
+
182
+ .drawer-bottom {
183
+ bottom: 0;
184
+ left: 0;
185
+ right: 0;
186
+ height: 20rem;
187
+ max-height: 85vh;
188
+ transform: translateY(100%);
189
+
190
+ &.active {
191
+ transform: translateY(0);
192
+ }
193
+ }
194
+
195
+ // ---- Size variants ----
196
+
197
+ .drawer-sm {
198
+ &.drawer-start,
199
+ &.drawer-end {
200
+ width: 16rem;
201
+ }
202
+
203
+ &.drawer-top,
204
+ &.drawer-bottom {
205
+ height: 14rem;
206
+ }
207
+ }
208
+
209
+ .drawer-lg {
210
+ &.drawer-start,
211
+ &.drawer-end {
212
+ width: 28rem;
213
+ }
214
+
215
+ &.drawer-top,
216
+ &.drawer-bottom {
217
+ height: 28rem;
218
+ }
219
+ }
220
+
221
+ // ---- Drawer sections ----
222
+
223
+ .drawer-header {
224
+ @extend %overlay-header;
225
+ }
226
+
227
+ .drawer-body {
228
+ @extend %overlay-body;
229
+ }
230
+
231
+ .drawer-footer {
232
+ @extend %overlay-footer;
233
+ }
@@ -0,0 +1,53 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Scroll Area Component
3
+ // ---------------------------------------------------------------------------
4
+ // Custom scrollbar container with tier-aware thumb colors.
5
+ // Extends the base scrollbar styling for component-level opt-in.
6
+ // ---------------------------------------------------------------------------
7
+
8
+ @use '../base/register' as *;
9
+
10
+ .scroll-area {
11
+ position: relative;
12
+ overflow: auto;
13
+ scrollbar-width: thin;
14
+ scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
15
+
16
+ // Webkit custom scrollbar
17
+ &::-webkit-scrollbar {
18
+ width: 0.5rem;
19
+ height: 0.5rem;
20
+ }
21
+
22
+ &::-webkit-scrollbar-track {
23
+ background: var(--scrollbar-track);
24
+ border-radius: var(--radius-full);
25
+ }
26
+
27
+ &::-webkit-scrollbar-thumb {
28
+ background: var(--scrollbar-thumb);
29
+ border-radius: var(--radius-full);
30
+ border: 2px solid transparent;
31
+ background-clip: content-box;
32
+ }
33
+
34
+ &::-webkit-scrollbar-thumb:hover {
35
+ background: var(--text-muted);
36
+ background-clip: content-box;
37
+ }
38
+ }
39
+
40
+ .scroll-area-sm {
41
+ &::-webkit-scrollbar {
42
+ width: 0.375rem;
43
+ height: 0.375rem;
44
+ }
45
+ }
46
+
47
+ .scroll-area-hidden {
48
+ scrollbar-width: none;
49
+
50
+ &::-webkit-scrollbar {
51
+ display: none;
52
+ }
53
+ }
@@ -0,0 +1,75 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Segmented Control Component
3
+ // ---------------------------------------------------------------------------
4
+ // Tier-aware segmented toggle consuming --relief-*, --finish-*, and --accent-*
5
+ // tokens. Inline group of mutually exclusive options.
6
+ // <div class="segmented-control">
7
+ // <button class="segmented-control__option active">Option A</button>
8
+ // <button class="segmented-control__option">Option B</button>
9
+ // </div>
10
+ // Uses BEM naming (__option) for the child elements — intentional for
11
+ // multi-element structures where parent/child coupling must be explicit.
12
+ // ---------------------------------------------------------------------------
13
+
14
+ @use '../base/register' as *;
15
+ @use '../base/accessibility' as *;
16
+ @use '../base/transitions' as *;
17
+
18
+ .segmented-control {
19
+ display: inline-flex;
20
+ border: 1px solid var(--border-default);
21
+ border-radius: var(--radius-md);
22
+ box-shadow: var(--relief-shadow-inset);
23
+ @include finish-surface;
24
+ overflow: hidden;
25
+ }
26
+
27
+ .segmented-control__option {
28
+ padding: 0.5rem 1rem;
29
+ font-size: var(--text-sm);
30
+ font-weight: var(--font-medium);
31
+ color: var(--text-secondary);
32
+ background: transparent;
33
+ border: none;
34
+ cursor: pointer;
35
+ @include transition-interactive;
36
+
37
+ & + & {
38
+ border-left: 1px solid var(--border-default);
39
+ }
40
+
41
+ &:hover:not(.active) {
42
+ color: var(--text-primary);
43
+ background: var(--state-hover);
44
+ }
45
+
46
+ &.active {
47
+ color: var(--text-inverse);
48
+ background: var(--accent-primary);
49
+ box-shadow: var(--relief-shadow-sm);
50
+ }
51
+
52
+ &:focus-visible {
53
+ @include focus-ring-outline($inset: true);
54
+ }
55
+ }
56
+
57
+ // Size variants
58
+ .segmented-control-sm .segmented-control__option {
59
+ padding: 0.25rem 0.75rem;
60
+ font-size: var(--text-xs);
61
+ }
62
+
63
+ .segmented-control-lg .segmented-control__option {
64
+ padding: 0.75rem 1.5rem;
65
+ font-size: var(--text-base);
66
+ }
67
+
68
+ .segmented-control-icon .segmented-control__option {
69
+ padding: 0.375rem 0.5rem;
70
+ line-height: 0;
71
+
72
+ svg {
73
+ display: block;
74
+ }
75
+ }
@@ -0,0 +1,137 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Table Components
3
+ // ---------------------------------------------------------------------------
4
+ // Data tables with striping, hover, modifiers, and relief-aware styling.
5
+ // Uses --relief-* variables for automatic relief switching.
6
+ // ---------------------------------------------------------------------------
7
+
8
+ @use '../base/register' as *;
9
+ @use '../base/transitions' as *;
10
+
11
+ // ============================================================================
12
+ // BASE TABLE
13
+ // ============================================================================
14
+
15
+ .table {
16
+ width: 100%;
17
+ border-collapse: collapse;
18
+ font-size: var(--text-sm);
19
+ letter-spacing: var(--tracking-refined);
20
+ transition:
21
+ background var(--transition-slow) var(--easing-in-out),
22
+ box-shadow var(--transition-slow) var(--easing-in-out);
23
+
24
+ th,
25
+ td {
26
+ padding: 0.75rem 1rem;
27
+ text-align: left;
28
+ border-bottom: 1px solid var(--border-default);
29
+ }
30
+
31
+ th {
32
+ font-weight: var(--font-semibold);
33
+ color: var(--text-secondary);
34
+ text-transform: uppercase;
35
+ font-size: var(--text-xs);
36
+ letter-spacing: var(--tracking-display);
37
+ background-color: var(--relief-surface-raised);
38
+ border-bottom: 2px solid var(--border-strong);
39
+ }
40
+
41
+ tbody tr {
42
+ @include transition-feedback(var(--transition-normal));
43
+
44
+ &:nth-child(even) {
45
+ background-color: var(--relief-surface-raised);
46
+ }
47
+
48
+ @include hover-state($guard: false);
49
+ }
50
+
51
+ caption {
52
+ caption-side: bottom;
53
+ padding: 0.75rem 0;
54
+ font-size: var(--text-xs);
55
+ color: var(--text-muted);
56
+ text-align: left;
57
+ }
58
+ }
59
+
60
+ // ============================================================================
61
+ // MODIFIERS
62
+ // ============================================================================
63
+
64
+ .table-bordered {
65
+ th,
66
+ td {
67
+ border: 1px solid var(--border-default);
68
+ }
69
+
70
+ th {
71
+ border-bottom-width: 2px;
72
+ border-bottom-color: var(--border-strong);
73
+ }
74
+ }
75
+
76
+ .table-compact {
77
+ th,
78
+ td {
79
+ padding: 0.375rem 0.625rem;
80
+ }
81
+ }
82
+
83
+ .table-relaxed {
84
+ th,
85
+ td {
86
+ padding: 1rem 1.25rem;
87
+ }
88
+ }
89
+
90
+ .table-fixed {
91
+ table-layout: fixed;
92
+ }
93
+
94
+ // ============================================================================
95
+ // ACTIVE ROW
96
+ // ============================================================================
97
+
98
+ .table tbody tr.active {
99
+ background-color: var(--state-active);
100
+ box-shadow: inset 4px 0 0 var(--accent-primary);
101
+ }
102
+
103
+ // ============================================================================
104
+ // RESPONSIVE WRAPPER
105
+ // ============================================================================
106
+
107
+ .table-responsive {
108
+ overflow-x: auto;
109
+ -webkit-overflow-scrolling: touch;
110
+ }
111
+
112
+ // ============================================================================
113
+ // INLAY VARIANT
114
+ // ============================================================================
115
+
116
+ .table-inlay {
117
+ border-collapse: separate;
118
+ border-spacing: 0 4px;
119
+
120
+ th {
121
+ @include accent-gradient(var(--accent-decorative), var(--accent-decorative-hover));
122
+ color: var(--text-inverse);
123
+ }
124
+
125
+ tbody tr {
126
+ background: var(--relief-bg);
127
+ box-shadow: var(--relief-shadow);
128
+
129
+ td:first-child {
130
+ border-radius: var(--radius-lg) 0 0 var(--radius-lg);
131
+ }
132
+
133
+ td:last-child {
134
+ border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
135
+ }
136
+ }
137
+ }
@@ -0,0 +1,111 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Toast Notifications
3
+ // ---------------------------------------------------------------------------
4
+ // Fixed-position notification component with semantic variants.
5
+ // Uses --relief-* and --finish-* variables for tier integration.
6
+ // ---------------------------------------------------------------------------
7
+
8
+ @use '../base/register' as *;
9
+ @use '../base/transitions' as *;
10
+
11
+ // ============================================================================
12
+ // TOAST CONTAINER
13
+ // ============================================================================
14
+
15
+ .toast-container {
16
+ position: fixed;
17
+ z-index: var(--z-toast);
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: 0.5rem;
21
+ padding: 1rem;
22
+ pointer-events: none;
23
+ max-width: 24rem;
24
+ }
25
+
26
+ .toast-container-top-right {
27
+ top: 0;
28
+ right: 0;
29
+ }
30
+
31
+ .toast-container-top-left {
32
+ top: 0;
33
+ left: 0;
34
+ }
35
+
36
+ .toast-container-top-center {
37
+ top: 0;
38
+ left: 50%;
39
+ transform: translateX(-50%);
40
+ }
41
+
42
+ .toast-container-bottom-right {
43
+ bottom: 0;
44
+ right: 0;
45
+ }
46
+
47
+ .toast-container-bottom-left {
48
+ bottom: 0;
49
+ left: 0;
50
+ }
51
+
52
+ .toast-container-bottom-center {
53
+ bottom: 0;
54
+ left: 50%;
55
+ transform: translateX(-50%);
56
+ }
57
+
58
+ // ============================================================================
59
+ // TOAST
60
+ // ============================================================================
61
+
62
+ .toast {
63
+ pointer-events: auto;
64
+ border-radius: var(--radius-xl);
65
+ border: 1px solid var(--border-default);
66
+ box-shadow: var(--relief-shadow-lg);
67
+ @include finish-surface(var(--toast-bg));
68
+ color: var(--toast-text);
69
+ opacity: 0;
70
+ transform: translateY(-0.5rem);
71
+ transition:
72
+ opacity var(--transition-slow) var(--easing-in-out),
73
+ transform var(--transition-slow) var(--easing-in-out);
74
+
75
+ &.active {
76
+ opacity: 1;
77
+ transform: translateY(0);
78
+ }
79
+ }
80
+
81
+ .toast-header {
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: space-between;
85
+ gap: 0.5rem;
86
+ padding: 0.625rem 1rem;
87
+ font-size: var(--text-sm);
88
+ font-weight: var(--font-semibold);
89
+ letter-spacing: var(--tracking-elegant);
90
+ border-bottom: 1px solid var(--border-subtle);
91
+ }
92
+
93
+ .toast-body {
94
+ padding: 0.75rem 1rem;
95
+ font-size: var(--text-sm);
96
+ line-height: 1.5;
97
+ }
98
+
99
+ // ============================================================================
100
+ // SEMANTIC VARIANTS
101
+ // ============================================================================
102
+
103
+ @each $type in (success, warning, error, info) {
104
+ .toast-#{$type} {
105
+ border-left: 3px solid var(--color-#{$type});
106
+
107
+ .toast-header {
108
+ color: var(--color-#{$type}-text);
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,57 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Toggle Component
3
+ // ---------------------------------------------------------------------------
4
+ // Tier-aware toggle switch consuming --relief-*, --finish-*, and --state-*
5
+ // tokens. Renders as a track with a sliding thumb pseudo-element.
6
+ // ARIA: use role="switch" with aria-checked and tabindex="0".
7
+ // <div class="toggle" role="switch" aria-checked="false" tabindex="0">
8
+ // ---------------------------------------------------------------------------
9
+
10
+ @use '../base/register' as *;
11
+ @use '../base/accessibility' as *;
12
+ @use '../base/transitions' as *;
13
+
14
+ .toggle {
15
+ position: relative;
16
+ width: 3.5rem;
17
+ height: 2rem;
18
+ @include relief-container(var(--relief-shadow-inset-lg));
19
+ border-radius: var(--radius-full);
20
+ @include finish-surface;
21
+ cursor: pointer;
22
+ @include transition-interactive;
23
+
24
+ &::after {
25
+ content: '';
26
+ position: absolute;
27
+ top: 3px;
28
+ left: 3px;
29
+ width: 1.625rem;
30
+ height: 1.625rem;
31
+ border-radius: var(--radius-full);
32
+ background: var(--relief-bg);
33
+ box-shadow: var(--relief-shadow-sm);
34
+ @include transition-interactive;
35
+ }
36
+
37
+ &.active,
38
+ &[aria-checked='true'] {
39
+ background: var(--accent-primary);
40
+ border-color: transparent;
41
+
42
+ &::after {
43
+ transform: translateX(1.5rem);
44
+ background: var(--text-inverse);
45
+ box-shadow: var(--relief-shadow);
46
+ }
47
+ }
48
+
49
+ &:focus-visible {
50
+ @include focus-ring-outline;
51
+ }
52
+
53
+ &.disabled {
54
+ @include disabled-state;
55
+ border-color: var(--border-subtle);
56
+ }
57
+ }