@inchurch/matcha-core 22.0.0 → 22.1.1

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 (2) hide show
  1. package/core.scss +1726 -1725
  2. package/package.json +1 -1
package/core.scss CHANGED
@@ -1,1725 +1,1726 @@
1
- @use "sass:map";
2
- @use "sass:list";
3
- @use "sass:math";
4
-
5
- // -------------------------------------------------------------------------------------------------------------------
6
- // @ Breakpoints generator
7
- //
8
- // Examples:
9
- // @include media-breakpoint("xs") {
10
- // Show styles in small devices ( Phones and Gadget, 0px and up < 600px )
11
- // }
12
- // @include media-breakpoint("gt-xs") {
13
- // Show styles in medium devices (landscapes and tablets, 600px and up < 1024px )
14
- // }
15
- // @include media-breakpoint("gt-sm") {
16
- // Show styles in large devices (tablets and small monitors, 1024px and up < 1440px)
17
- // }
18
- // @include media-breakpoint("gt-md") {
19
- // Show styles in X-Large devices (big desktops, 1440px and up < 1920)
20
- // }
21
- // @include media-breakpoint("gt-lg") {
22
- // Show styles in XX-Large devices (larger desktops, 1920px and up)
23
- // }
24
- // -------------------------------------------------------------------------------------------------------------------
25
-
26
- // Media step breakpoint mixin based on Angular Material lib
27
- $breakpoints: (
28
- xs: 'screen and (max-width: 639px)',
29
- sm: 'screen and (min-width: 640px) and (max-width: 1023px)',
30
- md: 'screen and (min-width: 1024px) and (max-width: 1279px)',
31
- lg: 'screen and (min-width: 1280px) and (max-width: 1535px)',
32
- xl: 'screen and (min-width: 1536px) and (max-width: 5000px)',
33
- lt-sm: 'screen and (max-width: 639px)',
34
- lt-md: 'screen and (max-width: 1023px)',
35
- lt-lg: 'screen and (max-width: 1279px)',
36
- lt-xl: 'screen and (max-width: 1535px)',
37
- gt-xs: 'screen and (min-width: 640px)',
38
- gt-sm: 'screen and (min-width: 1024px)',
39
- gt-md: 'screen and (min-width: 1280px)',
40
- gt-lg: 'screen and (min-width: 1536px)'
41
- ) !default;
42
-
43
- // Re-map the breakpoints for the helper classes
44
- $helper-breakpoints: (
45
- initial: null,
46
- xs: 'xs',
47
- sm: 'gt-xs',
48
- md: 'gt-sm',
49
- lg: 'gt-md',
50
- xl: 'gt-lg'
51
- );
52
-
53
- @mixin media-breakpoint($breakpointName) {
54
- $mediaQuery: map.get($breakpoints, $breakpointName);
55
- @if ($mediaQuery == null) {
56
- @content;
57
- } @else {
58
- @media #{$mediaQuery} {
59
- @content;
60
- }
61
- }
62
- }
63
-
64
- // Define the variable for the base size (usually 16 pixels = 1 rem).
65
- $base-font-size: 16px;
66
-
67
- // Function to convert pixels to rem.
68
- @function px-to-rem($value-in-px) {
69
- @if $value-in-px != 0 {
70
- @return calc($value-in-px / $base-font-size) * 1rem;
71
- } @else {
72
- @return $value-in-px;
73
- }
74
- }
75
-
76
- // =====================================================================================================
77
- // DS Token maps — connect legacy utility classes to Design System CSS custom properties.
78
- // When a utility class (.px-16, .gap-8) resolves to a value with a corresponding DS token,
79
- // we emit var(--matcha-*) so Figma changes propagate. Values without direct tokens fall back to px.
80
- // =====================================================================================================
81
- $space-token-map: (
82
- 0: var(--matcha-space-0, 0),
83
- 2: var(--matcha-space-025, 2px),
84
- 4: var(--matcha-space-050, 4px),
85
- 6: var(--matcha-space-075, 6px),
86
- 8: var(--matcha-space-100, 8px),
87
- 12: var(--matcha-space-150, 12px),
88
- 16: var(--matcha-space-200, 16px),
89
- 20: var(--matcha-space-250, 20px),
90
- 24: var(--matcha-space-300, 24px),
91
- 32: var(--matcha-space-400, 32px),
92
- 40: var(--matcha-space-500, 40px),
93
- 48: var(--matcha-space-600, 48px),
94
- 64: var(--matcha-space-800, 64px),
95
- 80: var(--matcha-space-1000, 80px),
96
- 96: var(--matcha-space-1200, 96px),
97
- );
98
-
99
- $radius-token-map: (
100
- 0: var(--matcha-radius-none, 0),
101
- 2: var(--matcha-radius-sm, 2px),
102
- 4: var(--matcha-radius-md, 4px),
103
- 8: var(--matcha-radius-lg, 8px),
104
- 16: var(--matcha-radius-xl, 16px),
105
- 24: var(--matcha-radius-2xl, 24px),
106
- 9999: var(--matcha-radius-pill, 9999px),
107
- );
108
-
109
- $font-size-token-map: (
110
- 10: var(--matcha-font-size-2xs, 10px),
111
- 12: var(--matcha-font-size-xs, 12px),
112
- 14: var(--matcha-font-size-sm, 14px),
113
- 16: var(--matcha-font-size-md, 16px),
114
- 18: var(--matcha-font-size-lg, 18px),
115
- 20: var(--matcha-font-size-xl, 20px),
116
- 24: var(--matcha-font-size-2xl, 24px),
117
- 32: var(--matcha-font-size-3xl, 32px),
118
- );
119
-
120
- $font-weight-token-map: (
121
- 400: var(--matcha-weight-regular, 400),
122
- 500: var(--matcha-weight-medium, 500),
123
- 600: var(--matcha-weight-semibold, 600),
124
- 700: var(--matcha-weight-bold, 700),
125
- 800: 800, // Figma não tem weight/extrabold; literal 800
126
- 900: var(--matcha-weight-black, 900),
127
- );
128
-
129
- @function ds-space($size) {
130
- $abs-size: if($size < 0, -$size, $size);
131
- $token: map.get($space-token-map, $abs-size);
132
- @if $token != null {
133
- @if $size < 0 {
134
- @return calc(-1 * #{$token});
135
- }
136
- @return $token;
137
- }
138
- @return #{$size}px;
139
- }
140
-
141
- @function ds-radius($size) {
142
- $token: map.get($radius-token-map, $size);
143
- @if $token != null {
144
- @return $token;
145
- }
146
- @return #{$size}px;
147
- }
148
-
149
- @function ds-font-size($size) {
150
- $token: map.get($font-size-token-map, $size);
151
- @if $token != null {
152
- @return $token;
153
- }
154
- @return #{$size}px;
155
- }
156
-
157
- @function ds-font-weight($weight) {
158
- $token: map.get($font-weight-token-map, $weight);
159
- @if $token != null {
160
- @return $token;
161
- }
162
- @return $weight;
163
- }
164
-
165
- // -----------------------------------------------------------------------------------------------------
166
- // @ Size classes | Width and Height
167
- // -----------------------------------------------------------------------------------------------------
168
- @mixin _size-classes($prop, $abbrev, $length, $size, $infix: "") {
169
- .#{$abbrev}#{$infix}-#{$size} {
170
- #{$prop}: $length;
171
- }
172
-
173
- .#{$abbrev}#{$infix}-#{$size}--force {
174
- #{$prop}: $length !important;
175
- }
176
-
177
- .max-#{$abbrev}#{$infix}-#{$size} {
178
- max-#{$prop}: $length;
179
- }
180
-
181
- .max-#{$abbrev}#{$infix}-#{$size}--force {
182
- max-#{$prop}: $length !important;
183
- }
184
-
185
- .min-#{$abbrev}#{$infix}-#{$size} {
186
- min-#{$prop}: $length;
187
- }
188
-
189
- .min-#{$abbrev}#{$infix}-#{$size}--force {
190
- min-#{$prop}: $length !important;
191
- }
192
- }
193
- @mixin generate-size-classes($helper-breakpoints) {
194
- @each $breakpoint, $media-size in $helper-breakpoints {
195
- @include media-breakpoint($media-size) {
196
- $infix: if($media-size == null, "", "-#{$breakpoint}");
197
-
198
- @each $prop, $abbrev in (height: h, width: w) {
199
- // Pixels
200
- @for $index from 0 through 64 {
201
- $size: $index * 4;
202
- $length: #{$size}px;
203
-
204
- @include _size-classes($prop, $abbrev, $length, $size, $infix);
205
- }
206
-
207
- // Percentages
208
- @for $i from 0 through 20 {
209
- $i-p: 5 * $i;
210
- $size-p: 5% * $i;
211
-
212
- @include _size-classes($prop, $abbrev, $size-p, "#{$i-p}-p", $infix);
213
- }
214
-
215
- // Big sizes
216
- @for $i from 3 through 20 {
217
- $size: $i * 100;
218
- $length: #{$size}px;
219
-
220
- @include _size-classes($prop, $abbrev, $length, $size, $infix);
221
- }
222
-
223
- // Auto
224
- .#{$abbrev}#{$infix}-auto {
225
- #{$prop}: auto;
226
- }
227
-
228
- .#{$abbrev}#{$infix}-auto--force {
229
- #{$prop}: auto !important;
230
- }
231
- }
232
- }
233
- }
234
- }
235
- @include generate-size-classes($helper-breakpoints);
236
-
237
- // -----------------------------------------------------------------------------------------------------
238
- // @ Spacing classes - Margin and Padding
239
- // Generate spacing values from -64 to 64 jumping from 4 to 4
240
- // -----------------------------------------------------------------------------------------------------
241
- @mixin _spacing-classes($prop, $abbrev, $length, $size, $infix: "") {
242
- .#{$abbrev}#{$infix}-#{$size} {
243
- #{$prop}: $length;
244
- }
245
-
246
- .#{$abbrev}#{$infix}-#{$size}--force {
247
- #{$prop}: $length !important;
248
- }
249
-
250
- .#{$abbrev}x#{$infix}-#{$size} {
251
- #{$prop}-right: $length;
252
- #{$prop}-left: $length;
253
- }
254
-
255
- .#{$abbrev}x#{$infix}-#{$size}--force {
256
- #{$prop}-right: $length !important;
257
- #{$prop}-left: $length !important;
258
- }
259
-
260
- .#{$abbrev}y#{$infix}-#{$size} {
261
- #{$prop}-top: $length;
262
- #{$prop}-bottom: $length;
263
- }
264
-
265
- .#{$abbrev}y#{$infix}-#{$size}--force {
266
- #{$prop}-top: $length !important;
267
- #{$prop}-bottom: $length !important;
268
- }
269
-
270
- .#{$abbrev}t#{$infix}-#{$size} {
271
- #{$prop}-top: $length;
272
- }
273
-
274
- .#{$abbrev}t#{$infix}-#{$size}--force {
275
- #{$prop}-top: $length !important;
276
- }
277
-
278
- .#{$abbrev}r#{$infix}-#{$size} {
279
- #{$prop}-right: $length;
280
- }
281
-
282
- .#{$abbrev}r#{$infix}-#{$size}--force {
283
- #{$prop}-right: $length !important;
284
- }
285
-
286
- .#{$abbrev}b#{$infix}-#{$size} {
287
- #{$prop}-bottom: $length;
288
- }
289
-
290
- .#{$abbrev}b#{$infix}-#{$size}--force {
291
- #{$prop}-bottom: $length !important;
292
- }
293
-
294
- .#{$abbrev}l#{$infix}-#{$size} {
295
- #{$prop}-left: $length;
296
- }
297
-
298
- .#{$abbrev}l#{$infix}-#{$size}--force {
299
- #{$prop}-left: $length !important;
300
- }
301
- }
302
- @mixin generate-spacing-classes($helper-breakpoints) {
303
- @each $breakpoint, $media-size in $helper-breakpoints {
304
- @include media-breakpoint($media-size) {
305
- $infix: if($media-size == null, "", "-#{$breakpoint}");
306
-
307
- @each $prop, $abbrev in (margin: m, padding: p) {
308
- // For margins, include negative values
309
- @for $index from -16 through 16 {
310
- $size: $index * 4;
311
- $length: ds-space($size); // uses --matcha-space-* tokens when available
312
-
313
- @include _spacing-classes($prop, $abbrev, $length, $size, $infix);
314
- }
315
-
316
- // For paddings, only positive values
317
- @if ($prop == padding) {
318
- @for $index from 0 through 24 {
319
- $size: $index * 4;
320
- $length: ds-space($size); // uses --matcha-space-* tokens when available
321
-
322
- @include _spacing-classes($prop, $abbrev, $length, $size, $infix);
323
- }
324
- }
325
-
326
- // Special auto classes for margin
327
- @if ($prop == margin) {
328
- .m#{$infix}-auto {
329
- margin: auto;
330
- }
331
-
332
- .m#{$infix}-auto--force {
333
- margin: auto !important;
334
- }
335
-
336
- .mt#{$infix}-auto {
337
- margin-top: auto;
338
- }
339
-
340
- .mt#{$infix}-auto--force {
341
- margin-top: auto !important;
342
- }
343
-
344
- .mr#{$infix}-auto {
345
- margin-right: auto;
346
- }
347
-
348
- .mr#{$infix}-auto--force {
349
- margin-right: auto !important;
350
- }
351
-
352
- .mb#{$infix}-auto {
353
- margin-bottom: auto;
354
- }
355
-
356
- .mb#{$infix}-auto--force {
357
- margin-bottom: auto !important;
358
- }
359
-
360
- .ml#{$infix}-auto {
361
- margin-left: auto;
362
- }
363
-
364
- .ml#{$infix}-auto--force {
365
- margin-left: auto !important;
366
- }
367
-
368
- .mx#{$infix}-auto {
369
- margin-right: auto;
370
- margin-left: auto;
371
- }
372
-
373
- .mx#{$infix}-auto--force {
374
- margin-right: auto !important;
375
- margin-left: auto !important;
376
- }
377
-
378
- .my#{$infix}-auto {
379
- margin-top: auto;
380
- margin-bottom: auto;
381
- }
382
-
383
- .my#{$infix}-auto--force {
384
- margin-top: auto !important;
385
- margin-bottom: auto !important;
386
- }
387
- }
388
- }
389
- }
390
- }
391
- }
392
- @include generate-spacing-classes($helper-breakpoints);
393
-
394
- // -------------------------------------------------------------------------------------------------------------------
395
- // @ Display classes | Flex and Grid
396
- // -------------------------------------------------------------------------------------------------------------------
397
- @mixin _grid-prop($i) {
398
- display: grid;
399
- grid-template-columns: repeat($i, minmax(0, 1fr));
400
- }
401
- @mixin generate-layout-grid($helper-breakpoints) {
402
- $grid-length: 12;
403
- $grid-prefix: "col";
404
-
405
- [class^="grid-"] {
406
- display: grid;
407
- grid-template-columns: minmax(0, 1fr);
408
- }
409
-
410
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
411
- @include media-breakpoint($materialBreakpoint) {
412
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
413
-
414
- @for $i from 1 through $grid-length {
415
- .grid#{$infix}-#{$i} {
416
- @include _grid-prop($i);
417
- }
418
-
419
- .span#{$infix}-#{$i}c,
420
- .colspan#{$infix}-#{$i} {
421
- grid-column-end: span #{$i};
422
- }
423
-
424
- .span#{$infix}-#{$i}r,
425
- .rowspan#{$infix}-#{$i} {
426
- grid-row-end: span #{$i};
427
- }
428
- }
429
- }
430
- }
431
- }
432
- @mixin generate-layout-flex($helper-breakpoints) {
433
- $grid-length: 12;
434
- $grid-prefix: "col";
435
- .row {
436
- display: flex;
437
- flex-wrap: wrap;
438
-
439
- > div[class*="#{$grid-prefix}-"] {
440
- box-sizing: border-box;
441
- }
442
-
443
- > div:not([class*="#{$grid-prefix}-"]) {
444
- flex: 1;
445
- }
446
-
447
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
448
- @include media-breakpoint($materialBreakpoint) {
449
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
450
-
451
- @for $i from 1 through $grid-length {
452
- .#{$grid-prefix}#{$infix}-#{$i} {
453
- flex-basis: math.percentage(math.div($i, $grid-length));
454
- }
455
-
456
- .#{$grid-prefix}-offset#{$infix}-#{$i} {
457
- margin-left: math.percentage(math.div($i, $grid-length));
458
- }
459
- }
460
- @each $classLabel, $cssValue in (align-start flex-start, align-center center, align-end flex-end) {
461
- > div[class*="#{$grid-prefix}-"].#{$classLabel} {
462
- align-self: $cssValue;
463
- }
464
- }
465
-
466
- @each $classLabel, $cssValue in (align-start flex-start, align-center center, align-end flex-end, space-around space-around, space-between space-between) {
467
- &.#{$classLabel} {
468
- justify-content: $cssValue;
469
- }
470
- }
471
- }
472
- }
473
- }
474
- }
475
- @include generate-layout-grid($helper-breakpoints);
476
- @include generate-layout-flex($helper-breakpoints);
477
-
478
- // -------------------------------------------------------------------------------------------------------------------
479
- // @Gaps classes
480
- // -------------------------------------------------------------------------------------------------------------------
481
- @mixin generate-gap-classes($helper-breakpoints) {
482
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
483
- @include media-breakpoint($materialBreakpoint) {
484
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
485
-
486
- @for $i from 0 through 12 {
487
- $size: $i * 4;
488
- $gap-value: ds-space($size);
489
- .gap#{$infix}-#{$size} {
490
- column-gap: $gap-value;
491
- row-gap: $gap-value;
492
- }
493
- }
494
- }
495
- }
496
- // Dynamic gaps
497
- .gap-inside {
498
- -moz-column-gap: var(--matcha-space-200, 16px);
499
- column-gap: var(--matcha-space-200, 16px);
500
- row-gap: var(--matcha-space-200, 16px);
501
- }
502
- .gap-outside {
503
- -moz-column-gap: var(--matcha-space-200, 16px);
504
- column-gap: var(--matcha-space-200, 16px);
505
- row-gap: var(--matcha-space-200, 16px);
506
- }
507
- @media screen and (min-width: 640px) {
508
- .gap-outside {
509
- -moz-column-gap: var(--matcha-space-300, 24px);
510
- column-gap: var(--matcha-space-300, 24px);
511
- row-gap: var(--matcha-space-300, 24px);
512
- }
513
- }
514
- }
515
- @include generate-gap-classes($helper-breakpoints);
516
-
517
- // Gap de 2px — o gerador acima salta de 4 em 4 (0/4/8…); 2px = --matcha-space-025 (token DSV3).
518
- .gap-2 {
519
- column-gap: var(--matcha-space-025, 2px);
520
- row-gap: var(--matcha-space-025, 2px);
521
- }
522
-
523
- // -----------------------------------------------------------------------------------------------------
524
- // @ Z-index classes
525
- // -----------------------------------------------------------------------------------------------------
526
- @mixin generate-z-index-classes($helper-breakpoints) {
527
- @each $breakpoint, $breakpointName in $helper-breakpoints {
528
- @include media-breakpoint($breakpointName) {
529
- $infix: if($breakpointName == null, "", "-#{$breakpoint}");
530
-
531
- @for $i from -1 through 24 {
532
- .z-index#{$infix}-#{$i} {
533
- z-index: #{$i};
534
- }
535
-
536
- .z-index#{$infix}-#{$i}--force {
537
- z-index: #{$i} !important;
538
- }
539
- }
540
- }
541
- }
542
- }
543
- @include generate-z-index-classes($helper-breakpoints);
544
-
545
- // -----------------------------------------------------------------------------------------------------
546
- // @ Order classes
547
- // -----------------------------------------------------------------------------------------------------
548
- @mixin generate-order-classes($helper-breakpoints) {
549
- @each $breakpoint, $breakpointName in $helper-breakpoints {
550
- @include media-breakpoint($breakpointName) {
551
- $infix: if($breakpointName == null, "", "-#{$breakpoint}");
552
-
553
- /* <integer> values */
554
- @for $i from -12 through 12 {
555
- .order#{$infix}-#{$i} {
556
- order: #{$i};
557
- }
558
-
559
- .order#{$infix}-#{$i}--force {
560
- order: #{$i} !important;
561
- }
562
- }
563
-
564
- /* Global values */
565
- @each $value in (inherit, initial) {
566
- .order#{$infix}-#{$value} {
567
- order: #{$value};
568
- }
569
-
570
- .order#{$infix}-#{$value}--force {
571
- order: #{$value} !important;
572
- }
573
- }
574
- }
575
- }
576
- }
577
- @include generate-order-classes($helper-breakpoints);
578
-
579
- // -----------------------------------------------------------------------------------------------------
580
- // @ Absolute position alignment classes
581
- // -----------------------------------------------------------------------------------------------------
582
- @mixin generate-position-classes($helper-breakpoints) {
583
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
584
- @include media-breakpoint($materialBreakpoint) {
585
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
586
-
587
- @each $position in (top, right, bottom, left) {
588
- .place#{$infix}-#{$position} {
589
- #{$position}: 0;
590
- }
591
-
592
- .place#{$infix}-#{$position}--force {
593
- #{$position}: 0 !important;
594
- }
595
- }
596
- }
597
- }
598
- }
599
- @include generate-position-classes($helper-breakpoints);
600
-
601
- // -----------------------------------------------------------------------------------------------------
602
- // @ Position classes
603
- // -----------------------------------------------------------------------------------------------------
604
- @mixin generate-position-classes($helper-breakpoints) {
605
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
606
- @include media-breakpoint($materialBreakpoint) {
607
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
608
-
609
- @each $pos in (relative, absolute, static, fixed, sticky) {
610
- .position#{$infix}-#{$pos} {
611
- position: #{$pos};
612
- }
613
-
614
- .position#{$infix}-#{$pos}--force {
615
- position: #{$pos} !important;
616
- }
617
- }
618
- }
619
- }
620
- }
621
- @include generate-position-classes($helper-breakpoints);
622
-
623
- // -----------------------------------------------------------------------------------------------------
624
- // @ Display classes
625
- // -----------------------------------------------------------------------------------------------------
626
- @mixin generate-display-classes($helper-breakpoints) {
627
- @each $breakpoint, $media-size in $helper-breakpoints {
628
- @include media-breakpoint($media-size) {
629
- $infix: if($media-size == null, "", "-#{$breakpoint}");
630
-
631
- @each $class-suffix, $value in (
632
- none: none,
633
- inline: inline,
634
- inline-block: inline-block,
635
- block: block,
636
- grid: grid,
637
- table: table,
638
- table-cell: table-cell,
639
- table-row: table-row,
640
- inline-flex: inline-flex,
641
- flex: flex
642
- ) {
643
- .d#{$infix}-#{$class-suffix} {
644
- display: $value;
645
- }
646
-
647
- .d#{$infix}-#{$class-suffix}--force {
648
- display: $value !important;
649
- }
650
- }
651
- }
652
- }
653
- }
654
- @include generate-display-classes($helper-breakpoints);
655
-
656
- // -----------------------------------------------------------------------------------------------------
657
- // @ Flex classes
658
- // -----------------------------------------------------------------------------------------------------
659
- @mixin generate-flex-classes($helper-breakpoints) {
660
- @each $breakpoint, $media-size in $helper-breakpoints {
661
- @include media-breakpoint($media-size) {
662
- $infix: if($media-size == null, "", "-#{$breakpoint}");
663
-
664
- @each $class-suffix, $value in (
665
- row: (display:flex, flex-direction: row),
666
- row-reverse: (display:flex, flex-direction: row-reverse),
667
- column: (display:flex, flex-direction: column),
668
- column-reverse: (display:flex, flex-direction: column-reverse),
669
-
670
- nowrap: (flex-wrap: nowrap),
671
- wrap: (flex-wrap: wrap),
672
-
673
- align-center: (display:flex, align-items: center),
674
- align-start: (display:flex, align-items: flex-start),
675
- align-end: (display:flex, align-items: flex-end),
676
- align-inherit: (display:flex, align-items: inherit),
677
- align-initial: (display:flex, align-items: initial),
678
-
679
- align-self-end: (display:flex, align-self: flex-end),
680
- align-self-start: (display:flex, align-self: flex-start),
681
- align-self-inherit: (display:flex, align-self: inherit),
682
- align-self-initial: (display:flex, align-self: initial),
683
-
684
- center-center: (display:flex, justify-content: center, align-items: center),
685
-
686
- justify-center: (display:flex, justify-content: center),
687
- center: (display:flex, justify-content: center),
688
-
689
- justify-end: (display:flex, justify-content: flex-end),
690
- end: (display:flex, justify-content: flex-end),
691
-
692
- justify-start: (display:flex, justify-content: flex-start),
693
- start: (display:flex, justify-content: flex-start),
694
-
695
- justify-inherit: (display:flex, justify-content: inherit),
696
- inherit: (display:flex, justify-content: inherit),
697
-
698
- justify-initial: (display:flex, justify-content: initial),
699
- initial: (display:flex, justify-content: initial),
700
-
701
- left: (display:flex, justify-content: left),
702
- right: (display:flex, justify-content: right),
703
- normal: (display:flex, justify-content: normal),
704
- revert: (display:flex, justify-content: revert),
705
-
706
- space-around: (display:flex, justify-content: space-around),
707
- around: (display:flex, justify-content: space-around),
708
-
709
- space-between: (display:flex, justify-content: space-between),
710
- between: (display:flex, justify-content: space-between),
711
-
712
- space-evenly: (display:flex, justify-content: space-evenly),
713
- evenly: (display:flex, justify-content: space-evenly),
714
-
715
- stretch: (display:flex, justify-content: stretch),
716
- unset: (display:flex, justify-content: unset)
717
-
718
- ) {
719
- $class-name: ".flex#{$infix}-#{$class-suffix}";
720
- $class-name-force: ".flex#{$infix}-#{$class-suffix}--force";
721
-
722
- #{$class-name} {
723
- @each $property, $prop-value in $value {
724
- #{$property}: #{$prop-value};
725
- }
726
- }
727
-
728
- #{$class-name-force} {
729
- @each $property, $prop-value in $value {
730
- #{$property}: #{$prop-value} !important;
731
- }
732
- }
733
- }
734
- // For margins, include negative values
735
- @for $index from 0 through 3 {
736
- .flex#{$infix}-grow-#{$index} {
737
- flex-grow: $index;
738
- }
739
- .flex#{$infix}-shrink-#{$index} {
740
- flex-shrink: $index;
741
- }
742
- }
743
- .flex#{$infix}-full {
744
- flex-grow: 1;
745
- flex-shrink: 1;
746
- flex-basis: 100%;
747
- ;
748
- }
749
- .flex#{$infix}-basis-1 {
750
- flex-basis: 100%;
751
- }
752
- }
753
- }
754
- }
755
- @include generate-flex-classes($helper-breakpoints);
756
-
757
- // -----------------------------------------------------------------------------------------------------
758
- // @ Font Weight classes
759
- // -----------------------------------------------------------------------------------------------------
760
- @mixin generate-font-weight-classes($helper-breakpoints) {
761
- @each $breakpoint, $media-size in $helper-breakpoints {
762
- @include media-breakpoint($media-size) {
763
- $infix: if($media-size == null, "", "-#{$breakpoint}");
764
-
765
- @for $index from 1 through 9 {
766
- $weight: $index * 100;
767
- $weight-value: ds-font-weight($weight);
768
-
769
- .fw#{$infix}-#{$weight} {
770
- font-weight: $weight-value;
771
- }
772
-
773
- .fw#{$infix}-#{$weight}--force {
774
- font-weight: $weight-value !important;
775
- }
776
- }
777
- }
778
- }
779
- }
780
- @include generate-font-weight-classes($helper-breakpoints);
781
-
782
- // -----------------------------------------------------------------------------------------------------
783
- // @ Font Size classes
784
- // -----------------------------------------------------------------------------------------------------
785
- @mixin generate-font-size-classes($helper-breakpoints) {
786
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
787
- @include media-breakpoint($materialBreakpoint) {
788
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
789
- $index: 0;
790
- @while $index <= 96 {
791
- $size: $index;
792
- $fs-value: ds-font-size($size);
793
- .fs#{$infix}-#{$size} {
794
- font-size: $fs-value;
795
- }
796
- .fs#{$infix}-#{$size}--force {
797
- font-size: $fs-value !important;
798
- }
799
- $index: $index + 1;
800
- }
801
- }
802
- }
803
- }
804
- @include generate-font-size-classes($helper-breakpoints);
805
-
806
- // -----------------------------------------------------------------------------------------------------
807
- // @ Letter Spacing classes
808
- // -----------------------------------------------------------------------------------------------------
809
- @mixin generate-letter-spacing-classes($helper-breakpoints) {
810
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
811
- @include media-breakpoint($materialBreakpoint) {
812
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
813
- $index: 0;
814
- @while $index <= 18 {
815
- $spacing: $index * 0.1;
816
- .ls#{$infix}-#{$index} {
817
- letter-spacing: #{$spacing}em;
818
- }
819
- .ls#{$infix}-#{$index}--force {
820
- letter-spacing: #{$spacing}em !important;
821
- }
822
- $index: $index + 1;
823
- }
824
-
825
- }
826
- }
827
- }
828
- @include generate-letter-spacing-classes($helper-breakpoints);
829
-
830
- // -----------------------------------------------------------------------------------------------------
831
- // @ Line Height classes
832
- // -----------------------------------------------------------------------------------------------------
833
- @mixin generate-line-height-classes($helper-breakpoints) {
834
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
835
- @include media-breakpoint($materialBreakpoint) {
836
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
837
-
838
- $index: 0;
839
- @while $index <= 100 {
840
- $height: $index * 1;
841
-
842
- .lh#{$infix}-#{$height} {
843
- line-height: #{$height}px;
844
- }
845
-
846
- .lh#{$infix}-#{$height}--force {
847
- line-height: #{$height}px !important;
848
- }
849
-
850
- $index: $index + 1;
851
- }
852
- }
853
- }
854
- }
855
- @include generate-line-height-classes($helper-breakpoints);
856
-
857
- // -----------------------------------------------------------------------------------------------------
858
- // @ Text Styles (composite — Figma matcha/text/*) → size + weight + line-height (+ letter-spacing/transform)
859
- // Uma classe aplica o text style INTEIRO, token-backed. Nomes seguem --matcha-text-* (canônico DS).
860
- // Não colide com os utilitários text-* single-prop (center/uppercase/truncate/...): sufixos distintos.
861
- // Pareamento size/weight/leading/tracking espelha matcha-theme/tokens/_emit-tokens.scss:103-148
862
- // (weight por estilo não é tokenizado → mapeia pro --matcha-weight-* correspondente).
863
- // -----------------------------------------------------------------------------------------------------
864
- @mixin generate-text-style-classes($helper-breakpoints) {
865
- // name: (size, weight, line-height, letter-spacing-or-null, text-transform-or-null)
866
- $text-styles: (
867
- display-hero: (var(--matcha-text-display-hero, 36px), var(--matcha-weight-extrabold, 800), var(--matcha-leading-display-hero, 40px), var(--matcha-tracking-display-hero, -1.2px), null),
868
- display: (var(--matcha-text-display, 32px), var(--matcha-weight-bold, 700), var(--matcha-leading-display, 40px), var(--matcha-tracking-display, -0.3px), null),
869
- headline: (var(--matcha-text-headline, 24px), var(--matcha-weight-bold, 700), var(--matcha-leading-headline, 32px), var(--matcha-tracking-headline, -0.3px), null),
870
- title-lg: (var(--matcha-text-title-lg, 20px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-lg, 28px), null, null),
871
- title-md: (var(--matcha-text-title-md, 18px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-md, 24px), null, null),
872
- title-sm: (var(--matcha-text-title-sm, 16px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-sm, 22px), null, null),
873
- title-xs: (var(--matcha-text-title-xs, 14px), var(--matcha-weight-extrabold, 800), var(--matcha-leading-title-xs, 20px), null, null),
874
- body-lg: (var(--matcha-text-body-lg, 16px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-lg, 24px), null, null),
875
- body-md: (var(--matcha-text-body-md, 14px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-md, 20px), null, null),
876
- body-sm: (var(--matcha-text-body-sm, 12px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-sm, 16px), null, null),
877
- p-tiny: (var(--matcha-text-p-tiny, 11px), var(--matcha-weight-regular, 400), var(--matcha-leading-p-tiny, 14px), var(--matcha-tracking-p-tiny, 0.3px), null),
878
- label-lg: (var(--matcha-text-label-lg, 16px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-lg, 22px), null, null),
879
- label-md: (var(--matcha-text-label-md, 14px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-md, 20px), null, null),
880
- label-sm: (var(--matcha-text-label-sm, 12px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-sm, 16px), null, null),
881
- overline: (var(--matcha-text-overline, 10px), var(--matcha-weight-semibold, 600), var(--matcha-leading-overline, 14px), var(--matcha-tracking-overline, 1px), uppercase),
882
- );
883
-
884
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
885
- @include media-breakpoint($materialBreakpoint) {
886
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
887
-
888
- @each $name, $props in $text-styles {
889
- $size: list.nth($props, 1);
890
- $weight: list.nth($props, 2);
891
- $leading: list.nth($props, 3);
892
- $tracking: list.nth($props, 4);
893
- $transform: list.nth($props, 5);
894
-
895
- .text#{$infix}-#{$name} {
896
- font-size: $size;
897
- font-weight: $weight;
898
- line-height: $leading;
899
- @if $tracking != null { letter-spacing: $tracking; }
900
- @if $transform != null { text-transform: $transform; }
901
- }
902
- .text#{$infix}-#{$name}--force {
903
- font-size: $size !important;
904
- font-weight: $weight !important;
905
- line-height: $leading !important;
906
- @if $tracking != null { letter-spacing: $tracking !important; }
907
- @if $transform != null { text-transform: $transform !important; }
908
- }
909
- }
910
- }
911
- }
912
- }
913
- @include generate-text-style-classes($helper-breakpoints);
914
-
915
- // -----------------------------------------------------------------------------------------------------
916
- // @ Aspect Ratio classes
917
- // -----------------------------------------------------------------------------------------------------
918
- @mixin generate-aspect-ratio-classes($helper-breakpoints) {
919
- // Aspect ratios definition
920
- $aspect-ratios: (
921
- 'auto': 'auto',
922
- '1x1': '1/1',
923
- '1x2': '1/2',
924
- '2x1': '2/1',
925
- '3x4': '3/4',
926
- '4x3': '4/3',
927
- '9x16': '9/16',
928
- '16x9': '16/9',
929
- 'half': '0.5',
930
- 'inherit': 'inherit',
931
- 'initial': 'initial',
932
- 'unset': 'unset'
933
- );
934
-
935
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
936
- @include media-breakpoint($materialBreakpoint) {
937
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
938
-
939
- @each $ratio, $value in $aspect-ratios {
940
- $class-name: ".aspect-ratio#{$infix}-#{$ratio}";
941
-
942
- #{$class-name} {
943
- aspect-ratio: #{$value};
944
- }
945
-
946
- #{$class-name}--force {
947
- aspect-ratio: #{$value} !important;
948
- }
949
- }
950
- }
951
- }
952
- }
953
- @include generate-aspect-ratio-classes($helper-breakpoints);
954
-
955
- // -----------------------------------------------------------------------------------------------------
956
- // @ Cursor classes
957
- // -----------------------------------------------------------------------------------------------------
958
- @mixin generate-cursor-classes($helper-breakpoints) {
959
- $cursor-types: (
960
- pointer,
961
- default,
962
- grab,
963
- grabbing,
964
- move,
965
- help,
966
- wait
967
- );
968
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
969
- @include media-breakpoint($materialBreakpoint) {
970
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
971
-
972
- @for $i from 1 through list.length($cursor-types) {
973
- $cursor-type: list.nth($cursor-types, $i);
974
-
975
- .cursor-#{$cursor-type}#{$infix} {
976
- cursor: #{$cursor-type};
977
- }
978
-
979
- .cursor-#{$cursor-type}#{$infix}--force {
980
- cursor: #{$cursor-type} !important;
981
- }
982
- }
983
- }
984
- }
985
- }
986
- @include generate-cursor-classes($helper-breakpoints);
987
-
988
- // -----------------------------------------------------------------------------------------------------
989
- // @ Pointer Events classes
990
- // -----------------------------------------------------------------------------------------------------
991
- @mixin generate-pointer-events-classes($helper-breakpoints) {
992
- $pointer-events: (
993
- auto,
994
- none,
995
- all,
996
- visible,
997
- visiblePainted,
998
- visibleFill,
999
- visibleStroke,
1000
- painted,
1001
- fill,
1002
- stroke
1003
- );
1004
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1005
- @include media-breakpoint($materialBreakpoint) {
1006
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1007
-
1008
- @for $i from 1 through list.length($pointer-events) {
1009
- $pointer-event: list.nth($pointer-events, $i);
1010
-
1011
- .pointer-events-#{$pointer-event}#{$infix} {
1012
- pointer-events: #{$pointer-event};
1013
- }
1014
-
1015
- .pointer-events-#{$pointer-event}#{$infix}--force {
1016
- pointer-events: #{$pointer-event} !important;
1017
- }
1018
- }
1019
- }
1020
- }
1021
- }
1022
- @include generate-pointer-events-classes($helper-breakpoints);
1023
-
1024
-
1025
- // -----------------------------------------------------------------------------------------------------
1026
- // @ Opacity
1027
- // -----------------------------------------------------------------------------------------------------
1028
- @mixin generate-opacity-classes($helper-breakpoints) {
1029
- // Definindo os valores de opacidade e seus nomes de classe
1030
- $opacity-values: (
1031
- '0': 0,
1032
- '01': 0.1,
1033
- '02': 0.2,
1034
- '03': 0.3,
1035
- '04': 0.4,
1036
- '05': 0.5,
1037
- '06': 0.6,
1038
- '07': 0.7,
1039
- '08': 0.8,
1040
- '09': 0.9,
1041
- '10': 1.0,
1042
- '1':1
1043
- );
1044
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1045
- @include media-breakpoint($materialBreakpoint) {
1046
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1047
- @each $step, $opacity in $opacity-values {
1048
- .opacity#{$infix}-#{$step} {
1049
- opacity: $opacity;
1050
- }
1051
- .opacity#{$infix}-#{$step}--force {
1052
- opacity: $opacity !important;
1053
- }
1054
- }
1055
- }
1056
- }
1057
- }
1058
- @include generate-opacity-classes($helper-breakpoints);
1059
-
1060
- // -----------------------------------------------------------------------------------------------------
1061
- // @ Float & List Style
1062
- // -----------------------------------------------------------------------------------------------------
1063
- @mixin generate-float-list-classes {
1064
- .clearfix::after {
1065
- content: "";
1066
- clear: both;
1067
- display: table;
1068
- }
1069
-
1070
- .float-left {
1071
- float: left;
1072
- }
1073
-
1074
- .float-right {
1075
- float: right;
1076
- }
1077
-
1078
- .list-style-none {
1079
- list-style: none;
1080
- }
1081
-
1082
- .list-style-disc {
1083
- list-style: disc;
1084
- }
1085
-
1086
- .list-style-dot {
1087
- list-style: dot;
1088
- }
1089
- }
1090
- @include generate-float-list-classes;
1091
-
1092
- // -----------------------------------------------------------------------------------------------------
1093
- // @ Text Decoration Helpers
1094
- // -----------------------------------------------------------------------------------------------------
1095
- @mixin generate-text-decoration-classes($helper-breakpoints){
1096
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1097
- @include media-breakpoint($materialBreakpoint) {
1098
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1099
-
1100
- .text#{$infix}-decoration-strike,
1101
- .text#{$infix}-strike,
1102
- .text#{$infix}-line-through {
1103
- text-decoration: line-through;
1104
- }
1105
-
1106
- .text#{$infix}-decoration-strike--force,
1107
- .text#{$infix}-strike--force,
1108
- .text#{$infix}-line-through--force {
1109
- text-decoration: line-through !important;
1110
- }
1111
-
1112
- .text#{$infix}-decoration-none,
1113
- .text#{$infix}-none {
1114
- text-decoration: none;
1115
- }
1116
-
1117
- .text#{$infix}-decoration-none--force,
1118
- .text#{$infix}-none--force {
1119
- text-decoration: none !important;
1120
- }
1121
-
1122
- .text#{$infix}-super {
1123
- vertical-align: super;
1124
- }
1125
-
1126
- .text#{$infix}-super--force {
1127
- vertical-align: super !important;
1128
- }
1129
-
1130
- .text#{$infix}-sub {
1131
- vertical-align: sub;
1132
- }
1133
-
1134
- .text#{$infix}-sub--force {
1135
- vertical-align: sub !important;
1136
- }
1137
- }
1138
- }
1139
- }
1140
- @include generate-text-decoration-classes($helper-breakpoints);
1141
-
1142
- // -----------------------------------------------------------------------------------------------------
1143
- // @ Text Alignment and Transform Helpers
1144
- // -----------------------------------------------------------------------------------------------------
1145
- @mixin generate-text-alignment-classes($helper-breakpoints){
1146
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1147
- @include media-breakpoint($materialBreakpoint) {
1148
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1149
-
1150
- .text#{$infix}-capitalize {
1151
- text-transform: capitalize;
1152
- }
1153
-
1154
- .text#{$infix}-capitalize--force {
1155
- text-transform: capitalize !important;
1156
- }
1157
-
1158
- .text#{$infix}-lowercase {
1159
- text-transform: lowercase;
1160
- }
1161
-
1162
- .text#{$infix}-lowercase--force {
1163
- text-transform: lowercase !important;
1164
- }
1165
-
1166
- .text#{$infix}-uppercase {
1167
- text-transform: uppercase;
1168
- }
1169
-
1170
- .text#{$infix}-uppercase--force {
1171
- text-transform: uppercase !important;
1172
- }
1173
-
1174
- .text#{$infix}-nowrap {
1175
- white-space: nowrap;
1176
- }
1177
-
1178
- .text#{$infix}-left {
1179
- text-align: left;
1180
- }
1181
-
1182
- .text#{$infix}-left--force {
1183
- text-align: left !important;
1184
- }
1185
-
1186
- .text#{$infix}-center {
1187
- text-align: center;
1188
- }
1189
-
1190
- .text#{$infix}-center--force {
1191
- text-align: center !important;
1192
- }
1193
-
1194
- .text#{$infix}-right {
1195
- text-align: right;
1196
- }
1197
-
1198
- .text#{$infix}-right--force {
1199
- text-align: right !important;
1200
- }
1201
- }
1202
- }
1203
- }
1204
- @include generate-text-alignment-classes($helper-breakpoints);
1205
-
1206
- // -----------------------------------------------------------------------------------------------------
1207
- // @ Text Spacing and Truncation Helpers
1208
- // -----------------------------------------------------------------------------------------------------
1209
- @mixin generate-text-spacing-classes($helper-breakpoints){
1210
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1211
- @include media-breakpoint($materialBreakpoint) {
1212
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1213
-
1214
- .text#{$infix}-boxed {
1215
- border-radius: 2px;
1216
- padding: 4px 8px;
1217
- margin: 0 8px;
1218
- font-size: 11px;
1219
- font-weight: 600;
1220
- white-space: nowrap;
1221
- }
1222
-
1223
- .text#{$infix}-truncate,
1224
- .text#{$infix}-ellipsis {
1225
- display: block;
1226
- overflow: hidden;
1227
- text-overflow: ellipsis;
1228
- white-space: nowrap;
1229
- }
1230
- }
1231
- }
1232
- }
1233
- @include generate-text-spacing-classes($helper-breakpoints);
1234
-
1235
- // -----------------------------------------------------------------------------------------------------
1236
- // @ Overflow Helpers
1237
- // -----------------------------------------------------------------------------------------------------
1238
- @mixin generate-overflow-classes($helper-breakpoints){
1239
- $overflow-classes: (
1240
- auto: auto,
1241
- scroll: scroll,
1242
- hidden: hidden,
1243
- overlay: overlay
1244
- );
1245
-
1246
- $overflow-directions: (
1247
- x: (auto: auto, scroll: scroll, hidden: hidden, overlay: overlay),
1248
- y: (auto: auto, scroll: scroll, hidden: hidden, overlay: overlay)
1249
- );
1250
-
1251
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1252
- @include media-breakpoint($materialBreakpoint) {
1253
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1254
-
1255
- // Classes para overflow geral
1256
- @each $class, $value in $overflow-classes {
1257
- .overflow#{$infix}-#{$class} {
1258
- overflow: $value;
1259
- }
1260
- .overflow#{$infix}-#{$class}--force {
1261
- overflow: $value !important;
1262
- }
1263
- }
1264
-
1265
- // Classes para overflow no eixo x
1266
- @each $class, $value in map.get($overflow-directions, x) {
1267
- .overflow-x#{$infix}-#{$class} {
1268
- overflow-x: $value;
1269
- }
1270
- .overflow-x#{$infix}-#{$class}--force {
1271
- overflow-x: $value !important;
1272
- }
1273
- }
1274
-
1275
- // Classes para overflow no eixo y
1276
- @each $class, $value in map.get($overflow-directions, y) {
1277
- .overflow-y#{$infix}-#{$class} {
1278
- overflow-y: $value;
1279
- }
1280
- .overflow-y#{$infix}-#{$class}--force {
1281
- overflow-y: $value !important;
1282
- }
1283
- }
1284
- }
1285
- }
1286
- }
1287
- @include generate-overflow-classes($helper-breakpoints);
1288
-
1289
- // -----------------------------------------------------------------------------------------------------
1290
- // @ Border Size Helpers
1291
- // -----------------------------------------------------------------------------------------------------
1292
- @mixin generate-border-size-classes($helper-breakpoints){
1293
- $border-directions: (bottom: bb, top: bt, left: bl, right: br);
1294
-
1295
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1296
- @include media-breakpoint($materialBreakpoint) {
1297
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1298
-
1299
- @for $i from 0 through 4 {
1300
- $border-value: $i * 2;
1301
- $border-suffix: "-#{$border-value}";
1302
-
1303
- // Classes para borda geral
1304
- .border#{$infix}#{$border-suffix},
1305
- .b#{$infix}#{$border-suffix} {
1306
- border: #{$border-value}px solid;
1307
- }
1308
-
1309
- // Classes para bordas individuais
1310
- @each $direction, $abbrev in $border-directions {
1311
- .border-#{$direction}#{$infix}#{$border-suffix},
1312
- .#{$abbrev}#{$infix}#{$border-suffix} {
1313
- border-#{$direction}: #{$border-value}px solid;
1314
- }
1315
- .border-#{$direction}#{$infix}#{$border-suffix}--force,
1316
- .#{$abbrev}#{$infix}#{$border-suffix}--force {
1317
- border-#{$direction}: #{$border-value}px solid !important;
1318
- }
1319
- }
1320
- }
1321
- // Classe para borda nula
1322
- .b#{$infix}-none,
1323
- .border#{$infix}-none {
1324
- border: none;
1325
- }
1326
- .b#{$infix}-none--force,
1327
- .border#{$infix}-none--force {
1328
- border: none !important;
1329
- }
1330
-
1331
- // Borda hairline (1px) — o loop acima só emite pares (0/2/4/6/8).
1332
- // 1px é o valor que faltava da família e é token DSV3: --matcha-border-hairline.
1333
- .border#{$infix}-1,
1334
- .b#{$infix}-1 {
1335
- border: var(--matcha-border-hairline, 1px) solid;
1336
- }
1337
- .border#{$infix}-1--force,
1338
- .b#{$infix}-1--force {
1339
- border: var(--matcha-border-hairline, 1px) solid !important;
1340
- }
1341
- @each $direction, $abbrev in $border-directions {
1342
- .border-#{$direction}#{$infix}-1,
1343
- .#{$abbrev}#{$infix}-1 {
1344
- border-#{$direction}: var(--matcha-border-hairline, 1px) solid;
1345
- }
1346
- .border-#{$direction}#{$infix}-1--force,
1347
- .#{$abbrev}#{$infix}-1--force {
1348
- border-#{$direction}: var(--matcha-border-hairline, 1px) solid !important;
1349
- }
1350
- }
1351
- }
1352
- }
1353
-
1354
-
1355
- }
1356
- @include generate-border-size-classes($helper-breakpoints);
1357
-
1358
- // -----------------------------------------------------------------------------------------------------
1359
- // @ Border Named Widths (token-backed — Figma matcha/border/{hairline,thin,medium,thick})
1360
- // Espelha o gerador numérico acima, mas nomeado e ligado ao token. Cor herda currentColor
1361
- // (cor de borda continua sendo token do tema matcha-core não gera border-color).
1362
- // -----------------------------------------------------------------------------------------------------
1363
- @mixin generate-border-named-classes($helper-breakpoints){
1364
- $border-named: (
1365
- hairline: var(--matcha-border-hairline, 1px),
1366
- thin: var(--matcha-border-thin, 2px),
1367
- medium: var(--matcha-border-medium, 4px),
1368
- thick: var(--matcha-border-thick, 8px),
1369
- );
1370
- $border-directions: (bottom: bb, top: bt, left: bl, right: br);
1371
-
1372
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1373
- @include media-breakpoint($materialBreakpoint) {
1374
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1375
-
1376
- @each $name, $width in $border-named {
1377
- .border#{$infix}-#{$name},
1378
- .b#{$infix}-#{$name} {
1379
- border: $width solid;
1380
- }
1381
- .border#{$infix}-#{$name}--force,
1382
- .b#{$infix}-#{$name}--force {
1383
- border: $width solid !important;
1384
- }
1385
-
1386
- @each $direction, $abbrev in $border-directions {
1387
- .border-#{$direction}#{$infix}-#{$name},
1388
- .#{$abbrev}#{$infix}-#{$name} {
1389
- border-#{$direction}: $width solid;
1390
- }
1391
- .border-#{$direction}#{$infix}-#{$name}--force,
1392
- .#{$abbrev}#{$infix}-#{$name}--force {
1393
- border-#{$direction}: $width solid !important;
1394
- }
1395
- }
1396
- }
1397
- }
1398
- }
1399
- }
1400
- @include generate-border-named-classes($helper-breakpoints);
1401
-
1402
- // -----------------------------------------------------------------------------------------------------
1403
- // @ Border Style
1404
- // -----------------------------------------------------------------------------------------------------
1405
- @mixin generate-border-style-classes($helper-breakpoints){
1406
- $border-styles: (
1407
- solid: solid,
1408
- dashed: dashed,
1409
- dotted: dotted,
1410
- double: double,
1411
- groove: groove,
1412
- ridge: ridge,
1413
- inset: inset,
1414
- outset: outset,
1415
- none: none
1416
- );
1417
-
1418
- $border-directions: (
1419
- bottom: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1420
- top: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1421
- left: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1422
- right: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none)
1423
- );
1424
-
1425
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1426
- @include media-breakpoint($materialBreakpoint) {
1427
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1428
-
1429
- // Classes para estilo de borda geral
1430
- @each $class, $value in $border-styles {
1431
- .border-style#{$infix}-#{$class} {
1432
- border-style: $value;
1433
- }
1434
- .border-style#{$infix}-#{$class}--force {
1435
- border-style: $value !important;
1436
- }
1437
- }
1438
- }
1439
- }
1440
- }
1441
- @include generate-border-style-classes($helper-breakpoints);
1442
-
1443
- // -----------------------------------------------------------------------------------------------------
1444
- // @ Border Radius Helpers
1445
- // -----------------------------------------------------------------------------------------------------
1446
- @mixin generate-radius-classes($helper-breakpoints){
1447
- $radius-directions: (bottom: b, top: t, left: l, right: r);
1448
-
1449
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1450
- @include media-breakpoint($materialBreakpoint) {
1451
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1452
-
1453
- @for $i from 0 through 12 {
1454
- $radius-value: $i * 2;
1455
- $radius-suffix: "-#{$radius-value}";
1456
- $r: ds-radius($radius-value);
1457
-
1458
- // Classes para borda geral
1459
- .radius#{$infix}#{$radius-suffix} {
1460
- border-radius: $r; // Sem !important
1461
- }
1462
-
1463
- // Classes para bordas individuais
1464
- @each $direction, $abbrev in $radius-directions {
1465
- @if $direction == bottom {
1466
- .radius-#{$direction}#{$infix}#{$radius-suffix} {
1467
- border-radius: 0 0 #{$r} #{$r}; // Sem !important
1468
- }
1469
-
1470
- .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1471
- border-radius: 0 0 #{$r} #{$r} !important; // Com !important
1472
- }
1473
- } @else if $direction == top {
1474
- .radius-#{$direction}#{$infix}#{$radius-suffix} {
1475
- border-radius: #{$r} #{$r} 0 0; // Sem !important
1476
- }
1477
-
1478
- .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1479
- border-radius: #{$r} #{$r} 0 0 !important; // Com !important
1480
- }
1481
- } @else if $direction == left {
1482
- .radius-#{$direction}#{$infix}#{$radius-suffix} {
1483
- border-radius: #{$r} 0 0 #{$r}; // Sem !important
1484
- }
1485
-
1486
- .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1487
- border-radius: #{$r} 0 0 #{$r} !important; // Com !important
1488
- }
1489
- } @else if $direction == right {
1490
- .radius-#{$direction}#{$infix}#{$radius-suffix} {
1491
- border-radius: 0 #{$r} #{$r} 0; // Sem !important
1492
- }
1493
-
1494
- .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1495
- border-radius: 0 #{$r} #{$r} 0 !important; // Com !important
1496
- }
1497
- }
1498
- }
1499
- }
1500
- .radius#{$infix}-full {
1501
- border-radius: 9999px;
1502
- }
1503
- .radius#{$infix}-full--force {
1504
- border-radius: 9999px !important;
1505
- }
1506
- .radius#{$infix}-none {
1507
- border-radius: 0;
1508
- }
1509
- .radius#{$infix}-none--force {
1510
- border-radius: 0 !important;
1511
- }
1512
- }
1513
- }
1514
- // Classe para borda nula
1515
- .border-none {
1516
- border: none !important;
1517
- }
1518
- }
1519
- @include generate-radius-classes($helper-breakpoints);
1520
-
1521
- // -----------------------------------------------------------------------------------------------------
1522
- // @ Shadow / Elevation (token-backed — Figma matcha/elevation/level-{1-4} → --matcha-shadow-*)
1523
- // Classe utilitária CANÔNICA de sombra. NÃO confundir com o legado .elevation-z-* (Material,
1524
- // deprecado, gerado no matcha-theme). Alternância light/dark vem do próprio token.
1525
- // Fallbacks (light) via unquote() a sombra é multi-camada (vírgulas) e não pode entrar
1526
- // crua num mapa Sass. Mantidos fiéis a matcha-theme/tokens/_elevation-tokens.scss.
1527
- // -----------------------------------------------------------------------------------------------------
1528
- @mixin generate-shadow-classes() {
1529
- $shadow-map: (
1530
- 1: unquote("var(--matcha-shadow-1, 0 8px 24px -8px rgba(45, 122, 47, 0.04), 0 2px 8px -1px rgba(26, 44, 30, 0.08), 0 1px 2px rgba(26, 44, 30, 0.04))"),
1531
- 2: unquote("var(--matcha-shadow-2, 0 12px 32px -10px rgba(45, 122, 47, 0.05), 0 4px 16px -2px rgba(26, 44, 30, 0.10), 0 2px 4px -1px rgba(26, 44, 30, 0.05))"),
1532
- 3: unquote("var(--matcha-shadow-3, 0 16px 40px -12px rgba(45, 122, 47, 0.06), 0 12px 32px -4px rgba(26, 44, 30, 0.14), 0 4px 8px -2px rgba(26, 44, 30, 0.08))"),
1533
- 4: unquote("var(--matcha-shadow-4, 0 24px 48px -16px rgba(45, 122, 47, 0.08), 0 24px 48px -8px rgba(26, 44, 30, 0.18), 0 8px 16px -4px rgba(26, 44, 30, 0.10))"),
1534
- );
1535
-
1536
- @each $level, $value in $shadow-map {
1537
- .shadow-#{$level} {
1538
- box-shadow: $value;
1539
- }
1540
- .shadow-#{$level}--force {
1541
- box-shadow: $value !important;
1542
- }
1543
- }
1544
-
1545
- .shadow-none {
1546
- box-shadow: none;
1547
- }
1548
- .shadow-none--force {
1549
- box-shadow: none !important;
1550
- }
1551
- }
1552
- @include generate-shadow-classes();
1553
-
1554
- // -----------------------------------------------------------------------------------------------------
1555
- // @ Hover - Show/Hide
1556
- // -----------------------------------------------------------------------------------------------------
1557
- @mixin generate-hover-show-hide-classes {
1558
- .on-hover-show:hover {
1559
- opacity: 1;
1560
- }
1561
- .on-hover-hide:hover {
1562
- opacity: 0;
1563
- }
1564
- }
1565
- @include generate-hover-show-hide-classes;
1566
-
1567
- // -----------------------------------------------------------------------------------------------------
1568
- // @ Transition
1569
- // -----------------------------------------------------------------------------------------------------
1570
- @mixin generate-transition-classes() {
1571
- $durations: (100, 300);
1572
- $easing: ('linear', 'ease-in', 'ease-out', 'ease-in-out');
1573
- @each $duration in $durations {
1574
- @each $ease in $easing {
1575
- $class-suffix: if($ease == 'linear', 'l', if($ease == 'ease-in', 'ei', if($ease == 'ease-out', 'eo', 'eio')));
1576
- .ts-#{$duration}-#{$class-suffix} {
1577
- transition: all #{$duration}ms #{$ease};
1578
- }
1579
- }
1580
- }
1581
- }
1582
- @include generate-transition-classes();
1583
-
1584
- // -----------------------------------------------------------------------------------------------------
1585
- // @ Motion — token-backed (Figma matcha/duration/*, matcha/easing/*)
1586
- // Complementa o legado .ts-* (100/300ms hardcoded, mantido). Estas ligam nos tokens do DS.
1587
- // .duration-* transition-duration · .ease-* transition-timing-function
1588
- // .transition-* → atalho composto (all + duração + easing standard)
1589
- // -----------------------------------------------------------------------------------------------------
1590
- @mixin generate-motion-classes() {
1591
- $duration-map: (
1592
- instant: var(--matcha-duration-instant, 80ms),
1593
- fast: var(--matcha-duration-fast, 200ms),
1594
- normal: var(--matcha-duration-normal, 400ms),
1595
- slow: var(--matcha-duration-slow, 600ms),
1596
- );
1597
- $easing-map: (
1598
- standard: unquote("var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1))"),
1599
- emphasized: unquote("var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1))"),
1600
- decelerated: unquote("var(--matcha-easing-decelerated, cubic-bezier(0, 0, 0.2, 1))"),
1601
- accelerated: unquote("var(--matcha-easing-accelerated, cubic-bezier(0.4, 0, 1, 1))"),
1602
- );
1603
- $standard-ease: unquote("var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1))");
1604
-
1605
- @each $name, $value in $duration-map {
1606
- .duration-#{$name} {
1607
- transition-duration: $value;
1608
- }
1609
- .duration-#{$name}--force {
1610
- transition-duration: $value !important;
1611
- }
1612
- }
1613
-
1614
- @each $name, $value in $easing-map {
1615
- .ease-#{$name} {
1616
- transition-timing-function: $value;
1617
- }
1618
- .ease-#{$name}--force {
1619
- transition-timing-function: $value !important;
1620
- }
1621
- }
1622
-
1623
- @each $name, $value in $duration-map {
1624
- .transition-#{$name} {
1625
- transition: all $value $standard-ease;
1626
- }
1627
- .transition-#{$name}--force {
1628
- transition: all $value $standard-ease !important;
1629
- }
1630
- }
1631
- }
1632
- @include generate-motion-classes();
1633
-
1634
- // -----------------------------------------------------------------------------------------------------
1635
- // @ Rotate Animation
1636
- // -----------------------------------------------------------------------------------------------------
1637
- @mixin generate-rotate-animation-classes() {
1638
- // Define as durações desejadas para a animação de rotação
1639
- $durations: (1, 2, 3);
1640
- @each $duration in $durations {
1641
- .rotate-infinity-#{$duration}s {
1642
- animation: spin #{$duration}s infinite;
1643
- }
1644
- }
1645
- }
1646
- // Define a keyframes para a animação de rotação
1647
- @keyframes spin {
1648
- 0% {
1649
- transform: rotate(0deg);
1650
- }
1651
-
1652
- 100% {
1653
- transform: rotate(360deg);
1654
- }
1655
- }
1656
- @include generate-rotate-animation-classes();
1657
-
1658
- // -----------------------------------------------------------------------------------------------------
1659
- // @ Border Size Helpers
1660
- // -----------------------------------------------------------------------------------------------------
1661
- @mixin generate-line-clamp-classes($helper-breakpoints){
1662
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1663
- @include media-breakpoint($materialBreakpoint) {
1664
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1665
- @for $i from 0 through 6 {
1666
- // Classes para borda geral
1667
- .line-clamp#{$infix}-#{$i}{
1668
- overflow: hidden;
1669
- display: -webkit-box;
1670
- -webkit-box-orient: vertical;
1671
- -webkit-line-clamp: $i;
1672
- line-clamp: $i;
1673
- text-overflow: ellipsis;
1674
- word-break: break-word;
1675
- white-space: initial;
1676
- -webkit-box-orient: vertical;
1677
- }
1678
- }
1679
- .line-clamp#{$infix}-none{
1680
- overflow: visible;
1681
- display: block;
1682
- -webkit-box-orient: horizontal;
1683
- -webkit-line-clamp: none;
1684
- line-clamp: none;
1685
- }
1686
- }
1687
- }
1688
- }
1689
- @include generate-line-clamp-classes($helper-breakpoints);
1690
-
1691
- // -----------------------------------------------------------------------------------------------------
1692
- // @ Masonry
1693
- // -----------------------------------------------------------------------------------------------------
1694
- @mixin generate-masonry-classes($helper-breakpoints){
1695
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1696
- @include media-breakpoint($materialBreakpoint) {
1697
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1698
- @for $i from 1 through 12 {
1699
- // Classes para borda geral
1700
- .masonry#{$infix}-#{$i}{
1701
- column-count: $i;
1702
- > *{
1703
- break-inside: avoid;
1704
- display: inline-block;
1705
- width: 100%;
1706
- }
1707
- }
1708
- }
1709
- @for $i from 0 through 12 {
1710
- $size: $i * 4;
1711
- // Classes para borda geral
1712
- .masonry-gap#{$infix}-#{$size}{
1713
- column-gap: #{$size}px;
1714
- > *{
1715
- margin-bottom: #{$size}px;
1716
- }
1717
- }
1718
- }
1719
- }
1720
- }
1721
- }
1722
- @include generate-masonry-classes($helper-breakpoints);
1723
-
1724
-
1725
-
1
+ @use "sass:map";
2
+ @use "sass:list";
3
+ @use "sass:math";
4
+ @use "sass:string";
5
+
6
+ // -------------------------------------------------------------------------------------------------------------------
7
+ // @ Breakpoints generator
8
+ //
9
+ // Examples:
10
+ // @include media-breakpoint("xs") {
11
+ // Show styles in small devices ( Phones and Gadget, 0px and up < 600px )
12
+ // }
13
+ // @include media-breakpoint("gt-xs") {
14
+ // Show styles in medium devices (landscapes and tablets, 600px and up < 1024px )
15
+ // }
16
+ // @include media-breakpoint("gt-sm") {
17
+ // Show styles in large devices (tablets and small monitors, 1024px and up < 1440px)
18
+ // }
19
+ // @include media-breakpoint("gt-md") {
20
+ // Show styles in X-Large devices (big desktops, 1440px and up < 1920)
21
+ // }
22
+ // @include media-breakpoint("gt-lg") {
23
+ // Show styles in XX-Large devices (larger desktops, 1920px and up)
24
+ // }
25
+ // -------------------------------------------------------------------------------------------------------------------
26
+
27
+ // Media step breakpoint mixin based on Angular Material lib
28
+ $breakpoints: (
29
+ xs: 'screen and (max-width: 639px)',
30
+ sm: 'screen and (min-width: 640px) and (max-width: 1023px)',
31
+ md: 'screen and (min-width: 1024px) and (max-width: 1279px)',
32
+ lg: 'screen and (min-width: 1280px) and (max-width: 1535px)',
33
+ xl: 'screen and (min-width: 1536px) and (max-width: 5000px)',
34
+ lt-sm: 'screen and (max-width: 639px)',
35
+ lt-md: 'screen and (max-width: 1023px)',
36
+ lt-lg: 'screen and (max-width: 1279px)',
37
+ lt-xl: 'screen and (max-width: 1535px)',
38
+ gt-xs: 'screen and (min-width: 640px)',
39
+ gt-sm: 'screen and (min-width: 1024px)',
40
+ gt-md: 'screen and (min-width: 1280px)',
41
+ gt-lg: 'screen and (min-width: 1536px)'
42
+ ) !default;
43
+
44
+ // Re-map the breakpoints for the helper classes
45
+ $helper-breakpoints: (
46
+ initial: null,
47
+ xs: 'xs',
48
+ sm: 'gt-xs',
49
+ md: 'gt-sm',
50
+ lg: 'gt-md',
51
+ xl: 'gt-lg'
52
+ );
53
+
54
+ @mixin media-breakpoint($breakpointName) {
55
+ $mediaQuery: map.get($breakpoints, $breakpointName);
56
+ @if ($mediaQuery == null) {
57
+ @content;
58
+ } @else {
59
+ @media #{$mediaQuery} {
60
+ @content;
61
+ }
62
+ }
63
+ }
64
+
65
+ // Define the variable for the base size (usually 16 pixels = 1 rem).
66
+ $base-font-size: 16px;
67
+
68
+ // Function to convert pixels to rem.
69
+ @function px-to-rem($value-in-px) {
70
+ @if $value-in-px != 0 {
71
+ @return calc($value-in-px / $base-font-size) * 1rem;
72
+ } @else {
73
+ @return $value-in-px;
74
+ }
75
+ }
76
+
77
+ // =====================================================================================================
78
+ // DS Token maps connect legacy utility classes to Design System CSS custom properties.
79
+ // When a utility class (.px-16, .gap-8) resolves to a value with a corresponding DS token,
80
+ // we emit var(--matcha-*) so Figma changes propagate. Values without direct tokens fall back to px.
81
+ // =====================================================================================================
82
+ $space-token-map: (
83
+ 0: var(--matcha-space-0, 0),
84
+ 2: var(--matcha-space-025, 2px),
85
+ 4: var(--matcha-space-050, 4px),
86
+ 6: var(--matcha-space-075, 6px),
87
+ 8: var(--matcha-space-100, 8px),
88
+ 12: var(--matcha-space-150, 12px),
89
+ 16: var(--matcha-space-200, 16px),
90
+ 20: var(--matcha-space-250, 20px),
91
+ 24: var(--matcha-space-300, 24px),
92
+ 32: var(--matcha-space-400, 32px),
93
+ 40: var(--matcha-space-500, 40px),
94
+ 48: var(--matcha-space-600, 48px),
95
+ 64: var(--matcha-space-800, 64px),
96
+ 80: var(--matcha-space-1000, 80px),
97
+ 96: var(--matcha-space-1200, 96px),
98
+ );
99
+
100
+ $radius-token-map: (
101
+ 0: var(--matcha-radius-none, 0),
102
+ 2: var(--matcha-radius-sm, 2px),
103
+ 4: var(--matcha-radius-md, 4px),
104
+ 8: var(--matcha-radius-lg, 8px),
105
+ 16: var(--matcha-radius-xl, 16px),
106
+ 24: var(--matcha-radius-2xl, 24px),
107
+ 9999: var(--matcha-radius-pill, 9999px),
108
+ );
109
+
110
+ $font-size-token-map: (
111
+ 10: var(--matcha-font-size-2xs, 10px),
112
+ 12: var(--matcha-font-size-xs, 12px),
113
+ 14: var(--matcha-font-size-sm, 14px),
114
+ 16: var(--matcha-font-size-md, 16px),
115
+ 18: var(--matcha-font-size-lg, 18px),
116
+ 20: var(--matcha-font-size-xl, 20px),
117
+ 24: var(--matcha-font-size-2xl, 24px),
118
+ 32: var(--matcha-font-size-3xl, 32px),
119
+ );
120
+
121
+ $font-weight-token-map: (
122
+ 400: var(--matcha-weight-regular, 400),
123
+ 500: var(--matcha-weight-medium, 500),
124
+ 600: var(--matcha-weight-semibold, 600),
125
+ 700: var(--matcha-weight-bold, 700),
126
+ 800: 800, // Figma não tem weight/extrabold; literal 800
127
+ 900: var(--matcha-weight-black, 900),
128
+ );
129
+
130
+ @function ds-space($size) {
131
+ $abs-size: if($size < 0, -$size, $size);
132
+ $token: map.get($space-token-map, $abs-size);
133
+ @if $token != null {
134
+ @if $size < 0 {
135
+ @return calc(-1 * #{$token});
136
+ }
137
+ @return $token;
138
+ }
139
+ @return #{$size}px;
140
+ }
141
+
142
+ @function ds-radius($size) {
143
+ $token: map.get($radius-token-map, $size);
144
+ @if $token != null {
145
+ @return $token;
146
+ }
147
+ @return #{$size}px;
148
+ }
149
+
150
+ @function ds-font-size($size) {
151
+ $token: map.get($font-size-token-map, $size);
152
+ @if $token != null {
153
+ @return $token;
154
+ }
155
+ @return #{$size}px;
156
+ }
157
+
158
+ @function ds-font-weight($weight) {
159
+ $token: map.get($font-weight-token-map, $weight);
160
+ @if $token != null {
161
+ @return $token;
162
+ }
163
+ @return $weight;
164
+ }
165
+
166
+ // -----------------------------------------------------------------------------------------------------
167
+ // @ Size classes | Width and Height
168
+ // -----------------------------------------------------------------------------------------------------
169
+ @mixin _size-classes($prop, $abbrev, $length, $size, $infix: "") {
170
+ .#{$abbrev}#{$infix}-#{$size} {
171
+ #{$prop}: $length;
172
+ }
173
+
174
+ .#{$abbrev}#{$infix}-#{$size}--force {
175
+ #{$prop}: $length !important;
176
+ }
177
+
178
+ .max-#{$abbrev}#{$infix}-#{$size} {
179
+ max-#{$prop}: $length;
180
+ }
181
+
182
+ .max-#{$abbrev}#{$infix}-#{$size}--force {
183
+ max-#{$prop}: $length !important;
184
+ }
185
+
186
+ .min-#{$abbrev}#{$infix}-#{$size} {
187
+ min-#{$prop}: $length;
188
+ }
189
+
190
+ .min-#{$abbrev}#{$infix}-#{$size}--force {
191
+ min-#{$prop}: $length !important;
192
+ }
193
+ }
194
+ @mixin generate-size-classes($helper-breakpoints) {
195
+ @each $breakpoint, $media-size in $helper-breakpoints {
196
+ @include media-breakpoint($media-size) {
197
+ $infix: if($media-size == null, "", "-#{$breakpoint}");
198
+
199
+ @each $prop, $abbrev in (height: h, width: w) {
200
+ // Pixels
201
+ @for $index from 0 through 64 {
202
+ $size: $index * 4;
203
+ $length: #{$size}px;
204
+
205
+ @include _size-classes($prop, $abbrev, $length, $size, $infix);
206
+ }
207
+
208
+ // Percentages
209
+ @for $i from 0 through 20 {
210
+ $i-p: 5 * $i;
211
+ $size-p: 5% * $i;
212
+
213
+ @include _size-classes($prop, $abbrev, $size-p, "#{$i-p}-p", $infix);
214
+ }
215
+
216
+ // Big sizes
217
+ @for $i from 3 through 20 {
218
+ $size: $i * 100;
219
+ $length: #{$size}px;
220
+
221
+ @include _size-classes($prop, $abbrev, $length, $size, $infix);
222
+ }
223
+
224
+ // Auto
225
+ .#{$abbrev}#{$infix}-auto {
226
+ #{$prop}: auto;
227
+ }
228
+
229
+ .#{$abbrev}#{$infix}-auto--force {
230
+ #{$prop}: auto !important;
231
+ }
232
+ }
233
+ }
234
+ }
235
+ }
236
+ @include generate-size-classes($helper-breakpoints);
237
+
238
+ // -----------------------------------------------------------------------------------------------------
239
+ // @ Spacing classes - Margin and Padding
240
+ // Generate spacing values from -64 to 64 jumping from 4 to 4
241
+ // -----------------------------------------------------------------------------------------------------
242
+ @mixin _spacing-classes($prop, $abbrev, $length, $size, $infix: "") {
243
+ .#{$abbrev}#{$infix}-#{$size} {
244
+ #{$prop}: $length;
245
+ }
246
+
247
+ .#{$abbrev}#{$infix}-#{$size}--force {
248
+ #{$prop}: $length !important;
249
+ }
250
+
251
+ .#{$abbrev}x#{$infix}-#{$size} {
252
+ #{$prop}-right: $length;
253
+ #{$prop}-left: $length;
254
+ }
255
+
256
+ .#{$abbrev}x#{$infix}-#{$size}--force {
257
+ #{$prop}-right: $length !important;
258
+ #{$prop}-left: $length !important;
259
+ }
260
+
261
+ .#{$abbrev}y#{$infix}-#{$size} {
262
+ #{$prop}-top: $length;
263
+ #{$prop}-bottom: $length;
264
+ }
265
+
266
+ .#{$abbrev}y#{$infix}-#{$size}--force {
267
+ #{$prop}-top: $length !important;
268
+ #{$prop}-bottom: $length !important;
269
+ }
270
+
271
+ .#{$abbrev}t#{$infix}-#{$size} {
272
+ #{$prop}-top: $length;
273
+ }
274
+
275
+ .#{$abbrev}t#{$infix}-#{$size}--force {
276
+ #{$prop}-top: $length !important;
277
+ }
278
+
279
+ .#{$abbrev}r#{$infix}-#{$size} {
280
+ #{$prop}-right: $length;
281
+ }
282
+
283
+ .#{$abbrev}r#{$infix}-#{$size}--force {
284
+ #{$prop}-right: $length !important;
285
+ }
286
+
287
+ .#{$abbrev}b#{$infix}-#{$size} {
288
+ #{$prop}-bottom: $length;
289
+ }
290
+
291
+ .#{$abbrev}b#{$infix}-#{$size}--force {
292
+ #{$prop}-bottom: $length !important;
293
+ }
294
+
295
+ .#{$abbrev}l#{$infix}-#{$size} {
296
+ #{$prop}-left: $length;
297
+ }
298
+
299
+ .#{$abbrev}l#{$infix}-#{$size}--force {
300
+ #{$prop}-left: $length !important;
301
+ }
302
+ }
303
+ @mixin generate-spacing-classes($helper-breakpoints) {
304
+ @each $breakpoint, $media-size in $helper-breakpoints {
305
+ @include media-breakpoint($media-size) {
306
+ $infix: if($media-size == null, "", "-#{$breakpoint}");
307
+
308
+ @each $prop, $abbrev in (margin: m, padding: p) {
309
+ // For margins, include negative values
310
+ @for $index from -16 through 16 {
311
+ $size: $index * 4;
312
+ $length: ds-space($size); // uses --matcha-space-* tokens when available
313
+
314
+ @include _spacing-classes($prop, $abbrev, $length, $size, $infix);
315
+ }
316
+
317
+ // For paddings, only positive values
318
+ @if ($prop == padding) {
319
+ @for $index from 0 through 24 {
320
+ $size: $index * 4;
321
+ $length: ds-space($size); // uses --matcha-space-* tokens when available
322
+
323
+ @include _spacing-classes($prop, $abbrev, $length, $size, $infix);
324
+ }
325
+ }
326
+
327
+ // Special auto classes for margin
328
+ @if ($prop == margin) {
329
+ .m#{$infix}-auto {
330
+ margin: auto;
331
+ }
332
+
333
+ .m#{$infix}-auto--force {
334
+ margin: auto !important;
335
+ }
336
+
337
+ .mt#{$infix}-auto {
338
+ margin-top: auto;
339
+ }
340
+
341
+ .mt#{$infix}-auto--force {
342
+ margin-top: auto !important;
343
+ }
344
+
345
+ .mr#{$infix}-auto {
346
+ margin-right: auto;
347
+ }
348
+
349
+ .mr#{$infix}-auto--force {
350
+ margin-right: auto !important;
351
+ }
352
+
353
+ .mb#{$infix}-auto {
354
+ margin-bottom: auto;
355
+ }
356
+
357
+ .mb#{$infix}-auto--force {
358
+ margin-bottom: auto !important;
359
+ }
360
+
361
+ .ml#{$infix}-auto {
362
+ margin-left: auto;
363
+ }
364
+
365
+ .ml#{$infix}-auto--force {
366
+ margin-left: auto !important;
367
+ }
368
+
369
+ .mx#{$infix}-auto {
370
+ margin-right: auto;
371
+ margin-left: auto;
372
+ }
373
+
374
+ .mx#{$infix}-auto--force {
375
+ margin-right: auto !important;
376
+ margin-left: auto !important;
377
+ }
378
+
379
+ .my#{$infix}-auto {
380
+ margin-top: auto;
381
+ margin-bottom: auto;
382
+ }
383
+
384
+ .my#{$infix}-auto--force {
385
+ margin-top: auto !important;
386
+ margin-bottom: auto !important;
387
+ }
388
+ }
389
+ }
390
+ }
391
+ }
392
+ }
393
+ @include generate-spacing-classes($helper-breakpoints);
394
+
395
+ // -------------------------------------------------------------------------------------------------------------------
396
+ // @ Display classes | Flex and Grid
397
+ // -------------------------------------------------------------------------------------------------------------------
398
+ @mixin _grid-prop($i) {
399
+ display: grid;
400
+ grid-template-columns: repeat($i, minmax(0, 1fr));
401
+ }
402
+ @mixin generate-layout-grid($helper-breakpoints) {
403
+ $grid-length: 12;
404
+ $grid-prefix: "col";
405
+
406
+ [class^="grid-"] {
407
+ display: grid;
408
+ grid-template-columns: minmax(0, 1fr);
409
+ }
410
+
411
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
412
+ @include media-breakpoint($materialBreakpoint) {
413
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
414
+
415
+ @for $i from 1 through $grid-length {
416
+ .grid#{$infix}-#{$i} {
417
+ @include _grid-prop($i);
418
+ }
419
+
420
+ .span#{$infix}-#{$i}c,
421
+ .colspan#{$infix}-#{$i} {
422
+ grid-column-end: span #{$i};
423
+ }
424
+
425
+ .span#{$infix}-#{$i}r,
426
+ .rowspan#{$infix}-#{$i} {
427
+ grid-row-end: span #{$i};
428
+ }
429
+ }
430
+ }
431
+ }
432
+ }
433
+ @mixin generate-layout-flex($helper-breakpoints) {
434
+ $grid-length: 12;
435
+ $grid-prefix: "col";
436
+ .row {
437
+ display: flex;
438
+ flex-wrap: wrap;
439
+
440
+ > div[class*="#{$grid-prefix}-"] {
441
+ box-sizing: border-box;
442
+ }
443
+
444
+ > div:not([class*="#{$grid-prefix}-"]) {
445
+ flex: 1;
446
+ }
447
+
448
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
449
+ @include media-breakpoint($materialBreakpoint) {
450
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
451
+
452
+ @for $i from 1 through $grid-length {
453
+ .#{$grid-prefix}#{$infix}-#{$i} {
454
+ flex-basis: math.percentage(math.div($i, $grid-length));
455
+ }
456
+
457
+ .#{$grid-prefix}-offset#{$infix}-#{$i} {
458
+ margin-left: math.percentage(math.div($i, $grid-length));
459
+ }
460
+ }
461
+ @each $classLabel, $cssValue in (align-start flex-start, align-center center, align-end flex-end) {
462
+ > div[class*="#{$grid-prefix}-"].#{$classLabel} {
463
+ align-self: $cssValue;
464
+ }
465
+ }
466
+
467
+ @each $classLabel, $cssValue in (align-start flex-start, align-center center, align-end flex-end, space-around space-around, space-between space-between) {
468
+ &.#{$classLabel} {
469
+ justify-content: $cssValue;
470
+ }
471
+ }
472
+ }
473
+ }
474
+ }
475
+ }
476
+ @include generate-layout-grid($helper-breakpoints);
477
+ @include generate-layout-flex($helper-breakpoints);
478
+
479
+ // -------------------------------------------------------------------------------------------------------------------
480
+ // @Gaps classes
481
+ // -------------------------------------------------------------------------------------------------------------------
482
+ @mixin generate-gap-classes($helper-breakpoints) {
483
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
484
+ @include media-breakpoint($materialBreakpoint) {
485
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
486
+
487
+ @for $i from 0 through 12 {
488
+ $size: $i * 4;
489
+ $gap-value: ds-space($size);
490
+ .gap#{$infix}-#{$size} {
491
+ column-gap: $gap-value;
492
+ row-gap: $gap-value;
493
+ }
494
+ }
495
+ }
496
+ }
497
+ // Dynamic gaps
498
+ .gap-inside {
499
+ -moz-column-gap: var(--matcha-space-200, 16px);
500
+ column-gap: var(--matcha-space-200, 16px);
501
+ row-gap: var(--matcha-space-200, 16px);
502
+ }
503
+ .gap-outside {
504
+ -moz-column-gap: var(--matcha-space-200, 16px);
505
+ column-gap: var(--matcha-space-200, 16px);
506
+ row-gap: var(--matcha-space-200, 16px);
507
+ }
508
+ @media screen and (min-width: 640px) {
509
+ .gap-outside {
510
+ -moz-column-gap: var(--matcha-space-300, 24px);
511
+ column-gap: var(--matcha-space-300, 24px);
512
+ row-gap: var(--matcha-space-300, 24px);
513
+ }
514
+ }
515
+ }
516
+ @include generate-gap-classes($helper-breakpoints);
517
+
518
+ // Gap de 2px — o gerador acima salta de 4 em 4 (0/4/8…); 2px = --matcha-space-025 (token DSV3).
519
+ .gap-2 {
520
+ column-gap: var(--matcha-space-025, 2px);
521
+ row-gap: var(--matcha-space-025, 2px);
522
+ }
523
+
524
+ // -----------------------------------------------------------------------------------------------------
525
+ // @ Z-index classes
526
+ // -----------------------------------------------------------------------------------------------------
527
+ @mixin generate-z-index-classes($helper-breakpoints) {
528
+ @each $breakpoint, $breakpointName in $helper-breakpoints {
529
+ @include media-breakpoint($breakpointName) {
530
+ $infix: if($breakpointName == null, "", "-#{$breakpoint}");
531
+
532
+ @for $i from -1 through 24 {
533
+ .z-index#{$infix}-#{$i} {
534
+ z-index: #{$i};
535
+ }
536
+
537
+ .z-index#{$infix}-#{$i}--force {
538
+ z-index: #{$i} !important;
539
+ }
540
+ }
541
+ }
542
+ }
543
+ }
544
+ @include generate-z-index-classes($helper-breakpoints);
545
+
546
+ // -----------------------------------------------------------------------------------------------------
547
+ // @ Order classes
548
+ // -----------------------------------------------------------------------------------------------------
549
+ @mixin generate-order-classes($helper-breakpoints) {
550
+ @each $breakpoint, $breakpointName in $helper-breakpoints {
551
+ @include media-breakpoint($breakpointName) {
552
+ $infix: if($breakpointName == null, "", "-#{$breakpoint}");
553
+
554
+ /* <integer> values */
555
+ @for $i from -12 through 12 {
556
+ .order#{$infix}-#{$i} {
557
+ order: #{$i};
558
+ }
559
+
560
+ .order#{$infix}-#{$i}--force {
561
+ order: #{$i} !important;
562
+ }
563
+ }
564
+
565
+ /* Global values */
566
+ @each $value in (inherit, initial) {
567
+ .order#{$infix}-#{$value} {
568
+ order: #{$value};
569
+ }
570
+
571
+ .order#{$infix}-#{$value}--force {
572
+ order: #{$value} !important;
573
+ }
574
+ }
575
+ }
576
+ }
577
+ }
578
+ @include generate-order-classes($helper-breakpoints);
579
+
580
+ // -----------------------------------------------------------------------------------------------------
581
+ // @ Absolute position alignment classes
582
+ // -----------------------------------------------------------------------------------------------------
583
+ @mixin generate-position-classes($helper-breakpoints) {
584
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
585
+ @include media-breakpoint($materialBreakpoint) {
586
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
587
+
588
+ @each $position in (top, right, bottom, left) {
589
+ .place#{$infix}-#{$position} {
590
+ #{$position}: 0;
591
+ }
592
+
593
+ .place#{$infix}-#{$position}--force {
594
+ #{$position}: 0 !important;
595
+ }
596
+ }
597
+ }
598
+ }
599
+ }
600
+ @include generate-position-classes($helper-breakpoints);
601
+
602
+ // -----------------------------------------------------------------------------------------------------
603
+ // @ Position classes
604
+ // -----------------------------------------------------------------------------------------------------
605
+ @mixin generate-position-classes($helper-breakpoints) {
606
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
607
+ @include media-breakpoint($materialBreakpoint) {
608
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
609
+
610
+ @each $pos in (relative, absolute, static, fixed, sticky) {
611
+ .position#{$infix}-#{$pos} {
612
+ position: #{$pos};
613
+ }
614
+
615
+ .position#{$infix}-#{$pos}--force {
616
+ position: #{$pos} !important;
617
+ }
618
+ }
619
+ }
620
+ }
621
+ }
622
+ @include generate-position-classes($helper-breakpoints);
623
+
624
+ // -----------------------------------------------------------------------------------------------------
625
+ // @ Display classes
626
+ // -----------------------------------------------------------------------------------------------------
627
+ @mixin generate-display-classes($helper-breakpoints) {
628
+ @each $breakpoint, $media-size in $helper-breakpoints {
629
+ @include media-breakpoint($media-size) {
630
+ $infix: if($media-size == null, "", "-#{$breakpoint}");
631
+
632
+ @each $class-suffix, $value in (
633
+ none: none,
634
+ inline: inline,
635
+ inline-block: inline-block,
636
+ block: block,
637
+ grid: grid,
638
+ table: table,
639
+ table-cell: table-cell,
640
+ table-row: table-row,
641
+ inline-flex: inline-flex,
642
+ flex: flex
643
+ ) {
644
+ .d#{$infix}-#{$class-suffix} {
645
+ display: $value;
646
+ }
647
+
648
+ .d#{$infix}-#{$class-suffix}--force {
649
+ display: $value !important;
650
+ }
651
+ }
652
+ }
653
+ }
654
+ }
655
+ @include generate-display-classes($helper-breakpoints);
656
+
657
+ // -----------------------------------------------------------------------------------------------------
658
+ // @ Flex classes
659
+ // -----------------------------------------------------------------------------------------------------
660
+ @mixin generate-flex-classes($helper-breakpoints) {
661
+ @each $breakpoint, $media-size in $helper-breakpoints {
662
+ @include media-breakpoint($media-size) {
663
+ $infix: if($media-size == null, "", "-#{$breakpoint}");
664
+
665
+ @each $class-suffix, $value in (
666
+ row: (display:flex, flex-direction: row),
667
+ row-reverse: (display:flex, flex-direction: row-reverse),
668
+ column: (display:flex, flex-direction: column),
669
+ column-reverse: (display:flex, flex-direction: column-reverse),
670
+
671
+ nowrap: (flex-wrap: nowrap),
672
+ wrap: (flex-wrap: wrap),
673
+
674
+ align-center: (display:flex, align-items: center),
675
+ align-start: (display:flex, align-items: flex-start),
676
+ align-end: (display:flex, align-items: flex-end),
677
+ align-inherit: (display:flex, align-items: inherit),
678
+ align-initial: (display:flex, align-items: initial),
679
+
680
+ align-self-end: (display:flex, align-self: flex-end),
681
+ align-self-start: (display:flex, align-self: flex-start),
682
+ align-self-inherit: (display:flex, align-self: inherit),
683
+ align-self-initial: (display:flex, align-self: initial),
684
+
685
+ center-center: (display:flex, justify-content: center, align-items: center),
686
+
687
+ justify-center: (display:flex, justify-content: center),
688
+ center: (display:flex, justify-content: center),
689
+
690
+ justify-end: (display:flex, justify-content: flex-end),
691
+ end: (display:flex, justify-content: flex-end),
692
+
693
+ justify-start: (display:flex, justify-content: flex-start),
694
+ start: (display:flex, justify-content: flex-start),
695
+
696
+ justify-inherit: (display:flex, justify-content: inherit),
697
+ inherit: (display:flex, justify-content: inherit),
698
+
699
+ justify-initial: (display:flex, justify-content: initial),
700
+ initial: (display:flex, justify-content: initial),
701
+
702
+ left: (display:flex, justify-content: left),
703
+ right: (display:flex, justify-content: right),
704
+ normal: (display:flex, justify-content: normal),
705
+ revert: (display:flex, justify-content: revert),
706
+
707
+ space-around: (display:flex, justify-content: space-around),
708
+ around: (display:flex, justify-content: space-around),
709
+
710
+ space-between: (display:flex, justify-content: space-between),
711
+ between: (display:flex, justify-content: space-between),
712
+
713
+ space-evenly: (display:flex, justify-content: space-evenly),
714
+ evenly: (display:flex, justify-content: space-evenly),
715
+
716
+ stretch: (display:flex, justify-content: stretch),
717
+ unset: (display:flex, justify-content: unset)
718
+
719
+ ) {
720
+ $class-name: ".flex#{$infix}-#{$class-suffix}";
721
+ $class-name-force: ".flex#{$infix}-#{$class-suffix}--force";
722
+
723
+ #{$class-name} {
724
+ @each $property, $prop-value in $value {
725
+ #{$property}: #{$prop-value};
726
+ }
727
+ }
728
+
729
+ #{$class-name-force} {
730
+ @each $property, $prop-value in $value {
731
+ #{$property}: #{$prop-value} !important;
732
+ }
733
+ }
734
+ }
735
+ // For margins, include negative values
736
+ @for $index from 0 through 3 {
737
+ .flex#{$infix}-grow-#{$index} {
738
+ flex-grow: $index;
739
+ }
740
+ .flex#{$infix}-shrink-#{$index} {
741
+ flex-shrink: $index;
742
+ }
743
+ }
744
+ .flex#{$infix}-full {
745
+ flex-grow: 1;
746
+ flex-shrink: 1;
747
+ flex-basis: 100%;
748
+ ;
749
+ }
750
+ .flex#{$infix}-basis-1 {
751
+ flex-basis: 100%;
752
+ }
753
+ }
754
+ }
755
+ }
756
+ @include generate-flex-classes($helper-breakpoints);
757
+
758
+ // -----------------------------------------------------------------------------------------------------
759
+ // @ Font Weight classes
760
+ // -----------------------------------------------------------------------------------------------------
761
+ @mixin generate-font-weight-classes($helper-breakpoints) {
762
+ @each $breakpoint, $media-size in $helper-breakpoints {
763
+ @include media-breakpoint($media-size) {
764
+ $infix: if($media-size == null, "", "-#{$breakpoint}");
765
+
766
+ @for $index from 1 through 9 {
767
+ $weight: $index * 100;
768
+ $weight-value: ds-font-weight($weight);
769
+
770
+ .fw#{$infix}-#{$weight} {
771
+ font-weight: $weight-value;
772
+ }
773
+
774
+ .fw#{$infix}-#{$weight}--force {
775
+ font-weight: $weight-value !important;
776
+ }
777
+ }
778
+ }
779
+ }
780
+ }
781
+ @include generate-font-weight-classes($helper-breakpoints);
782
+
783
+ // -----------------------------------------------------------------------------------------------------
784
+ // @ Font Size classes
785
+ // -----------------------------------------------------------------------------------------------------
786
+ @mixin generate-font-size-classes($helper-breakpoints) {
787
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
788
+ @include media-breakpoint($materialBreakpoint) {
789
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
790
+ $index: 0;
791
+ @while $index <= 96 {
792
+ $size: $index;
793
+ $fs-value: ds-font-size($size);
794
+ .fs#{$infix}-#{$size} {
795
+ font-size: $fs-value;
796
+ }
797
+ .fs#{$infix}-#{$size}--force {
798
+ font-size: $fs-value !important;
799
+ }
800
+ $index: $index + 1;
801
+ }
802
+ }
803
+ }
804
+ }
805
+ @include generate-font-size-classes($helper-breakpoints);
806
+
807
+ // -----------------------------------------------------------------------------------------------------
808
+ // @ Letter Spacing classes
809
+ // -----------------------------------------------------------------------------------------------------
810
+ @mixin generate-letter-spacing-classes($helper-breakpoints) {
811
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
812
+ @include media-breakpoint($materialBreakpoint) {
813
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
814
+ $index: 0;
815
+ @while $index <= 18 {
816
+ $spacing: $index * 0.1;
817
+ .ls#{$infix}-#{$index} {
818
+ letter-spacing: #{$spacing}em;
819
+ }
820
+ .ls#{$infix}-#{$index}--force {
821
+ letter-spacing: #{$spacing}em !important;
822
+ }
823
+ $index: $index + 1;
824
+ }
825
+
826
+ }
827
+ }
828
+ }
829
+ @include generate-letter-spacing-classes($helper-breakpoints);
830
+
831
+ // -----------------------------------------------------------------------------------------------------
832
+ // @ Line Height classes
833
+ // -----------------------------------------------------------------------------------------------------
834
+ @mixin generate-line-height-classes($helper-breakpoints) {
835
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
836
+ @include media-breakpoint($materialBreakpoint) {
837
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
838
+
839
+ $index: 0;
840
+ @while $index <= 100 {
841
+ $height: $index * 1;
842
+
843
+ .lh#{$infix}-#{$height} {
844
+ line-height: #{$height}px;
845
+ }
846
+
847
+ .lh#{$infix}-#{$height}--force {
848
+ line-height: #{$height}px !important;
849
+ }
850
+
851
+ $index: $index + 1;
852
+ }
853
+ }
854
+ }
855
+ }
856
+ @include generate-line-height-classes($helper-breakpoints);
857
+
858
+ // -----------------------------------------------------------------------------------------------------
859
+ // @ Text Styles (composite — Figma matcha/text/*) size + weight + line-height (+ letter-spacing/transform)
860
+ // Uma classe aplica o text style INTEIRO, token-backed. Nomes seguem --matcha-text-* (canônico DS).
861
+ // Não colide com os utilitários text-* single-prop (center/uppercase/truncate/...): sufixos distintos.
862
+ // Pareamento size/weight/leading/tracking espelha matcha-theme/tokens/_emit-tokens.scss:103-148
863
+ // (weight por estilo não é tokenizado → mapeia pro --matcha-weight-* correspondente).
864
+ // -----------------------------------------------------------------------------------------------------
865
+ @mixin generate-text-style-classes($helper-breakpoints) {
866
+ // name: (size, weight, line-height, letter-spacing-or-null, text-transform-or-null)
867
+ $text-styles: (
868
+ display-hero: (var(--matcha-text-display-hero, 36px), var(--matcha-weight-extrabold, 800), var(--matcha-leading-display-hero, 40px), var(--matcha-tracking-display-hero, -1.2px), null),
869
+ display: (var(--matcha-text-display, 32px), var(--matcha-weight-bold, 700), var(--matcha-leading-display, 40px), var(--matcha-tracking-display, -0.3px), null),
870
+ headline: (var(--matcha-text-headline, 24px), var(--matcha-weight-bold, 700), var(--matcha-leading-headline, 32px), var(--matcha-tracking-headline, -0.3px), null),
871
+ title-lg: (var(--matcha-text-title-lg, 20px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-lg, 28px), null, null),
872
+ title-md: (var(--matcha-text-title-md, 18px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-md, 24px), null, null),
873
+ title-sm: (var(--matcha-text-title-sm, 16px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-sm, 22px), null, null),
874
+ title-xs: (var(--matcha-text-title-xs, 14px), var(--matcha-weight-extrabold, 800), var(--matcha-leading-title-xs, 20px), null, null),
875
+ body-lg: (var(--matcha-text-body-lg, 16px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-lg, 24px), null, null),
876
+ body-md: (var(--matcha-text-body-md, 14px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-md, 20px), null, null),
877
+ body-sm: (var(--matcha-text-body-sm, 12px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-sm, 16px), null, null),
878
+ p-tiny: (var(--matcha-text-p-tiny, 11px), var(--matcha-weight-regular, 400), var(--matcha-leading-p-tiny, 14px), var(--matcha-tracking-p-tiny, 0.3px), null),
879
+ label-lg: (var(--matcha-text-label-lg, 16px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-lg, 22px), null, null),
880
+ label-md: (var(--matcha-text-label-md, 14px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-md, 20px), null, null),
881
+ label-sm: (var(--matcha-text-label-sm, 12px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-sm, 16px), null, null),
882
+ overline: (var(--matcha-text-overline, 10px), var(--matcha-weight-semibold, 600), var(--matcha-leading-overline, 14px), var(--matcha-tracking-overline, 1px), uppercase),
883
+ );
884
+
885
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
886
+ @include media-breakpoint($materialBreakpoint) {
887
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
888
+
889
+ @each $name, $props in $text-styles {
890
+ $size: list.nth($props, 1);
891
+ $weight: list.nth($props, 2);
892
+ $leading: list.nth($props, 3);
893
+ $tracking: list.nth($props, 4);
894
+ $transform: list.nth($props, 5);
895
+
896
+ .text#{$infix}-#{$name} {
897
+ font-size: $size;
898
+ font-weight: $weight;
899
+ line-height: $leading;
900
+ @if $tracking != null { letter-spacing: $tracking; }
901
+ @if $transform != null { text-transform: $transform; }
902
+ }
903
+ .text#{$infix}-#{$name}--force {
904
+ font-size: $size !important;
905
+ font-weight: $weight !important;
906
+ line-height: $leading !important;
907
+ @if $tracking != null { letter-spacing: $tracking !important; }
908
+ @if $transform != null { text-transform: $transform !important; }
909
+ }
910
+ }
911
+ }
912
+ }
913
+ }
914
+ @include generate-text-style-classes($helper-breakpoints);
915
+
916
+ // -----------------------------------------------------------------------------------------------------
917
+ // @ Aspect Ratio classes
918
+ // -----------------------------------------------------------------------------------------------------
919
+ @mixin generate-aspect-ratio-classes($helper-breakpoints) {
920
+ // Aspect ratios definition
921
+ $aspect-ratios: (
922
+ 'auto': 'auto',
923
+ '1x1': '1/1',
924
+ '1x2': '1/2',
925
+ '2x1': '2/1',
926
+ '3x4': '3/4',
927
+ '4x3': '4/3',
928
+ '9x16': '9/16',
929
+ '16x9': '16/9',
930
+ 'half': '0.5',
931
+ 'inherit': 'inherit',
932
+ 'initial': 'initial',
933
+ 'unset': 'unset'
934
+ );
935
+
936
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
937
+ @include media-breakpoint($materialBreakpoint) {
938
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
939
+
940
+ @each $ratio, $value in $aspect-ratios {
941
+ $class-name: ".aspect-ratio#{$infix}-#{$ratio}";
942
+
943
+ #{$class-name} {
944
+ aspect-ratio: #{$value};
945
+ }
946
+
947
+ #{$class-name}--force {
948
+ aspect-ratio: #{$value} !important;
949
+ }
950
+ }
951
+ }
952
+ }
953
+ }
954
+ @include generate-aspect-ratio-classes($helper-breakpoints);
955
+
956
+ // -----------------------------------------------------------------------------------------------------
957
+ // @ Cursor classes
958
+ // -----------------------------------------------------------------------------------------------------
959
+ @mixin generate-cursor-classes($helper-breakpoints) {
960
+ $cursor-types: (
961
+ pointer,
962
+ default,
963
+ grab,
964
+ grabbing,
965
+ move,
966
+ help,
967
+ wait
968
+ );
969
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
970
+ @include media-breakpoint($materialBreakpoint) {
971
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
972
+
973
+ @for $i from 1 through list.length($cursor-types) {
974
+ $cursor-type: list.nth($cursor-types, $i);
975
+
976
+ .cursor-#{$cursor-type}#{$infix} {
977
+ cursor: #{$cursor-type};
978
+ }
979
+
980
+ .cursor-#{$cursor-type}#{$infix}--force {
981
+ cursor: #{$cursor-type} !important;
982
+ }
983
+ }
984
+ }
985
+ }
986
+ }
987
+ @include generate-cursor-classes($helper-breakpoints);
988
+
989
+ // -----------------------------------------------------------------------------------------------------
990
+ // @ Pointer Events classes
991
+ // -----------------------------------------------------------------------------------------------------
992
+ @mixin generate-pointer-events-classes($helper-breakpoints) {
993
+ $pointer-events: (
994
+ auto,
995
+ none,
996
+ all,
997
+ visible,
998
+ visiblePainted,
999
+ visibleFill,
1000
+ visibleStroke,
1001
+ painted,
1002
+ fill,
1003
+ stroke
1004
+ );
1005
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1006
+ @include media-breakpoint($materialBreakpoint) {
1007
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1008
+
1009
+ @for $i from 1 through list.length($pointer-events) {
1010
+ $pointer-event: list.nth($pointer-events, $i);
1011
+
1012
+ .pointer-events-#{$pointer-event}#{$infix} {
1013
+ pointer-events: #{$pointer-event};
1014
+ }
1015
+
1016
+ .pointer-events-#{$pointer-event}#{$infix}--force {
1017
+ pointer-events: #{$pointer-event} !important;
1018
+ }
1019
+ }
1020
+ }
1021
+ }
1022
+ }
1023
+ @include generate-pointer-events-classes($helper-breakpoints);
1024
+
1025
+
1026
+ // -----------------------------------------------------------------------------------------------------
1027
+ // @ Opacity
1028
+ // -----------------------------------------------------------------------------------------------------
1029
+ @mixin generate-opacity-classes($helper-breakpoints) {
1030
+ // Definindo os valores de opacidade e seus nomes de classe
1031
+ $opacity-values: (
1032
+ '0': 0,
1033
+ '01': 0.1,
1034
+ '02': 0.2,
1035
+ '03': 0.3,
1036
+ '04': 0.4,
1037
+ '05': 0.5,
1038
+ '06': 0.6,
1039
+ '07': 0.7,
1040
+ '08': 0.8,
1041
+ '09': 0.9,
1042
+ '10': 1.0,
1043
+ '1':1
1044
+ );
1045
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1046
+ @include media-breakpoint($materialBreakpoint) {
1047
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1048
+ @each $step, $opacity in $opacity-values {
1049
+ .opacity#{$infix}-#{$step} {
1050
+ opacity: $opacity;
1051
+ }
1052
+ .opacity#{$infix}-#{$step}--force {
1053
+ opacity: $opacity !important;
1054
+ }
1055
+ }
1056
+ }
1057
+ }
1058
+ }
1059
+ @include generate-opacity-classes($helper-breakpoints);
1060
+
1061
+ // -----------------------------------------------------------------------------------------------------
1062
+ // @ Float & List Style
1063
+ // -----------------------------------------------------------------------------------------------------
1064
+ @mixin generate-float-list-classes {
1065
+ .clearfix::after {
1066
+ content: "";
1067
+ clear: both;
1068
+ display: table;
1069
+ }
1070
+
1071
+ .float-left {
1072
+ float: left;
1073
+ }
1074
+
1075
+ .float-right {
1076
+ float: right;
1077
+ }
1078
+
1079
+ .list-style-none {
1080
+ list-style: none;
1081
+ }
1082
+
1083
+ .list-style-disc {
1084
+ list-style: disc;
1085
+ }
1086
+
1087
+ .list-style-dot {
1088
+ list-style: dot;
1089
+ }
1090
+ }
1091
+ @include generate-float-list-classes;
1092
+
1093
+ // -----------------------------------------------------------------------------------------------------
1094
+ // @ Text Decoration Helpers
1095
+ // -----------------------------------------------------------------------------------------------------
1096
+ @mixin generate-text-decoration-classes($helper-breakpoints){
1097
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1098
+ @include media-breakpoint($materialBreakpoint) {
1099
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1100
+
1101
+ .text#{$infix}-decoration-strike,
1102
+ .text#{$infix}-strike,
1103
+ .text#{$infix}-line-through {
1104
+ text-decoration: line-through;
1105
+ }
1106
+
1107
+ .text#{$infix}-decoration-strike--force,
1108
+ .text#{$infix}-strike--force,
1109
+ .text#{$infix}-line-through--force {
1110
+ text-decoration: line-through !important;
1111
+ }
1112
+
1113
+ .text#{$infix}-decoration-none,
1114
+ .text#{$infix}-none {
1115
+ text-decoration: none;
1116
+ }
1117
+
1118
+ .text#{$infix}-decoration-none--force,
1119
+ .text#{$infix}-none--force {
1120
+ text-decoration: none !important;
1121
+ }
1122
+
1123
+ .text#{$infix}-super {
1124
+ vertical-align: super;
1125
+ }
1126
+
1127
+ .text#{$infix}-super--force {
1128
+ vertical-align: super !important;
1129
+ }
1130
+
1131
+ .text#{$infix}-sub {
1132
+ vertical-align: sub;
1133
+ }
1134
+
1135
+ .text#{$infix}-sub--force {
1136
+ vertical-align: sub !important;
1137
+ }
1138
+ }
1139
+ }
1140
+ }
1141
+ @include generate-text-decoration-classes($helper-breakpoints);
1142
+
1143
+ // -----------------------------------------------------------------------------------------------------
1144
+ // @ Text Alignment and Transform Helpers
1145
+ // -----------------------------------------------------------------------------------------------------
1146
+ @mixin generate-text-alignment-classes($helper-breakpoints){
1147
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1148
+ @include media-breakpoint($materialBreakpoint) {
1149
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1150
+
1151
+ .text#{$infix}-capitalize {
1152
+ text-transform: capitalize;
1153
+ }
1154
+
1155
+ .text#{$infix}-capitalize--force {
1156
+ text-transform: capitalize !important;
1157
+ }
1158
+
1159
+ .text#{$infix}-lowercase {
1160
+ text-transform: lowercase;
1161
+ }
1162
+
1163
+ .text#{$infix}-lowercase--force {
1164
+ text-transform: lowercase !important;
1165
+ }
1166
+
1167
+ .text#{$infix}-uppercase {
1168
+ text-transform: uppercase;
1169
+ }
1170
+
1171
+ .text#{$infix}-uppercase--force {
1172
+ text-transform: uppercase !important;
1173
+ }
1174
+
1175
+ .text#{$infix}-nowrap {
1176
+ white-space: nowrap;
1177
+ }
1178
+
1179
+ .text#{$infix}-left {
1180
+ text-align: left;
1181
+ }
1182
+
1183
+ .text#{$infix}-left--force {
1184
+ text-align: left !important;
1185
+ }
1186
+
1187
+ .text#{$infix}-center {
1188
+ text-align: center;
1189
+ }
1190
+
1191
+ .text#{$infix}-center--force {
1192
+ text-align: center !important;
1193
+ }
1194
+
1195
+ .text#{$infix}-right {
1196
+ text-align: right;
1197
+ }
1198
+
1199
+ .text#{$infix}-right--force {
1200
+ text-align: right !important;
1201
+ }
1202
+ }
1203
+ }
1204
+ }
1205
+ @include generate-text-alignment-classes($helper-breakpoints);
1206
+
1207
+ // -----------------------------------------------------------------------------------------------------
1208
+ // @ Text Spacing and Truncation Helpers
1209
+ // -----------------------------------------------------------------------------------------------------
1210
+ @mixin generate-text-spacing-classes($helper-breakpoints){
1211
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1212
+ @include media-breakpoint($materialBreakpoint) {
1213
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1214
+
1215
+ .text#{$infix}-boxed {
1216
+ border-radius: 2px;
1217
+ padding: 4px 8px;
1218
+ margin: 0 8px;
1219
+ font-size: 11px;
1220
+ font-weight: 600;
1221
+ white-space: nowrap;
1222
+ }
1223
+
1224
+ .text#{$infix}-truncate,
1225
+ .text#{$infix}-ellipsis {
1226
+ display: block;
1227
+ overflow: hidden;
1228
+ text-overflow: ellipsis;
1229
+ white-space: nowrap;
1230
+ }
1231
+ }
1232
+ }
1233
+ }
1234
+ @include generate-text-spacing-classes($helper-breakpoints);
1235
+
1236
+ // -----------------------------------------------------------------------------------------------------
1237
+ // @ Overflow Helpers
1238
+ // -----------------------------------------------------------------------------------------------------
1239
+ @mixin generate-overflow-classes($helper-breakpoints){
1240
+ $overflow-classes: (
1241
+ auto: auto,
1242
+ scroll: scroll,
1243
+ hidden: hidden,
1244
+ overlay: overlay
1245
+ );
1246
+
1247
+ $overflow-directions: (
1248
+ x: (auto: auto, scroll: scroll, hidden: hidden, overlay: overlay),
1249
+ y: (auto: auto, scroll: scroll, hidden: hidden, overlay: overlay)
1250
+ );
1251
+
1252
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1253
+ @include media-breakpoint($materialBreakpoint) {
1254
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1255
+
1256
+ // Classes para overflow geral
1257
+ @each $class, $value in $overflow-classes {
1258
+ .overflow#{$infix}-#{$class} {
1259
+ overflow: $value;
1260
+ }
1261
+ .overflow#{$infix}-#{$class}--force {
1262
+ overflow: $value !important;
1263
+ }
1264
+ }
1265
+
1266
+ // Classes para overflow no eixo x
1267
+ @each $class, $value in map.get($overflow-directions, x) {
1268
+ .overflow-x#{$infix}-#{$class} {
1269
+ overflow-x: $value;
1270
+ }
1271
+ .overflow-x#{$infix}-#{$class}--force {
1272
+ overflow-x: $value !important;
1273
+ }
1274
+ }
1275
+
1276
+ // Classes para overflow no eixo y
1277
+ @each $class, $value in map.get($overflow-directions, y) {
1278
+ .overflow-y#{$infix}-#{$class} {
1279
+ overflow-y: $value;
1280
+ }
1281
+ .overflow-y#{$infix}-#{$class}--force {
1282
+ overflow-y: $value !important;
1283
+ }
1284
+ }
1285
+ }
1286
+ }
1287
+ }
1288
+ @include generate-overflow-classes($helper-breakpoints);
1289
+
1290
+ // -----------------------------------------------------------------------------------------------------
1291
+ // @ Border Size Helpers
1292
+ // -----------------------------------------------------------------------------------------------------
1293
+ @mixin generate-border-size-classes($helper-breakpoints){
1294
+ $border-directions: (bottom: bb, top: bt, left: bl, right: br);
1295
+
1296
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1297
+ @include media-breakpoint($materialBreakpoint) {
1298
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1299
+
1300
+ @for $i from 0 through 4 {
1301
+ $border-value: $i * 2;
1302
+ $border-suffix: "-#{$border-value}";
1303
+
1304
+ // Classes para borda geral
1305
+ .border#{$infix}#{$border-suffix},
1306
+ .b#{$infix}#{$border-suffix} {
1307
+ border: #{$border-value}px solid;
1308
+ }
1309
+
1310
+ // Classes para bordas individuais
1311
+ @each $direction, $abbrev in $border-directions {
1312
+ .border-#{$direction}#{$infix}#{$border-suffix},
1313
+ .#{$abbrev}#{$infix}#{$border-suffix} {
1314
+ border-#{$direction}: #{$border-value}px solid;
1315
+ }
1316
+ .border-#{$direction}#{$infix}#{$border-suffix}--force,
1317
+ .#{$abbrev}#{$infix}#{$border-suffix}--force {
1318
+ border-#{$direction}: #{$border-value}px solid !important;
1319
+ }
1320
+ }
1321
+ }
1322
+ // Classe para borda nula
1323
+ .b#{$infix}-none,
1324
+ .border#{$infix}-none {
1325
+ border: none;
1326
+ }
1327
+ .b#{$infix}-none--force,
1328
+ .border#{$infix}-none--force {
1329
+ border: none !important;
1330
+ }
1331
+
1332
+ // Borda hairline (1px) o loop acima emite pares (0/2/4/6/8).
1333
+ // 1px é o valor que faltava da família e é token DSV3: --matcha-border-hairline.
1334
+ .border#{$infix}-1,
1335
+ .b#{$infix}-1 {
1336
+ border: var(--matcha-border-hairline, 1px) solid;
1337
+ }
1338
+ .border#{$infix}-1--force,
1339
+ .b#{$infix}-1--force {
1340
+ border: var(--matcha-border-hairline, 1px) solid !important;
1341
+ }
1342
+ @each $direction, $abbrev in $border-directions {
1343
+ .border-#{$direction}#{$infix}-1,
1344
+ .#{$abbrev}#{$infix}-1 {
1345
+ border-#{$direction}: var(--matcha-border-hairline, 1px) solid;
1346
+ }
1347
+ .border-#{$direction}#{$infix}-1--force,
1348
+ .#{$abbrev}#{$infix}-1--force {
1349
+ border-#{$direction}: var(--matcha-border-hairline, 1px) solid !important;
1350
+ }
1351
+ }
1352
+ }
1353
+ }
1354
+
1355
+
1356
+ }
1357
+ @include generate-border-size-classes($helper-breakpoints);
1358
+
1359
+ // -----------------------------------------------------------------------------------------------------
1360
+ // @ Border Named Widths (token-backed Figma matcha/border/{hairline,thin,medium,thick})
1361
+ // Espelha o gerador numérico acima, mas nomeado e ligado ao token. Cor herda currentColor
1362
+ // (cor de borda continua sendo token do tema — matcha-core não gera border-color).
1363
+ // -----------------------------------------------------------------------------------------------------
1364
+ @mixin generate-border-named-classes($helper-breakpoints){
1365
+ $border-named: (
1366
+ hairline: var(--matcha-border-hairline, 1px),
1367
+ thin: var(--matcha-border-thin, 2px),
1368
+ medium: var(--matcha-border-medium, 4px),
1369
+ thick: var(--matcha-border-thick, 8px),
1370
+ );
1371
+ $border-directions: (bottom: bb, top: bt, left: bl, right: br);
1372
+
1373
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1374
+ @include media-breakpoint($materialBreakpoint) {
1375
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1376
+
1377
+ @each $name, $width in $border-named {
1378
+ .border#{$infix}-#{$name},
1379
+ .b#{$infix}-#{$name} {
1380
+ border: $width solid;
1381
+ }
1382
+ .border#{$infix}-#{$name}--force,
1383
+ .b#{$infix}-#{$name}--force {
1384
+ border: $width solid !important;
1385
+ }
1386
+
1387
+ @each $direction, $abbrev in $border-directions {
1388
+ .border-#{$direction}#{$infix}-#{$name},
1389
+ .#{$abbrev}#{$infix}-#{$name} {
1390
+ border-#{$direction}: $width solid;
1391
+ }
1392
+ .border-#{$direction}#{$infix}-#{$name}--force,
1393
+ .#{$abbrev}#{$infix}-#{$name}--force {
1394
+ border-#{$direction}: $width solid !important;
1395
+ }
1396
+ }
1397
+ }
1398
+ }
1399
+ }
1400
+ }
1401
+ @include generate-border-named-classes($helper-breakpoints);
1402
+
1403
+ // -----------------------------------------------------------------------------------------------------
1404
+ // @ Border Style
1405
+ // -----------------------------------------------------------------------------------------------------
1406
+ @mixin generate-border-style-classes($helper-breakpoints){
1407
+ $border-styles: (
1408
+ solid: solid,
1409
+ dashed: dashed,
1410
+ dotted: dotted,
1411
+ double: double,
1412
+ groove: groove,
1413
+ ridge: ridge,
1414
+ inset: inset,
1415
+ outset: outset,
1416
+ none: none
1417
+ );
1418
+
1419
+ $border-directions: (
1420
+ bottom: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1421
+ top: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1422
+ left: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1423
+ right: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none)
1424
+ );
1425
+
1426
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1427
+ @include media-breakpoint($materialBreakpoint) {
1428
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1429
+
1430
+ // Classes para estilo de borda geral
1431
+ @each $class, $value in $border-styles {
1432
+ .border-style#{$infix}-#{$class} {
1433
+ border-style: $value;
1434
+ }
1435
+ .border-style#{$infix}-#{$class}--force {
1436
+ border-style: $value !important;
1437
+ }
1438
+ }
1439
+ }
1440
+ }
1441
+ }
1442
+ @include generate-border-style-classes($helper-breakpoints);
1443
+
1444
+ // -----------------------------------------------------------------------------------------------------
1445
+ // @ Border Radius Helpers
1446
+ // -----------------------------------------------------------------------------------------------------
1447
+ @mixin generate-radius-classes($helper-breakpoints){
1448
+ $radius-directions: (bottom: b, top: t, left: l, right: r);
1449
+
1450
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1451
+ @include media-breakpoint($materialBreakpoint) {
1452
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1453
+
1454
+ @for $i from 0 through 12 {
1455
+ $radius-value: $i * 2;
1456
+ $radius-suffix: "-#{$radius-value}";
1457
+ $r: ds-radius($radius-value);
1458
+
1459
+ // Classes para borda geral
1460
+ .radius#{$infix}#{$radius-suffix} {
1461
+ border-radius: $r; // Sem !important
1462
+ }
1463
+
1464
+ // Classes para bordas individuais
1465
+ @each $direction, $abbrev in $radius-directions {
1466
+ @if $direction == bottom {
1467
+ .radius-#{$direction}#{$infix}#{$radius-suffix} {
1468
+ border-radius: 0 0 #{$r} #{$r}; // Sem !important
1469
+ }
1470
+
1471
+ .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1472
+ border-radius: 0 0 #{$r} #{$r} !important; // Com !important
1473
+ }
1474
+ } @else if $direction == top {
1475
+ .radius-#{$direction}#{$infix}#{$radius-suffix} {
1476
+ border-radius: #{$r} #{$r} 0 0; // Sem !important
1477
+ }
1478
+
1479
+ .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1480
+ border-radius: #{$r} #{$r} 0 0 !important; // Com !important
1481
+ }
1482
+ } @else if $direction == left {
1483
+ .radius-#{$direction}#{$infix}#{$radius-suffix} {
1484
+ border-radius: #{$r} 0 0 #{$r}; // Sem !important
1485
+ }
1486
+
1487
+ .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1488
+ border-radius: #{$r} 0 0 #{$r} !important; // Com !important
1489
+ }
1490
+ } @else if $direction == right {
1491
+ .radius-#{$direction}#{$infix}#{$radius-suffix} {
1492
+ border-radius: 0 #{$r} #{$r} 0; // Sem !important
1493
+ }
1494
+
1495
+ .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1496
+ border-radius: 0 #{$r} #{$r} 0 !important; // Com !important
1497
+ }
1498
+ }
1499
+ }
1500
+ }
1501
+ .radius#{$infix}-full {
1502
+ border-radius: 9999px;
1503
+ }
1504
+ .radius#{$infix}-full--force {
1505
+ border-radius: 9999px !important;
1506
+ }
1507
+ .radius#{$infix}-none {
1508
+ border-radius: 0;
1509
+ }
1510
+ .radius#{$infix}-none--force {
1511
+ border-radius: 0 !important;
1512
+ }
1513
+ }
1514
+ }
1515
+ // Classe para borda nula
1516
+ .border-none {
1517
+ border: none !important;
1518
+ }
1519
+ }
1520
+ @include generate-radius-classes($helper-breakpoints);
1521
+
1522
+ // -----------------------------------------------------------------------------------------------------
1523
+ // @ Shadow / Elevation (token-backed Figma matcha/elevation/level-{1-4} --matcha-shadow-*)
1524
+ // Classe utilitária CANÔNICA de sombra. NÃO confundir com o legado .elevation-z-* (Material,
1525
+ // deprecado, gerado no matcha-theme). Alternância light/dark vem do próprio token.
1526
+ // Fallbacks (light) via string.unquote() a sombra é multi-camada (vírgulas) e não pode entrar
1527
+ // crua num mapa Sass. Mantidos fiéis a matcha-theme/tokens/_elevation-tokens.scss.
1528
+ // -----------------------------------------------------------------------------------------------------
1529
+ @mixin generate-shadow-classes() {
1530
+ $shadow-map: (
1531
+ 1: string.unquote("var(--matcha-shadow-1, 0 8px 24px -8px rgba(45, 122, 47, 0.04), 0 2px 8px -1px rgba(26, 44, 30, 0.08), 0 1px 2px rgba(26, 44, 30, 0.04))"),
1532
+ 2: string.unquote("var(--matcha-shadow-2, 0 12px 32px -10px rgba(45, 122, 47, 0.05), 0 4px 16px -2px rgba(26, 44, 30, 0.10), 0 2px 4px -1px rgba(26, 44, 30, 0.05))"),
1533
+ 3: string.unquote("var(--matcha-shadow-3, 0 16px 40px -12px rgba(45, 122, 47, 0.06), 0 12px 32px -4px rgba(26, 44, 30, 0.14), 0 4px 8px -2px rgba(26, 44, 30, 0.08))"),
1534
+ 4: string.unquote("var(--matcha-shadow-4, 0 24px 48px -16px rgba(45, 122, 47, 0.08), 0 24px 48px -8px rgba(26, 44, 30, 0.18), 0 8px 16px -4px rgba(26, 44, 30, 0.10))"),
1535
+ );
1536
+
1537
+ @each $level, $value in $shadow-map {
1538
+ .shadow-#{$level} {
1539
+ box-shadow: $value;
1540
+ }
1541
+ .shadow-#{$level}--force {
1542
+ box-shadow: $value !important;
1543
+ }
1544
+ }
1545
+
1546
+ .shadow-none {
1547
+ box-shadow: none;
1548
+ }
1549
+ .shadow-none--force {
1550
+ box-shadow: none !important;
1551
+ }
1552
+ }
1553
+ @include generate-shadow-classes();
1554
+
1555
+ // -----------------------------------------------------------------------------------------------------
1556
+ // @ Hover - Show/Hide
1557
+ // -----------------------------------------------------------------------------------------------------
1558
+ @mixin generate-hover-show-hide-classes {
1559
+ .on-hover-show:hover {
1560
+ opacity: 1;
1561
+ }
1562
+ .on-hover-hide:hover {
1563
+ opacity: 0;
1564
+ }
1565
+ }
1566
+ @include generate-hover-show-hide-classes;
1567
+
1568
+ // -----------------------------------------------------------------------------------------------------
1569
+ // @ Transition
1570
+ // -----------------------------------------------------------------------------------------------------
1571
+ @mixin generate-transition-classes() {
1572
+ $durations: (100, 300);
1573
+ $easing: ('linear', 'ease-in', 'ease-out', 'ease-in-out');
1574
+ @each $duration in $durations {
1575
+ @each $ease in $easing {
1576
+ $class-suffix: if($ease == 'linear', 'l', if($ease == 'ease-in', 'ei', if($ease == 'ease-out', 'eo', 'eio')));
1577
+ .ts-#{$duration}-#{$class-suffix} {
1578
+ transition: all #{$duration}ms #{$ease};
1579
+ }
1580
+ }
1581
+ }
1582
+ }
1583
+ @include generate-transition-classes();
1584
+
1585
+ // -----------------------------------------------------------------------------------------------------
1586
+ // @ Motion token-backed (Figma matcha/duration/*, matcha/easing/*)
1587
+ // Complementa o legado .ts-* (100/300ms hardcoded, mantido). Estas ligam nos tokens do DS.
1588
+ // .duration-* → transition-duration · .ease-* transition-timing-function
1589
+ // .transition-* → atalho composto (all + duração + easing standard)
1590
+ // -----------------------------------------------------------------------------------------------------
1591
+ @mixin generate-motion-classes() {
1592
+ $duration-map: (
1593
+ instant: var(--matcha-duration-instant, 80ms),
1594
+ fast: var(--matcha-duration-fast, 200ms),
1595
+ normal: var(--matcha-duration-normal, 400ms),
1596
+ slow: var(--matcha-duration-slow, 600ms),
1597
+ );
1598
+ $easing-map: (
1599
+ standard: string.unquote("var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1))"),
1600
+ emphasized: string.unquote("var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1))"),
1601
+ decelerated: string.unquote("var(--matcha-easing-decelerated, cubic-bezier(0, 0, 0.2, 1))"),
1602
+ accelerated: string.unquote("var(--matcha-easing-accelerated, cubic-bezier(0.4, 0, 1, 1))"),
1603
+ );
1604
+ $standard-ease: string.unquote("var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1))");
1605
+
1606
+ @each $name, $value in $duration-map {
1607
+ .duration-#{$name} {
1608
+ transition-duration: $value;
1609
+ }
1610
+ .duration-#{$name}--force {
1611
+ transition-duration: $value !important;
1612
+ }
1613
+ }
1614
+
1615
+ @each $name, $value in $easing-map {
1616
+ .ease-#{$name} {
1617
+ transition-timing-function: $value;
1618
+ }
1619
+ .ease-#{$name}--force {
1620
+ transition-timing-function: $value !important;
1621
+ }
1622
+ }
1623
+
1624
+ @each $name, $value in $duration-map {
1625
+ .transition-#{$name} {
1626
+ transition: all $value $standard-ease;
1627
+ }
1628
+ .transition-#{$name}--force {
1629
+ transition: all $value $standard-ease !important;
1630
+ }
1631
+ }
1632
+ }
1633
+ @include generate-motion-classes();
1634
+
1635
+ // -----------------------------------------------------------------------------------------------------
1636
+ // @ Rotate Animation
1637
+ // -----------------------------------------------------------------------------------------------------
1638
+ @mixin generate-rotate-animation-classes() {
1639
+ // Define as durações desejadas para a animação de rotação
1640
+ $durations: (1, 2, 3);
1641
+ @each $duration in $durations {
1642
+ .rotate-infinity-#{$duration}s {
1643
+ animation: spin #{$duration}s infinite;
1644
+ }
1645
+ }
1646
+ }
1647
+ // Define a keyframes para a animação de rotação
1648
+ @keyframes spin {
1649
+ 0% {
1650
+ transform: rotate(0deg);
1651
+ }
1652
+
1653
+ 100% {
1654
+ transform: rotate(360deg);
1655
+ }
1656
+ }
1657
+ @include generate-rotate-animation-classes();
1658
+
1659
+ // -----------------------------------------------------------------------------------------------------
1660
+ // @ Border Size Helpers
1661
+ // -----------------------------------------------------------------------------------------------------
1662
+ @mixin generate-line-clamp-classes($helper-breakpoints){
1663
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1664
+ @include media-breakpoint($materialBreakpoint) {
1665
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1666
+ @for $i from 0 through 6 {
1667
+ // Classes para borda geral
1668
+ .line-clamp#{$infix}-#{$i}{
1669
+ overflow: hidden;
1670
+ display: -webkit-box;
1671
+ -webkit-box-orient: vertical;
1672
+ -webkit-line-clamp: $i;
1673
+ line-clamp: $i;
1674
+ text-overflow: ellipsis;
1675
+ word-break: break-word;
1676
+ white-space: initial;
1677
+ -webkit-box-orient: vertical;
1678
+ }
1679
+ }
1680
+ .line-clamp#{$infix}-none{
1681
+ overflow: visible;
1682
+ display: block;
1683
+ -webkit-box-orient: horizontal;
1684
+ -webkit-line-clamp: none;
1685
+ line-clamp: none;
1686
+ }
1687
+ }
1688
+ }
1689
+ }
1690
+ @include generate-line-clamp-classes($helper-breakpoints);
1691
+
1692
+ // -----------------------------------------------------------------------------------------------------
1693
+ // @ Masonry
1694
+ // -----------------------------------------------------------------------------------------------------
1695
+ @mixin generate-masonry-classes($helper-breakpoints){
1696
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1697
+ @include media-breakpoint($materialBreakpoint) {
1698
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1699
+ @for $i from 1 through 12 {
1700
+ // Classes para borda geral
1701
+ .masonry#{$infix}-#{$i}{
1702
+ column-count: $i;
1703
+ > *{
1704
+ break-inside: avoid;
1705
+ display: inline-block;
1706
+ width: 100%;
1707
+ }
1708
+ }
1709
+ }
1710
+ @for $i from 0 through 12 {
1711
+ $size: $i * 4;
1712
+ // Classes para borda geral
1713
+ .masonry-gap#{$infix}-#{$size}{
1714
+ column-gap: #{$size}px;
1715
+ > *{
1716
+ margin-bottom: #{$size}px;
1717
+ }
1718
+ }
1719
+ }
1720
+ }
1721
+ }
1722
+ }
1723
+ @include generate-masonry-classes($helper-breakpoints);
1724
+
1725
+
1726
+