@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,128 @@
1
+ // ============================================
2
+ // COMPONENT: FEEDBACK (CHIPS, BADGES, TAGS, LINKS)
3
+ // ============================================
4
+
5
+ @use '../tokens' as *;
6
+ @use '../mixins' as *;
7
+
8
+ // --- CHIPS ---
9
+ .gloss-chip {
10
+ display: inline-flex;
11
+ align-items: center;
12
+ gap: $space-2;
13
+ font-size: $text-sm;
14
+ font-weight: 500;
15
+ padding: $space-1 $space-3;
16
+ border-radius: $radius-full;
17
+ background: $color-white;
18
+ border: 1px solid $alias-border-default;
19
+ @include shadow-input-default;
20
+ transition: all 0.2s;
21
+ cursor: default;
22
+
23
+ &:hover {
24
+ background: $alias-bg-hover;
25
+ border-color: $alias-border-hover;
26
+ @include shadow-elevation-hover;
27
+ transform: translateY(-1px);
28
+ }
29
+
30
+ &--selected {
31
+ background: $alias-primary;
32
+ border-color: $alias-primary;
33
+ color: white;
34
+
35
+ &:hover {
36
+ background: $alias-primary-hover;
37
+ }
38
+ }
39
+
40
+ &--error {
41
+ background: $alias-bg-error;
42
+ border-color: transparent;
43
+ color: $alias-text-error;
44
+ }
45
+ }
46
+
47
+ .gloss-chip__close {
48
+ background: rgba(0,0,0,0.1);
49
+ border: none;
50
+ border-radius: 50%;
51
+ width: 16px;
52
+ height: 16px;
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ cursor: pointer;
57
+ color: inherit;
58
+ }
59
+
60
+ // --- BADGES ---
61
+ .gloss-badge {
62
+ display: inline-flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ font-size: $text-xs;
66
+ font-weight: 600;
67
+ min-width: 20px;
68
+ height: 20px;
69
+ padding: 0 $space-2;
70
+ border-radius: $radius-full;
71
+
72
+ &--default {
73
+ background: $color-gray-200;
74
+ color: $alias-text-secondary;
75
+ }
76
+
77
+ &--informational {
78
+ background: $color-blue-100;
79
+ color: $color-blue-700;
80
+ }
81
+
82
+ &--success {
83
+ background: $color-green-100;
84
+ color: $color-green-600;
85
+ }
86
+
87
+ &--attention {
88
+ background: $color-amber-100;
89
+ color: $color-amber-600;
90
+ }
91
+
92
+ &--critical {
93
+ background: $color-red-100;
94
+ color: $color-red-600;
95
+ }
96
+ }
97
+
98
+ // --- TAGS ---
99
+ .gloss-tag {
100
+ display: inline-flex;
101
+ align-items: center;
102
+ gap: $space-1;
103
+ font-size: $text-xs;
104
+ font-weight: 500;
105
+ padding: $space-1 $space-2;
106
+ border-radius: $radius-sm;
107
+ background: $color-gray-100;
108
+ color: $alias-text-secondary;
109
+ border: 1px solid $alias-border-default;
110
+ }
111
+
112
+ // --- LINKS ---
113
+ .gloss-link {
114
+ color: $alias-text-link;
115
+ text-decoration: none;
116
+ font-weight: 400;
117
+ transition: color 0.1s;
118
+ cursor: pointer;
119
+
120
+ &:hover {
121
+ color: $color-blue-700;
122
+ text-decoration: underline;
123
+ }
124
+
125
+ &--bold {
126
+ font-weight: 600;
127
+ }
128
+ }
@@ -0,0 +1,153 @@
1
+ // ============================================
2
+ // COMPONENT: FORM FIELD
3
+ // ============================================
4
+
5
+ @use '../tokens' as *;
6
+
7
+ .gloss-form-field {
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: $space-2;
11
+ margin-bottom: $space-4;
12
+
13
+ &:last-child {
14
+ margin-bottom: 0;
15
+ }
16
+ }
17
+
18
+ // --- LABEL POSITIONS ---
19
+ .gloss-form-field--label-top {
20
+ flex-direction: column;
21
+ }
22
+
23
+ .gloss-form-field--label-left {
24
+ flex-direction: row;
25
+ align-items: flex-start;
26
+ gap: $space-4;
27
+
28
+ .gloss-form-field__label {
29
+ min-width: 120px;
30
+ padding-top: $space-3; // Align with input
31
+ text-align: right;
32
+ }
33
+
34
+ .gloss-form-field__control {
35
+ flex: 1;
36
+ }
37
+ }
38
+
39
+ .gloss-form-field--label-right {
40
+ flex-direction: row;
41
+ align-items: center;
42
+ gap: $space-3;
43
+
44
+ .gloss-form-field__control {
45
+ flex-shrink: 0;
46
+ }
47
+ }
48
+
49
+ // --- LABEL ---
50
+ .gloss-form-field__label {
51
+ display: block;
52
+ font-family: $font-body;
53
+ font-size: $text-sm;
54
+ font-weight: 500;
55
+ color: $alias-text-primary;
56
+ line-height: 1.4;
57
+
58
+ &--hidden {
59
+ position: absolute;
60
+ width: 1px;
61
+ height: 1px;
62
+ padding: 0;
63
+ margin: -1px;
64
+ overflow: hidden;
65
+ clip: rect(0, 0, 0, 0);
66
+ white-space: nowrap;
67
+ border: 0;
68
+ }
69
+ }
70
+
71
+ .gloss-form-field__required {
72
+ color: $color-red-500;
73
+ margin-left: $space-1;
74
+ }
75
+
76
+ // --- CONTROL ---
77
+ .gloss-form-field__control {
78
+ position: relative;
79
+ }
80
+
81
+ // --- FOOTER (Helper/Error) ---
82
+ .gloss-form-field__footer {
83
+ min-height: 20px; // Prevent layout shift
84
+ }
85
+
86
+ .gloss-form-field__helper {
87
+ font-family: $font-body;
88
+ font-size: $text-xs;
89
+ color: $alias-text-tertiary;
90
+ line-height: 1.4;
91
+ }
92
+
93
+ .gloss-form-field__error {
94
+ font-family: $font-body;
95
+ font-size: $text-xs;
96
+ color: $alias-text-error;
97
+ line-height: 1.4;
98
+ display: flex;
99
+ align-items: center;
100
+ gap: $space-1;
101
+
102
+ &::before {
103
+ content: '';
104
+ display: inline-block;
105
+ width: 12px;
106
+ height: 12px;
107
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23EF4444' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E");
108
+ background-size: contain;
109
+ flex-shrink: 0;
110
+ }
111
+ }
112
+
113
+ // --- ERROR STATE ---
114
+ .gloss-form-field--error {
115
+ .gloss-form-field__label {
116
+ color: $alias-text-error;
117
+ }
118
+ }
119
+
120
+ // --- INLINE FORM FIELDS ---
121
+ .gloss-form-inline {
122
+ display: flex;
123
+ flex-wrap: wrap;
124
+ gap: $space-4;
125
+ align-items: flex-end;
126
+
127
+ .gloss-form-field {
128
+ margin-bottom: 0;
129
+ flex: 1;
130
+ min-width: 200px;
131
+ }
132
+ }
133
+
134
+ // --- FORM ACTIONS ---
135
+ .gloss-form-actions {
136
+ display: flex;
137
+ gap: $space-3;
138
+ margin-top: $space-6;
139
+ padding-top: $space-4;
140
+ border-top: 1px solid $alias-border-default;
141
+
142
+ &--right {
143
+ justify-content: flex-end;
144
+ }
145
+
146
+ &--center {
147
+ justify-content: center;
148
+ }
149
+
150
+ &--between {
151
+ justify-content: space-between;
152
+ }
153
+ }
@@ -0,0 +1,459 @@
1
+ // ============================================
2
+ // COMPONENT: INPUTS
3
+ // ============================================
4
+
5
+ @use '../tokens' as *;
6
+ @use '../mixins' as *;
7
+
8
+ .gloss-input {
9
+ width: 100%;
10
+ font-family: $font-body;
11
+ font-size: $text-base;
12
+ font-weight: 500;
13
+ color: $alias-text-primary;
14
+ background: $color-white;
15
+ border: 1px solid $alias-border-default;
16
+ border-radius: $radius-md;
17
+ padding: $space-3 $space-4;
18
+ @include shadow-input-default;
19
+ outline: none;
20
+ @include input-transition-default;
21
+
22
+ &::placeholder {
23
+ color: $alias-text-tertiary;
24
+ font-weight: 400;
25
+ }
26
+
27
+ &:hover:not(:disabled):not(:focus):not(.gloss-input--error):not(.gloss-input--success) {
28
+ background: $alias-bg-hover;
29
+ border-color: $alias-border-hover;
30
+ @include input-transition-hover;
31
+ }
32
+
33
+ &:focus:not(.gloss-input--error):not(.gloss-input--success) {
34
+ background: $alias-bg-hover;
35
+ border-color: $alias-border-focus;
36
+ @include shadow-input-focus;
37
+ @include input-transition-focus;
38
+ }
39
+
40
+ &:disabled {
41
+ background: $alias-bg-disabled;
42
+ box-shadow: $shadow-input-disabled;
43
+ cursor: not-allowed;
44
+ color: $alias-text-tertiary;
45
+ border-color: transparent;
46
+ }
47
+ }
48
+
49
+ // --- SUCCESS STATE ---
50
+ .gloss-input--success {
51
+ border-color: $alias-border-success;
52
+ @include shadow-input-default;
53
+
54
+ &:hover:not(:disabled):not(:focus) {
55
+ background: $alias-bg-hover;
56
+ }
57
+
58
+ &:focus {
59
+ background: $alias-bg-hover;
60
+ box-shadow: $shadow-input-success-focus;
61
+ }
62
+ }
63
+
64
+ // --- ERROR STATE ---
65
+ .gloss-input--error {
66
+ border-color: $color-red-200;
67
+ background: $alias-bg-error;
68
+ color: $alias-text-error;
69
+ box-shadow: $shadow-input-error;
70
+
71
+ &:hover:not(:disabled):not(:focus) {
72
+ border-color: $color-red-400;
73
+ }
74
+
75
+ &:focus {
76
+ border-color: $color-red-400;
77
+ box-shadow: $shadow-input-error-focus;
78
+ }
79
+ }
80
+
81
+ // --- INPUT WRAPPER (for prefix/suffix) ---
82
+ .gloss-input-wrapper {
83
+ position: relative;
84
+ display: flex;
85
+ align-items: center;
86
+ width: 100%;
87
+ }
88
+
89
+ .gloss-input__prefix,
90
+ .gloss-input__suffix {
91
+ position: absolute;
92
+ display: flex;
93
+ align-items: center;
94
+ color: $alias-text-tertiary;
95
+ font-size: $text-lg;
96
+ font-weight: 500;
97
+ pointer-events: none;
98
+ z-index: 1;
99
+ }
100
+
101
+ .gloss-input__prefix {
102
+ left: $space-4;
103
+ }
104
+
105
+ .gloss-input__suffix {
106
+ right: $space-4;
107
+ }
108
+
109
+ // --- ICON ALIGNMENT ---
110
+ .gloss-input__icon {
111
+ &--center {
112
+ top: 50%;
113
+ transform: translateY(-50%);
114
+ }
115
+
116
+ &--top {
117
+ top: $space-3;
118
+ transform: none;
119
+ }
120
+ }
121
+
122
+ .gloss-input--has-prefix {
123
+ padding-left: $space-10;
124
+ }
125
+
126
+ .gloss-input--has-suffix {
127
+ padding-right: $space-10;
128
+ }
129
+
130
+ // --- INPUT ANATOMY ---
131
+ .gloss-input-anatomy {
132
+ display: flex;
133
+ flex-direction: column;
134
+ gap: $space-2;
135
+ width: 100%;
136
+ }
137
+
138
+ .gloss-input__label {
139
+ font-size: $text-sm;
140
+ font-weight: 500;
141
+ color: $alias-text-secondary;
142
+ display: flex;
143
+ justify-content: space-between;
144
+ align-items: center;
145
+ }
146
+
147
+ .gloss-input__label-status {
148
+ font-size: $text-xs;
149
+ font-weight: 600;
150
+ display: flex;
151
+ align-items: center;
152
+ gap: 4px;
153
+
154
+ &--success {
155
+ color: $alias-text-success;
156
+ }
157
+
158
+ &--error {
159
+ color: $alias-text-error;
160
+ }
161
+
162
+ &--required {
163
+ color: $alias-text-tertiary;
164
+ font-weight: 400;
165
+ }
166
+
167
+ &--pending {
168
+ color: $alias-primary;
169
+ }
170
+ }
171
+
172
+ .gloss-input__helper {
173
+ font-size: $text-xs;
174
+ color: $alias-text-tertiary;
175
+ margin-top: $space-1;
176
+ line-height: 1.4;
177
+ display: flex;
178
+ align-items: flex-start;
179
+ gap: 6px;
180
+
181
+ &--error {
182
+ color: $alias-text-error;
183
+ }
184
+
185
+ svg {
186
+ flex-shrink: 0;
187
+ margin-top: 2px;
188
+ }
189
+ }
190
+
191
+ // --- CLEARABLE & COPYABLE BUTTONS ---
192
+ .gloss-input__clear,
193
+ .gloss-input__copy {
194
+ display: flex;
195
+ align-items: center;
196
+ justify-content: center;
197
+ padding: $space-1;
198
+ background: transparent;
199
+ border: none;
200
+ border-radius: $radius-sm;
201
+ cursor: pointer;
202
+ color: $alias-text-tertiary;
203
+ transition: color 0.15s ease, background-color 0.15s ease;
204
+ pointer-events: auto;
205
+
206
+ &:hover {
207
+ color: $alias-text-primary;
208
+ background: $alias-bg-hover;
209
+ }
210
+
211
+ &:focus-visible {
212
+ outline: none;
213
+ box-shadow: 0 0 0 2px $alias-border-focus;
214
+ }
215
+ }
216
+
217
+ .gloss-input__clear {
218
+ opacity: 0.6;
219
+
220
+ &:hover {
221
+ opacity: 1;
222
+ }
223
+ }
224
+
225
+ .gloss-input__copy {
226
+ &--copied {
227
+ color: $alias-text-success;
228
+
229
+ &:hover {
230
+ color: $alias-text-success;
231
+ }
232
+ }
233
+ }
234
+
235
+ .gloss-input__right-icon {
236
+ display: flex;
237
+ align-items: center;
238
+ }
239
+
240
+ // Allow pointer events on suffix when it contains interactive elements
241
+ .gloss-input__suffix:has(.gloss-input__clear, .gloss-input__copy) {
242
+ pointer-events: auto;
243
+ display: flex;
244
+ align-items: center;
245
+ gap: $space-1;
246
+ }
247
+
248
+ // --- INPUT FOOTER (helper + counter) ---
249
+ .gloss-input__footer {
250
+ display: flex;
251
+ justify-content: space-between;
252
+ align-items: flex-start;
253
+ gap: $space-4;
254
+ min-height: $space-4;
255
+
256
+ // When only counter, align right
257
+ &:has(.gloss-input__counter):not(:has(.gloss-input__helper)) {
258
+ justify-content: flex-end;
259
+ }
260
+ }
261
+
262
+ // --- CHARACTER COUNTER ---
263
+ .gloss-input__counter {
264
+ font-size: $text-xs;
265
+ color: $alias-text-tertiary;
266
+ text-align: right;
267
+ flex-shrink: 0;
268
+ margin-top: $space-1;
269
+
270
+ &--warning {
271
+ color: $color-amber-500;
272
+ }
273
+
274
+ &--error {
275
+ color: $alias-text-error;
276
+ }
277
+ }
278
+
279
+ // --- INPUT GROUP ---
280
+ .gloss-input-group {
281
+ display: flex;
282
+ width: 100%;
283
+
284
+ // Gap when not attached
285
+ &:not(.gloss-input-group--attached) {
286
+ gap: $space-2;
287
+ }
288
+
289
+ // Attached mode - merge borders
290
+ &--attached {
291
+ > .gloss-input,
292
+ > .gloss-input-wrapper > .gloss-input {
293
+ // Remove border radius from middle items
294
+ &:not(:first-child):not(:last-child) {
295
+ border-radius: 0;
296
+ }
297
+
298
+ // First item - remove right border radius
299
+ &:first-child {
300
+ border-top-right-radius: 0;
301
+ border-bottom-right-radius: 0;
302
+ }
303
+
304
+ // Last item - remove left border radius
305
+ &:last-child {
306
+ border-top-left-radius: 0;
307
+ border-bottom-left-radius: 0;
308
+ }
309
+
310
+ // Handle negative margin for overlapping borders
311
+ &:not(:first-child) {
312
+ margin-left: -1px;
313
+ }
314
+
315
+ &:focus {
316
+ z-index: 1;
317
+ }
318
+ }
319
+
320
+ // Handle addon + input combinations
321
+ > .gloss-input-addon + .gloss-input,
322
+ > .gloss-input-addon + .gloss-input-wrapper > .gloss-input {
323
+ border-top-left-radius: 0;
324
+ border-bottom-left-radius: 0;
325
+ }
326
+
327
+ > .gloss-input + .gloss-input-addon,
328
+ > .gloss-input-wrapper + .gloss-input-addon {
329
+ margin-left: -1px;
330
+ }
331
+ }
332
+ }
333
+
334
+ // --- INPUT ADDON ---
335
+ .gloss-input-addon {
336
+ display: flex;
337
+ align-items: center;
338
+ padding: 0 $space-4;
339
+ background: $alias-bg-secondary;
340
+ border: 1px solid $alias-border-default;
341
+ color: $alias-text-secondary;
342
+ font-size: $text-base;
343
+ font-weight: 500;
344
+ white-space: nowrap;
345
+
346
+ &--left {
347
+ border-right: none;
348
+ border-radius: $radius-md 0 0 $radius-md;
349
+ }
350
+
351
+ &--right {
352
+ border-left: none;
353
+ border-radius: 0 $radius-md $radius-md 0;
354
+ }
355
+ }
356
+
357
+ // Fix input in group to not have full width classes interfering
358
+ .gloss-input-group .gloss-input {
359
+ flex: 1;
360
+ min-width: 0; // Allow shrinking
361
+ }
362
+
363
+ // --- NUMBER INPUT ---
364
+ .gloss-number-input {
365
+ display: flex;
366
+ position: relative;
367
+
368
+ &__input {
369
+ text-align: center;
370
+ -moz-appearance: textfield; // Hide browser spinners
371
+
372
+ &::-webkit-outer-spin-button,
373
+ &::-webkit-inner-spin-button {
374
+ -webkit-appearance: none;
375
+ margin: 0;
376
+ }
377
+ }
378
+
379
+ // Right-side stepper (stacked)
380
+ &__stepper {
381
+ position: absolute;
382
+ right: 1px;
383
+ top: 1px;
384
+ bottom: 1px;
385
+ display: flex;
386
+ flex-direction: column;
387
+ border-left: 1px solid $alias-border-default;
388
+ border-radius: 0 $radius-md $radius-md 0;
389
+ overflow: hidden;
390
+ }
391
+
392
+ &__stepper-btn {
393
+ display: flex;
394
+ align-items: center;
395
+ justify-content: center;
396
+ padding: 0 $space-2;
397
+ background: transparent;
398
+ border: none;
399
+ cursor: pointer;
400
+ color: $alias-text-secondary;
401
+ transition: background-color 0.15s ease, color 0.15s ease;
402
+
403
+ &:hover:not(:disabled) {
404
+ background: $alias-bg-hover;
405
+ color: $alias-text-primary;
406
+ }
407
+
408
+ &:active:not(:disabled) {
409
+ background: $color-gray-200;
410
+ }
411
+
412
+ &:disabled {
413
+ opacity: 0.4;
414
+ cursor: not-allowed;
415
+ }
416
+ }
417
+
418
+ // Stacked stepper buttons
419
+ &__stepper &__stepper-btn {
420
+ flex: 1;
421
+
422
+ &--increment {
423
+ border-bottom: 1px solid $alias-border-default;
424
+ }
425
+ }
426
+
427
+ // When stepper is right, add padding to input
428
+ &:has(.gloss-number-input__stepper) .gloss-number-input__input {
429
+ padding-right: $space-10;
430
+ }
431
+
432
+ // Side stepper mode
433
+ &--stepper-sides {
434
+ .gloss-number-input__input {
435
+ border-radius: 0;
436
+ text-align: center;
437
+ }
438
+
439
+ .gloss-number-input__stepper-btn {
440
+ padding: 0 $space-3;
441
+ border: 1px solid $alias-border-default;
442
+ background: $alias-bg-surface;
443
+
444
+ &--decrement {
445
+ border-radius: $radius-md 0 0 $radius-md;
446
+ border-right: none;
447
+ }
448
+
449
+ &--increment {
450
+ border-radius: 0 $radius-md $radius-md 0;
451
+ border-left: none;
452
+ }
453
+
454
+ &:hover:not(:disabled) {
455
+ background: $alias-bg-hover;
456
+ }
457
+ }
458
+ }
459
+ }