@mt-gloss/styles 0.0.3

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.
@@ -0,0 +1,555 @@
1
+ // ============================================
2
+ // COMPONENT: BUTTONS
3
+ // ============================================
4
+
5
+ @use '../tokens' as *;
6
+ @use '../mixins' as *;
7
+
8
+ .gloss-btn {
9
+ border: none;
10
+ cursor: pointer;
11
+ font-family: $font-body;
12
+ display: inline-flex;
13
+ align-items: center;
14
+ justify-content: center;
15
+ gap: $space-2;
16
+ padding: $space-3 $space-6;
17
+ min-height: 48px;
18
+ border-radius: $radius-lg;
19
+ font-size: $text-base;
20
+ font-weight: 600;
21
+ @include button-transition;
22
+ transform: translateY(0) scale(1);
23
+
24
+ svg {
25
+ width: 18px;
26
+ height: 18px;
27
+ }
28
+ }
29
+
30
+ // --- ICON SLOTS ---
31
+ .gloss-btn__icon {
32
+ display: flex;
33
+ flex-shrink: 0;
34
+
35
+ &--left {
36
+ order: -1;
37
+ }
38
+
39
+ &--right {
40
+ order: 1;
41
+ }
42
+
43
+ &--top {
44
+ align-self: flex-start;
45
+ }
46
+
47
+ &--center {
48
+ align-self: center;
49
+ }
50
+ }
51
+
52
+ .gloss-btn__content {
53
+ flex: 1 0 auto;
54
+ }
55
+
56
+ // --- ICON-ONLY MODE ---
57
+ .gloss-btn--icon-only {
58
+ aspect-ratio: 1;
59
+ padding: 0;
60
+ justify-content: center;
61
+
62
+ // Size variants for icon-only
63
+ &.gloss-btn--sm {
64
+ width: 32px;
65
+ min-height: 32px;
66
+ }
67
+
68
+ &:not(.gloss-btn--sm):not(.gloss-btn--lg) {
69
+ width: 40px;
70
+ min-height: 40px;
71
+ }
72
+
73
+ &.gloss-btn--lg {
74
+ width: 48px;
75
+ min-height: 48px;
76
+ }
77
+ }
78
+
79
+ // --- FULL-WIDTH MODE ---
80
+ .gloss-btn--full-width {
81
+ width: 100%;
82
+ justify-content: center;
83
+ }
84
+
85
+ // --- BUTTON GROUP ---
86
+ .gloss-btn-group {
87
+ display: inline-flex;
88
+ align-items: stretch;
89
+
90
+ // Gap variants (when not attached)
91
+ &--gap-sm {
92
+ gap: $space-1;
93
+ }
94
+
95
+ &--gap-md {
96
+ gap: $space-2;
97
+ }
98
+
99
+ &--gap-lg {
100
+ gap: $space-4;
101
+ }
102
+
103
+ // Horizontal orientation (default)
104
+ &--horizontal {
105
+ flex-direction: row;
106
+
107
+ &.gloss-btn-group--attached {
108
+ gap: 0;
109
+
110
+ > .gloss-btn {
111
+ // Remove individual button shadows to prevent overlap issues
112
+ box-shadow: none;
113
+
114
+ &:not(:first-child) {
115
+ border-top-left-radius: 0;
116
+ border-bottom-left-radius: 0;
117
+ margin-left: -1px;
118
+ }
119
+
120
+ &:not(:last-child) {
121
+ border-top-right-radius: 0;
122
+ border-bottom-right-radius: 0;
123
+ }
124
+
125
+ // Ensure focused button appears above siblings
126
+ &:focus-visible {
127
+ z-index: 1;
128
+ }
129
+
130
+ // Ensure hovered button appears above siblings
131
+ &:hover {
132
+ z-index: 1;
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ // Vertical orientation
139
+ &--vertical {
140
+ flex-direction: column;
141
+
142
+ &.gloss-btn-group--attached {
143
+ gap: 0;
144
+
145
+ > .gloss-btn {
146
+ box-shadow: none;
147
+
148
+ &:not(:first-child) {
149
+ border-top-left-radius: 0;
150
+ border-top-right-radius: 0;
151
+ margin-top: -1px;
152
+ }
153
+
154
+ &:not(:last-child) {
155
+ border-bottom-left-radius: 0;
156
+ border-bottom-right-radius: 0;
157
+ }
158
+
159
+ &:focus-visible {
160
+ z-index: 1;
161
+ }
162
+
163
+ &:hover {
164
+ z-index: 1;
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ // Full width mode
171
+ &--full-width {
172
+ width: 100%;
173
+
174
+ > .gloss-btn {
175
+ flex: 1;
176
+ }
177
+ }
178
+ }
179
+
180
+ // --- SPLIT BUTTON ---
181
+ .gloss-split-button {
182
+ position: relative;
183
+ display: inline-flex;
184
+
185
+ &__menu {
186
+ position: absolute;
187
+ top: 100%;
188
+ right: 0;
189
+ margin-top: $space-1;
190
+ min-width: 180px;
191
+ background: $alias-bg-surface;
192
+ border: 1px solid $alias-border-default;
193
+ border-radius: $radius-lg;
194
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
195
+ z-index: 100;
196
+ overflow: hidden;
197
+ animation: gloss-dropdown-enter 0.15s ease-out;
198
+ }
199
+
200
+ &__item {
201
+ width: 100%;
202
+ display: flex;
203
+ align-items: center;
204
+ gap: $space-3;
205
+ padding: $space-3 $space-4;
206
+ background: transparent;
207
+ border: none;
208
+ font-family: $font-body;
209
+ font-size: $text-sm;
210
+ color: $alias-text-primary;
211
+ cursor: pointer;
212
+ text-align: left;
213
+ transition: background-color 0.15s ease;
214
+
215
+ &:hover:not(:disabled) {
216
+ background: $alias-bg-hover;
217
+ }
218
+
219
+ &:focus-visible {
220
+ outline: none;
221
+ background: $alias-bg-hover;
222
+ }
223
+
224
+ &--disabled {
225
+ color: $alias-text-tertiary;
226
+ cursor: not-allowed;
227
+ }
228
+
229
+ &-icon {
230
+ display: flex;
231
+ flex-shrink: 0;
232
+ color: $alias-text-secondary;
233
+ }
234
+
235
+ &-label {
236
+ flex: 1;
237
+ }
238
+ }
239
+
240
+ &__divider {
241
+ height: 1px;
242
+ background: $alias-border-default;
243
+ margin: $space-1 0;
244
+ }
245
+ }
246
+
247
+ @keyframes gloss-dropdown-enter {
248
+ from {
249
+ opacity: 0;
250
+ transform: translateY(-4px);
251
+ }
252
+ to {
253
+ opacity: 1;
254
+ transform: translateY(0);
255
+ }
256
+ }
257
+
258
+ // --- SIZE MODIFIERS ---
259
+ .gloss-btn--sm {
260
+ padding: $space-2 $space-4;
261
+ min-height: 36px;
262
+ font-size: $text-sm;
263
+ gap: $space-1;
264
+
265
+ svg {
266
+ width: 14px;
267
+ height: 14px;
268
+ }
269
+ }
270
+
271
+ .gloss-btn--lg {
272
+ padding: $space-4 $space-8;
273
+ min-height: 56px;
274
+ font-size: $text-lg;
275
+ gap: $space-3;
276
+
277
+ svg {
278
+ width: 20px;
279
+ height: 20px;
280
+ }
281
+ }
282
+
283
+ // --- PRIMARY BUTTON ---
284
+ .gloss-btn--primary {
285
+ background: linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0) 50%, rgba(0,0,0,0.1) 100%), $color-blue-600;
286
+ color: $alias-text-inverse;
287
+ @include shadow-button-default;
288
+
289
+ &:hover:not(:disabled):not(.gloss-btn--error-disabled) {
290
+ background: linear-gradient(180deg, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0) 50%, rgba(0,0,0,0.15) 100%), $color-blue-700;
291
+ @include shadow-button-hover;
292
+ transform: translateY(-2px) scale(1.01);
293
+ }
294
+
295
+ &:active:not(:disabled):not(.gloss-btn--error-disabled) {
296
+ background: linear-gradient(180deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.2) 100%), $color-blue-800;
297
+ @include shadow-button-active;
298
+ transform: translateY(2px) scaleY(0.96) scaleX(1.02);
299
+ }
300
+
301
+ &:focus-visible {
302
+ outline: none;
303
+ box-shadow: $shadow-button-default, 0 0 0 3px rgba(59, 130, 246, 0.4);
304
+ }
305
+
306
+ &:disabled {
307
+ background: $color-gray-300;
308
+ box-shadow: none;
309
+ cursor: not-allowed;
310
+ transform: none;
311
+ color: $color-gray-500;
312
+ }
313
+
314
+ &.gloss-btn--error-disabled {
315
+ background: linear-gradient(180deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%), rgba(37, 99, 235, 0.5);
316
+ color: rgba(255, 255, 255, 0.75);
317
+ box-shadow: none;
318
+ cursor: pointer;
319
+ transform: none;
320
+
321
+ svg {
322
+ color: $color-red-500;
323
+ }
324
+ }
325
+ }
326
+
327
+ // --- SECONDARY BUTTON ---
328
+ .gloss-btn--secondary {
329
+ background: $alias-bg-surface;
330
+ color: $alias-text-primary;
331
+ border: 1px solid $alias-border-default;
332
+ @include shadow-input-default;
333
+
334
+ &:hover:not(:disabled) {
335
+ background: $alias-bg-hover;
336
+ border-color: $alias-border-hover;
337
+ @include shadow-elevation-hover;
338
+ transform: translateY(-1px);
339
+ }
340
+
341
+ &:active:not(:disabled) {
342
+ background: $color-gray-100;
343
+ @include shadow-input-default;
344
+ transform: translateY(1px) scaleY(0.98);
345
+ }
346
+
347
+ &:disabled {
348
+ background: $color-gray-100;
349
+ color: $alias-text-tertiary;
350
+ box-shadow: none;
351
+ cursor: not-allowed;
352
+ transform: none;
353
+ }
354
+ }
355
+
356
+ // --- GHOST BUTTON ---
357
+ .gloss-btn--ghost {
358
+ background: transparent;
359
+ color: $alias-primary;
360
+ box-shadow: none;
361
+
362
+ &:hover:not(:disabled) {
363
+ background: $color-blue-50;
364
+ color: $color-blue-700;
365
+ }
366
+
367
+ &:active:not(:disabled) {
368
+ background: $color-blue-100;
369
+ color: $color-blue-800;
370
+ transform: scale(0.98);
371
+ }
372
+
373
+ &:disabled {
374
+ color: $alias-text-tertiary;
375
+ cursor: not-allowed;
376
+ }
377
+ }
378
+
379
+ // --- OUTLINE BUTTON ---
380
+ .gloss-btn--outline {
381
+ background: transparent;
382
+ border: 1px solid $alias-border-default;
383
+ color: $alias-text-primary;
384
+ box-shadow: none;
385
+
386
+ &:hover:not(:disabled) {
387
+ background: $alias-bg-hover;
388
+ border-color: $alias-border-hover;
389
+ transform: translateY(-1px);
390
+ }
391
+
392
+ &:active:not(:disabled) {
393
+ background: $color-gray-100;
394
+ transform: translateY(1px) scaleY(0.98);
395
+ }
396
+
397
+ &:focus-visible {
398
+ outline: none;
399
+ box-shadow: 0 0 0 3px rgba(107, 114, 128, 0.3);
400
+ }
401
+
402
+ &:disabled {
403
+ background: transparent;
404
+ border-color: $color-gray-200;
405
+ color: $alias-text-tertiary;
406
+ cursor: not-allowed;
407
+ transform: none;
408
+ }
409
+ }
410
+
411
+ // --- DANGER BUTTON ---
412
+ .gloss-btn--danger {
413
+ background: linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0) 50%, rgba(0,0,0,0.1) 100%), $color-red-500;
414
+ color: $color-white;
415
+ @include shadow-button-default;
416
+
417
+ &:hover:not(:disabled) {
418
+ background: linear-gradient(180deg, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0) 50%, rgba(0,0,0,0.15) 100%), $color-red-600;
419
+ @include shadow-button-hover;
420
+ transform: translateY(-2px) scale(1.01);
421
+ }
422
+
423
+ &:active:not(:disabled) {
424
+ background: linear-gradient(180deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.2) 100%), $color-red-700;
425
+ @include shadow-button-active;
426
+ transform: translateY(2px) scaleY(0.96) scaleX(1.02);
427
+ }
428
+
429
+ &:focus-visible {
430
+ outline: none;
431
+ box-shadow: $shadow-button-default, 0 0 0 3px rgba(239, 68, 68, 0.4);
432
+ }
433
+
434
+ &:disabled {
435
+ background: $color-gray-300;
436
+ box-shadow: none;
437
+ cursor: not-allowed;
438
+ transform: none;
439
+ color: $color-gray-500;
440
+ }
441
+ }
442
+
443
+ // --- DANGER OUTLINE BUTTON ---
444
+ .gloss-btn--danger-outline {
445
+ background: transparent;
446
+ border: 1px solid $color-red-500;
447
+ color: $color-red-500;
448
+ box-shadow: none;
449
+
450
+ &:hover:not(:disabled) {
451
+ background: $color-red-50;
452
+ border-color: $color-red-600;
453
+ color: $color-red-600;
454
+ transform: translateY(-1px);
455
+ }
456
+
457
+ &:active:not(:disabled) {
458
+ background: $color-red-100;
459
+ border-color: $color-red-700;
460
+ color: $color-red-700;
461
+ transform: translateY(1px) scaleY(0.98);
462
+ }
463
+
464
+ &:focus-visible {
465
+ outline: none;
466
+ box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.3);
467
+ }
468
+
469
+ &:disabled {
470
+ background: transparent;
471
+ border-color: $color-red-200;
472
+ color: $color-red-300;
473
+ cursor: not-allowed;
474
+ transform: none;
475
+ }
476
+ }
477
+
478
+ // --- LOADING STATE ---
479
+ .gloss-btn--loading {
480
+ position: relative;
481
+ color: transparent !important;
482
+ pointer-events: none;
483
+
484
+ &::after {
485
+ content: '';
486
+ position: absolute;
487
+ width: 20px;
488
+ height: 20px;
489
+ border: 2px solid rgba(255,255,255,0.3);
490
+ border-top-color: white;
491
+ border-radius: 50%;
492
+ animation: spinner 0.8s linear infinite;
493
+ }
494
+ }
495
+
496
+ // --- ERROR INDICATOR ---
497
+ .gloss-btn__error-indicator {
498
+ display: inline-flex;
499
+ align-items: center;
500
+ justify-content: center;
501
+ width: 18px;
502
+ height: 18px;
503
+ background: $color-red-500;
504
+ border-radius: 50%;
505
+ margin-left: $space-1;
506
+
507
+ svg {
508
+ width: 10px;
509
+ height: 10px;
510
+ }
511
+ }
512
+
513
+ // --- PILL BUTTON ---
514
+ .gloss-btn--pill {
515
+ padding: $space-6 $space-8;
516
+ border-radius: $radius-full;
517
+ transition-duration: 300ms;
518
+ transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform;
519
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
520
+ align-items: center;
521
+ display: flex;
522
+
523
+ svg {
524
+ transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform;
525
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
526
+ transition-duration: 150ms;
527
+ flex-shrink: 0;
528
+ width: 3rem;
529
+ height: 3rem;
530
+ }
531
+
532
+ > span {
533
+ letter-spacing: -0.025em;
534
+ font-weight: 400;
535
+ font-size: $text-lg;
536
+ line-height: 1.75rem;
537
+ padding-left: $space-4;
538
+ padding-right: $space-4;
539
+
540
+ span {
541
+ display: block;
542
+ font-size: $text-sm;
543
+ font-weight: 300;
544
+ line-height: 1.25rem;
545
+ }
546
+ }
547
+
548
+ &:hover {
549
+ color: $color-white !important;
550
+
551
+ svg {
552
+ color: $color-white !important;
553
+ }
554
+ }
555
+ }