@inchurch/matcha-core 22.33.0 → 22.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/core.scss +1790 -1747
  2. package/package.json +1 -1
package/core.scss CHANGED
@@ -1,1747 +1,1790 @@
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
- // @ Tracking classes (letter-spacing token-driven — --matcha-tracking-*)
833
- // -----------------------------------------------------------------------------------------------------
834
- @mixin generate-tracking-classes($helper-breakpoints) {
835
- $tracking-names: display-hero, display, headline, overline, p-tiny;
836
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
837
- @include media-breakpoint($materialBreakpoint) {
838
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
839
- @each $name in $tracking-names {
840
- .tracking#{$infix}-#{$name} {
841
- letter-spacing: var(--matcha-tracking-#{$name});
842
- }
843
- .tracking#{$infix}-#{$name}--force {
844
- letter-spacing: var(--matcha-tracking-#{$name}) !important;
845
- }
846
- }
847
- }
848
- }
849
- }
850
- @include generate-tracking-classes($helper-breakpoints);
851
-
852
- // -----------------------------------------------------------------------------------------------------
853
- // @ Line Height classes
854
- // -----------------------------------------------------------------------------------------------------
855
- @mixin generate-line-height-classes($helper-breakpoints) {
856
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
857
- @include media-breakpoint($materialBreakpoint) {
858
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
859
-
860
- $index: 0;
861
- @while $index <= 100 {
862
- $height: $index * 1;
863
-
864
- .lh#{$infix}-#{$height} {
865
- line-height: #{$height}px;
866
- }
867
-
868
- .lh#{$infix}-#{$height}--force {
869
- line-height: #{$height}px !important;
870
- }
871
-
872
- $index: $index + 1;
873
- }
874
- }
875
- }
876
- }
877
- @include generate-line-height-classes($helper-breakpoints);
878
-
879
- // -----------------------------------------------------------------------------------------------------
880
- // @ Text Styles (composite — Figma matcha/text/*) → size + weight + line-height (+ letter-spacing/transform)
881
- // Uma classe aplica o text style INTEIRO, token-backed. Nomes seguem --matcha-text-* (canônico DS).
882
- // Não colide com os utilitários text-* single-prop (center/uppercase/truncate/...): sufixos distintos.
883
- // Pareamento size/weight/leading/tracking espelha matcha-theme/tokens/_emit-tokens.scss:103-148
884
- // (weight por estilo não é tokenizado → mapeia pro --matcha-weight-* correspondente).
885
- // -----------------------------------------------------------------------------------------------------
886
- @mixin generate-text-style-classes($helper-breakpoints) {
887
- // name: (size, weight, line-height, letter-spacing-or-null, text-transform-or-null)
888
- $text-styles: (
889
- 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),
890
- display: (var(--matcha-text-display, 32px), var(--matcha-weight-bold, 700), var(--matcha-leading-display, 40px), var(--matcha-tracking-display, -0.3px), null),
891
- headline: (var(--matcha-text-headline, 24px), var(--matcha-weight-bold, 700), var(--matcha-leading-headline, 32px), var(--matcha-tracking-headline, -0.3px), null),
892
- title-lg: (var(--matcha-text-title-lg, 20px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-lg, 28px), null, null),
893
- title-md: (var(--matcha-text-title-md, 18px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-md, 24px), null, null),
894
- title-sm: (var(--matcha-text-title-sm, 16px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-sm, 22px), null, null),
895
- title-xs: (var(--matcha-text-title-xs, 14px), var(--matcha-weight-extrabold, 800), var(--matcha-leading-title-xs, 20px), null, null),
896
- body-lg: (var(--matcha-text-body-lg, 16px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-lg, 24px), null, null),
897
- body-md: (var(--matcha-text-body-md, 14px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-md, 20px), null, null),
898
- body-sm: (var(--matcha-text-body-sm, 12px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-sm, 16px), null, null),
899
- 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),
900
- label-lg: (var(--matcha-text-label-lg, 16px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-lg, 22px), null, null),
901
- label-md: (var(--matcha-text-label-md, 14px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-md, 20px), null, null),
902
- label-sm: (var(--matcha-text-label-sm, 12px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-sm, 16px), null, null),
903
- overline: (var(--matcha-text-overline, 10px), var(--matcha-weight-semibold, 600), var(--matcha-leading-overline, 14px), var(--matcha-tracking-overline, 1px), uppercase),
904
- );
905
-
906
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
907
- @include media-breakpoint($materialBreakpoint) {
908
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
909
-
910
- @each $name, $props in $text-styles {
911
- $size: list.nth($props, 1);
912
- $weight: list.nth($props, 2);
913
- $leading: list.nth($props, 3);
914
- $tracking: list.nth($props, 4);
915
- $transform: list.nth($props, 5);
916
-
917
- .text#{$infix}-#{$name} {
918
- font-size: $size;
919
- font-weight: $weight;
920
- line-height: $leading;
921
- @if $tracking != null { letter-spacing: $tracking; }
922
- @if $transform != null { text-transform: $transform; }
923
- }
924
- .text#{$infix}-#{$name}--force {
925
- font-size: $size !important;
926
- font-weight: $weight !important;
927
- line-height: $leading !important;
928
- @if $tracking != null { letter-spacing: $tracking !important; }
929
- @if $transform != null { text-transform: $transform !important; }
930
- }
931
- }
932
- }
933
- }
934
- }
935
- @include generate-text-style-classes($helper-breakpoints);
936
-
937
- // -----------------------------------------------------------------------------------------------------
938
- // @ Aspect Ratio classes
939
- // -----------------------------------------------------------------------------------------------------
940
- @mixin generate-aspect-ratio-classes($helper-breakpoints) {
941
- // Aspect ratios definition
942
- $aspect-ratios: (
943
- 'auto': 'auto',
944
- '1x1': '1/1',
945
- '1x2': '1/2',
946
- '2x1': '2/1',
947
- '3x4': '3/4',
948
- '4x3': '4/3',
949
- '9x16': '9/16',
950
- '16x9': '16/9',
951
- 'half': '0.5',
952
- 'inherit': 'inherit',
953
- 'initial': 'initial',
954
- 'unset': 'unset'
955
- );
956
-
957
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
958
- @include media-breakpoint($materialBreakpoint) {
959
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
960
-
961
- @each $ratio, $value in $aspect-ratios {
962
- $class-name: ".aspect-ratio#{$infix}-#{$ratio}";
963
-
964
- #{$class-name} {
965
- aspect-ratio: #{$value};
966
- }
967
-
968
- #{$class-name}--force {
969
- aspect-ratio: #{$value} !important;
970
- }
971
- }
972
- }
973
- }
974
- }
975
- @include generate-aspect-ratio-classes($helper-breakpoints);
976
-
977
- // -----------------------------------------------------------------------------------------------------
978
- // @ Cursor classes
979
- // -----------------------------------------------------------------------------------------------------
980
- @mixin generate-cursor-classes($helper-breakpoints) {
981
- $cursor-types: (
982
- pointer,
983
- default,
984
- grab,
985
- grabbing,
986
- move,
987
- help,
988
- wait
989
- );
990
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
991
- @include media-breakpoint($materialBreakpoint) {
992
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
993
-
994
- @for $i from 1 through list.length($cursor-types) {
995
- $cursor-type: list.nth($cursor-types, $i);
996
-
997
- .cursor-#{$cursor-type}#{$infix} {
998
- cursor: #{$cursor-type};
999
- }
1000
-
1001
- .cursor-#{$cursor-type}#{$infix}--force {
1002
- cursor: #{$cursor-type} !important;
1003
- }
1004
- }
1005
- }
1006
- }
1007
- }
1008
- @include generate-cursor-classes($helper-breakpoints);
1009
-
1010
- // -----------------------------------------------------------------------------------------------------
1011
- // @ Pointer Events classes
1012
- // -----------------------------------------------------------------------------------------------------
1013
- @mixin generate-pointer-events-classes($helper-breakpoints) {
1014
- $pointer-events: (
1015
- auto,
1016
- none,
1017
- all,
1018
- visible,
1019
- visiblePainted,
1020
- visibleFill,
1021
- visibleStroke,
1022
- painted,
1023
- fill,
1024
- stroke
1025
- );
1026
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1027
- @include media-breakpoint($materialBreakpoint) {
1028
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1029
-
1030
- @for $i from 1 through list.length($pointer-events) {
1031
- $pointer-event: list.nth($pointer-events, $i);
1032
-
1033
- .pointer-events-#{$pointer-event}#{$infix} {
1034
- pointer-events: #{$pointer-event};
1035
- }
1036
-
1037
- .pointer-events-#{$pointer-event}#{$infix}--force {
1038
- pointer-events: #{$pointer-event} !important;
1039
- }
1040
- }
1041
- }
1042
- }
1043
- }
1044
- @include generate-pointer-events-classes($helper-breakpoints);
1045
-
1046
-
1047
- // -----------------------------------------------------------------------------------------------------
1048
- // @ Opacity
1049
- // -----------------------------------------------------------------------------------------------------
1050
- @mixin generate-opacity-classes($helper-breakpoints) {
1051
- // Definindo os valores de opacidade e seus nomes de classe
1052
- $opacity-values: (
1053
- '0': 0,
1054
- '01': 0.1,
1055
- '02': 0.2,
1056
- '03': 0.3,
1057
- '04': 0.4,
1058
- '05': 0.5,
1059
- '06': 0.6,
1060
- '07': 0.7,
1061
- '08': 0.8,
1062
- '09': 0.9,
1063
- '10': 1.0,
1064
- '1':1
1065
- );
1066
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1067
- @include media-breakpoint($materialBreakpoint) {
1068
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1069
- @each $step, $opacity in $opacity-values {
1070
- .opacity#{$infix}-#{$step} {
1071
- opacity: $opacity;
1072
- }
1073
- .opacity#{$infix}-#{$step}--force {
1074
- opacity: $opacity !important;
1075
- }
1076
- }
1077
- }
1078
- }
1079
- }
1080
- @include generate-opacity-classes($helper-breakpoints);
1081
-
1082
- // -----------------------------------------------------------------------------------------------------
1083
- // @ Float & List Style
1084
- // -----------------------------------------------------------------------------------------------------
1085
- @mixin generate-float-list-classes {
1086
- .clearfix::after {
1087
- content: "";
1088
- clear: both;
1089
- display: table;
1090
- }
1091
-
1092
- .float-left {
1093
- float: left;
1094
- }
1095
-
1096
- .float-right {
1097
- float: right;
1098
- }
1099
-
1100
- .list-style-none {
1101
- list-style: none;
1102
- }
1103
-
1104
- .list-style-disc {
1105
- list-style: disc;
1106
- }
1107
-
1108
- .list-style-dot {
1109
- list-style: dot;
1110
- }
1111
- }
1112
- @include generate-float-list-classes;
1113
-
1114
- // -----------------------------------------------------------------------------------------------------
1115
- // @ Text Decoration Helpers
1116
- // -----------------------------------------------------------------------------------------------------
1117
- @mixin generate-text-decoration-classes($helper-breakpoints){
1118
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1119
- @include media-breakpoint($materialBreakpoint) {
1120
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1121
-
1122
- .text#{$infix}-decoration-strike,
1123
- .text#{$infix}-strike,
1124
- .text#{$infix}-line-through {
1125
- text-decoration: line-through;
1126
- }
1127
-
1128
- .text#{$infix}-decoration-strike--force,
1129
- .text#{$infix}-strike--force,
1130
- .text#{$infix}-line-through--force {
1131
- text-decoration: line-through !important;
1132
- }
1133
-
1134
- .text#{$infix}-decoration-none,
1135
- .text#{$infix}-none {
1136
- text-decoration: none;
1137
- }
1138
-
1139
- .text#{$infix}-decoration-none--force,
1140
- .text#{$infix}-none--force {
1141
- text-decoration: none !important;
1142
- }
1143
-
1144
- .text#{$infix}-super {
1145
- vertical-align: super;
1146
- }
1147
-
1148
- .text#{$infix}-super--force {
1149
- vertical-align: super !important;
1150
- }
1151
-
1152
- .text#{$infix}-sub {
1153
- vertical-align: sub;
1154
- }
1155
-
1156
- .text#{$infix}-sub--force {
1157
- vertical-align: sub !important;
1158
- }
1159
- }
1160
- }
1161
- }
1162
- @include generate-text-decoration-classes($helper-breakpoints);
1163
-
1164
- // -----------------------------------------------------------------------------------------------------
1165
- // @ Text Alignment and Transform Helpers
1166
- // -----------------------------------------------------------------------------------------------------
1167
- @mixin generate-text-alignment-classes($helper-breakpoints){
1168
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1169
- @include media-breakpoint($materialBreakpoint) {
1170
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1171
-
1172
- .text#{$infix}-capitalize {
1173
- text-transform: capitalize;
1174
- }
1175
-
1176
- .text#{$infix}-capitalize--force {
1177
- text-transform: capitalize !important;
1178
- }
1179
-
1180
- .text#{$infix}-lowercase {
1181
- text-transform: lowercase;
1182
- }
1183
-
1184
- .text#{$infix}-lowercase--force {
1185
- text-transform: lowercase !important;
1186
- }
1187
-
1188
- .text#{$infix}-uppercase {
1189
- text-transform: uppercase;
1190
- }
1191
-
1192
- .text#{$infix}-uppercase--force {
1193
- text-transform: uppercase !important;
1194
- }
1195
-
1196
- .text#{$infix}-nowrap {
1197
- white-space: nowrap;
1198
- }
1199
-
1200
- .text#{$infix}-left {
1201
- text-align: left;
1202
- }
1203
-
1204
- .text#{$infix}-left--force {
1205
- text-align: left !important;
1206
- }
1207
-
1208
- .text#{$infix}-center {
1209
- text-align: center;
1210
- }
1211
-
1212
- .text#{$infix}-center--force {
1213
- text-align: center !important;
1214
- }
1215
-
1216
- .text#{$infix}-right {
1217
- text-align: right;
1218
- }
1219
-
1220
- .text#{$infix}-right--force {
1221
- text-align: right !important;
1222
- }
1223
- }
1224
- }
1225
- }
1226
- @include generate-text-alignment-classes($helper-breakpoints);
1227
-
1228
- // -----------------------------------------------------------------------------------------------------
1229
- // @ Text Spacing and Truncation Helpers
1230
- // -----------------------------------------------------------------------------------------------------
1231
- @mixin generate-text-spacing-classes($helper-breakpoints){
1232
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1233
- @include media-breakpoint($materialBreakpoint) {
1234
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1235
-
1236
- .text#{$infix}-boxed {
1237
- border-radius: 2px;
1238
- padding: 4px 8px;
1239
- margin: 0 8px;
1240
- font-size: 11px;
1241
- font-weight: 600;
1242
- white-space: nowrap;
1243
- }
1244
-
1245
- .text#{$infix}-truncate,
1246
- .text#{$infix}-ellipsis {
1247
- display: block;
1248
- overflow: hidden;
1249
- text-overflow: ellipsis;
1250
- white-space: nowrap;
1251
- }
1252
- }
1253
- }
1254
- }
1255
- @include generate-text-spacing-classes($helper-breakpoints);
1256
-
1257
- // -----------------------------------------------------------------------------------------------------
1258
- // @ Overflow Helpers
1259
- // -----------------------------------------------------------------------------------------------------
1260
- @mixin generate-overflow-classes($helper-breakpoints){
1261
- $overflow-classes: (
1262
- auto: auto,
1263
- scroll: scroll,
1264
- hidden: hidden,
1265
- overlay: overlay
1266
- );
1267
-
1268
- $overflow-directions: (
1269
- x: (auto: auto, scroll: scroll, hidden: hidden, overlay: overlay),
1270
- y: (auto: auto, scroll: scroll, hidden: hidden, overlay: overlay)
1271
- );
1272
-
1273
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1274
- @include media-breakpoint($materialBreakpoint) {
1275
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1276
-
1277
- // Classes para overflow geral
1278
- @each $class, $value in $overflow-classes {
1279
- .overflow#{$infix}-#{$class} {
1280
- overflow: $value;
1281
- }
1282
- .overflow#{$infix}-#{$class}--force {
1283
- overflow: $value !important;
1284
- }
1285
- }
1286
-
1287
- // Classes para overflow no eixo x
1288
- @each $class, $value in map.get($overflow-directions, x) {
1289
- .overflow-x#{$infix}-#{$class} {
1290
- overflow-x: $value;
1291
- }
1292
- .overflow-x#{$infix}-#{$class}--force {
1293
- overflow-x: $value !important;
1294
- }
1295
- }
1296
-
1297
- // Classes para overflow no eixo y
1298
- @each $class, $value in map.get($overflow-directions, y) {
1299
- .overflow-y#{$infix}-#{$class} {
1300
- overflow-y: $value;
1301
- }
1302
- .overflow-y#{$infix}-#{$class}--force {
1303
- overflow-y: $value !important;
1304
- }
1305
- }
1306
- }
1307
- }
1308
- }
1309
- @include generate-overflow-classes($helper-breakpoints);
1310
-
1311
- // -----------------------------------------------------------------------------------------------------
1312
- // @ Border Size Helpers
1313
- // -----------------------------------------------------------------------------------------------------
1314
- @mixin generate-border-size-classes($helper-breakpoints){
1315
- $border-directions: (bottom: bb, top: bt, left: bl, right: br);
1316
-
1317
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1318
- @include media-breakpoint($materialBreakpoint) {
1319
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1320
-
1321
- @for $i from 0 through 4 {
1322
- $border-value: $i * 2;
1323
- $border-suffix: "-#{$border-value}";
1324
-
1325
- // Classes para borda geral
1326
- .border#{$infix}#{$border-suffix},
1327
- .b#{$infix}#{$border-suffix} {
1328
- border: #{$border-value}px solid;
1329
- }
1330
-
1331
- // Classes para bordas individuais
1332
- @each $direction, $abbrev in $border-directions {
1333
- .border-#{$direction}#{$infix}#{$border-suffix},
1334
- .#{$abbrev}#{$infix}#{$border-suffix} {
1335
- border-#{$direction}: #{$border-value}px solid;
1336
- }
1337
- .border-#{$direction}#{$infix}#{$border-suffix}--force,
1338
- .#{$abbrev}#{$infix}#{$border-suffix}--force {
1339
- border-#{$direction}: #{$border-value}px solid !important;
1340
- }
1341
- }
1342
- }
1343
- // Classe para borda nula
1344
- .b#{$infix}-none,
1345
- .border#{$infix}-none {
1346
- border: none;
1347
- }
1348
- .b#{$infix}-none--force,
1349
- .border#{$infix}-none--force {
1350
- border: none !important;
1351
- }
1352
-
1353
- // Borda hairline (1px) — o loop acima só emite pares (0/2/4/6/8).
1354
- // 1px é o valor que faltava da família e é token DSV3: --matcha-border-hairline.
1355
- .border#{$infix}-1,
1356
- .b#{$infix}-1 {
1357
- border: var(--matcha-border-hairline, 1px) solid;
1358
- }
1359
- .border#{$infix}-1--force,
1360
- .b#{$infix}-1--force {
1361
- border: var(--matcha-border-hairline, 1px) solid !important;
1362
- }
1363
- @each $direction, $abbrev in $border-directions {
1364
- .border-#{$direction}#{$infix}-1,
1365
- .#{$abbrev}#{$infix}-1 {
1366
- border-#{$direction}: var(--matcha-border-hairline, 1px) solid;
1367
- }
1368
- .border-#{$direction}#{$infix}-1--force,
1369
- .#{$abbrev}#{$infix}-1--force {
1370
- border-#{$direction}: var(--matcha-border-hairline, 1px) solid !important;
1371
- }
1372
- }
1373
- }
1374
- }
1375
-
1376
-
1377
- }
1378
- @include generate-border-size-classes($helper-breakpoints);
1379
-
1380
- // -----------------------------------------------------------------------------------------------------
1381
- // @ Border Named Widths (token-backed — Figma matcha/border/{hairline,thin,medium,thick})
1382
- // Espelha o gerador numérico acima, mas nomeado e ligado ao token. Cor herda currentColor
1383
- // (cor de borda continua sendo token do tema — matcha-core não gera border-color).
1384
- // -----------------------------------------------------------------------------------------------------
1385
- @mixin generate-border-named-classes($helper-breakpoints){
1386
- $border-named: (
1387
- hairline: var(--matcha-border-hairline, 1px),
1388
- thin: var(--matcha-border-thin, 2px),
1389
- medium: var(--matcha-border-medium, 4px),
1390
- thick: var(--matcha-border-thick, 8px),
1391
- );
1392
- $border-directions: (bottom: bb, top: bt, left: bl, right: br);
1393
-
1394
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1395
- @include media-breakpoint($materialBreakpoint) {
1396
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1397
-
1398
- @each $name, $width in $border-named {
1399
- .border#{$infix}-#{$name},
1400
- .b#{$infix}-#{$name} {
1401
- border: $width solid;
1402
- }
1403
- .border#{$infix}-#{$name}--force,
1404
- .b#{$infix}-#{$name}--force {
1405
- border: $width solid !important;
1406
- }
1407
-
1408
- @each $direction, $abbrev in $border-directions {
1409
- .border-#{$direction}#{$infix}-#{$name},
1410
- .#{$abbrev}#{$infix}-#{$name} {
1411
- border-#{$direction}: $width solid;
1412
- }
1413
- .border-#{$direction}#{$infix}-#{$name}--force,
1414
- .#{$abbrev}#{$infix}-#{$name}--force {
1415
- border-#{$direction}: $width solid !important;
1416
- }
1417
- }
1418
- }
1419
- }
1420
- }
1421
- }
1422
- @include generate-border-named-classes($helper-breakpoints);
1423
-
1424
- // -----------------------------------------------------------------------------------------------------
1425
- // @ Border Style
1426
- // -----------------------------------------------------------------------------------------------------
1427
- @mixin generate-border-style-classes($helper-breakpoints){
1428
- $border-styles: (
1429
- solid: solid,
1430
- dashed: dashed,
1431
- dotted: dotted,
1432
- double: double,
1433
- groove: groove,
1434
- ridge: ridge,
1435
- inset: inset,
1436
- outset: outset,
1437
- none: none
1438
- );
1439
-
1440
- $border-directions: (
1441
- bottom: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1442
- top: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1443
- left: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1444
- right: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none)
1445
- );
1446
-
1447
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1448
- @include media-breakpoint($materialBreakpoint) {
1449
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1450
-
1451
- // Classes para estilo de borda geral
1452
- @each $class, $value in $border-styles {
1453
- .border-style#{$infix}-#{$class} {
1454
- border-style: $value;
1455
- }
1456
- .border-style#{$infix}-#{$class}--force {
1457
- border-style: $value !important;
1458
- }
1459
- }
1460
- }
1461
- }
1462
- }
1463
- @include generate-border-style-classes($helper-breakpoints);
1464
-
1465
- // -----------------------------------------------------------------------------------------------------
1466
- // @ Border Radius Helpers
1467
- // -----------------------------------------------------------------------------------------------------
1468
- @mixin generate-radius-classes($helper-breakpoints){
1469
- $radius-directions: (bottom: b, top: t, left: l, right: r);
1470
-
1471
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1472
- @include media-breakpoint($materialBreakpoint) {
1473
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1474
-
1475
- @for $i from 0 through 12 {
1476
- $radius-value: $i * 2;
1477
- $radius-suffix: "-#{$radius-value}";
1478
- $r: ds-radius($radius-value);
1479
-
1480
- // Classes para borda geral
1481
- .radius#{$infix}#{$radius-suffix} {
1482
- border-radius: $r; // Sem !important
1483
- }
1484
-
1485
- // Classes para bordas individuais
1486
- @each $direction, $abbrev in $radius-directions {
1487
- @if $direction == bottom {
1488
- .radius-#{$direction}#{$infix}#{$radius-suffix} {
1489
- border-radius: 0 0 #{$r} #{$r}; // Sem !important
1490
- }
1491
-
1492
- .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1493
- border-radius: 0 0 #{$r} #{$r} !important; // Com !important
1494
- }
1495
- } @else if $direction == top {
1496
- .radius-#{$direction}#{$infix}#{$radius-suffix} {
1497
- border-radius: #{$r} #{$r} 0 0; // Sem !important
1498
- }
1499
-
1500
- .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1501
- border-radius: #{$r} #{$r} 0 0 !important; // Com !important
1502
- }
1503
- } @else if $direction == left {
1504
- .radius-#{$direction}#{$infix}#{$radius-suffix} {
1505
- border-radius: #{$r} 0 0 #{$r}; // Sem !important
1506
- }
1507
-
1508
- .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1509
- border-radius: #{$r} 0 0 #{$r} !important; // Com !important
1510
- }
1511
- } @else if $direction == right {
1512
- .radius-#{$direction}#{$infix}#{$radius-suffix} {
1513
- border-radius: 0 #{$r} #{$r} 0; // Sem !important
1514
- }
1515
-
1516
- .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1517
- border-radius: 0 #{$r} #{$r} 0 !important; // Com !important
1518
- }
1519
- }
1520
- }
1521
- }
1522
- .radius#{$infix}-full {
1523
- border-radius: 9999px;
1524
- }
1525
- .radius#{$infix}-full--force {
1526
- border-radius: 9999px !important;
1527
- }
1528
- .radius#{$infix}-none {
1529
- border-radius: 0;
1530
- }
1531
- .radius#{$infix}-none--force {
1532
- border-radius: 0 !important;
1533
- }
1534
- }
1535
- }
1536
- // Classe para borda nula
1537
- .border-none {
1538
- border: none !important;
1539
- }
1540
- }
1541
- @include generate-radius-classes($helper-breakpoints);
1542
-
1543
- // -----------------------------------------------------------------------------------------------------
1544
- // @ Shadow / Elevation (token-backed Figma matcha/elevation/level-{1-4} → --matcha-shadow-*)
1545
- // Classe utilitária CANÔNICA de sombra. NÃO confundir com o legado .elevation-z-* (Material,
1546
- // deprecado, gerado no matcha-theme). Alternância light/dark vem do próprio token.
1547
- // Fallbacks (light) via string.unquote() — a sombra é multi-camada (vírgulas) e não pode entrar
1548
- // crua num mapa Sass. Mantidos fiéis a matcha-theme/tokens/_elevation-tokens.scss.
1549
- // -----------------------------------------------------------------------------------------------------
1550
- @mixin generate-shadow-classes() {
1551
- $shadow-map: (
1552
- 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))"),
1553
- 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))"),
1554
- 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))"),
1555
- 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))"),
1556
- );
1557
-
1558
- @each $level, $value in $shadow-map {
1559
- .shadow-#{$level} {
1560
- box-shadow: $value;
1561
- }
1562
- .shadow-#{$level}--force {
1563
- box-shadow: $value !important;
1564
- }
1565
- }
1566
-
1567
- .shadow-none {
1568
- box-shadow: none;
1569
- }
1570
- .shadow-none--force {
1571
- box-shadow: none !important;
1572
- }
1573
- }
1574
- @include generate-shadow-classes();
1575
-
1576
- // -----------------------------------------------------------------------------------------------------
1577
- // @ Hover - Show/Hide
1578
- // -----------------------------------------------------------------------------------------------------
1579
- @mixin generate-hover-show-hide-classes {
1580
- .on-hover-show:hover {
1581
- opacity: 1;
1582
- }
1583
- .on-hover-hide:hover {
1584
- opacity: 0;
1585
- }
1586
- }
1587
- @include generate-hover-show-hide-classes;
1588
-
1589
- // -----------------------------------------------------------------------------------------------------
1590
- // @ Transition
1591
- // -----------------------------------------------------------------------------------------------------
1592
- @mixin generate-transition-classes() {
1593
- $durations: (100, 300);
1594
- $easing: ('linear', 'ease-in', 'ease-out', 'ease-in-out');
1595
- @each $duration in $durations {
1596
- @each $ease in $easing {
1597
- $class-suffix: if($ease == 'linear', 'l', if($ease == 'ease-in', 'ei', if($ease == 'ease-out', 'eo', 'eio')));
1598
- .ts-#{$duration}-#{$class-suffix} {
1599
- transition: all #{$duration}ms #{$ease};
1600
- }
1601
- }
1602
- }
1603
- }
1604
- @include generate-transition-classes();
1605
-
1606
- // -----------------------------------------------------------------------------------------------------
1607
- // @ Motion — token-backed (Figma matcha/duration/*, matcha/easing/*)
1608
- // Complementa o legado .ts-* (100/300ms hardcoded, mantido). Estas ligam nos tokens do DS.
1609
- // .duration-* → transition-duration · .ease-* → transition-timing-function
1610
- // .transition-* → atalho composto (all + duração + easing standard)
1611
- // -----------------------------------------------------------------------------------------------------
1612
- @mixin generate-motion-classes() {
1613
- $duration-map: (
1614
- instant: var(--matcha-duration-instant, 80ms),
1615
- fast: var(--matcha-duration-fast, 200ms),
1616
- normal: var(--matcha-duration-normal, 400ms),
1617
- slow: var(--matcha-duration-slow, 600ms),
1618
- );
1619
- $easing-map: (
1620
- standard: string.unquote("var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1))"),
1621
- emphasized: string.unquote("var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1))"),
1622
- decelerated: string.unquote("var(--matcha-easing-decelerated, cubic-bezier(0, 0, 0.2, 1))"),
1623
- accelerated: string.unquote("var(--matcha-easing-accelerated, cubic-bezier(0.4, 0, 1, 1))"),
1624
- );
1625
- $standard-ease: string.unquote("var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1))");
1626
-
1627
- @each $name, $value in $duration-map {
1628
- .duration-#{$name} {
1629
- transition-duration: $value;
1630
- }
1631
- .duration-#{$name}--force {
1632
- transition-duration: $value !important;
1633
- }
1634
- }
1635
-
1636
- @each $name, $value in $easing-map {
1637
- .ease-#{$name} {
1638
- transition-timing-function: $value;
1639
- }
1640
- .ease-#{$name}--force {
1641
- transition-timing-function: $value !important;
1642
- }
1643
- }
1644
-
1645
- @each $name, $value in $duration-map {
1646
- .transition-#{$name} {
1647
- transition: all $value $standard-ease;
1648
- }
1649
- .transition-#{$name}--force {
1650
- transition: all $value $standard-ease !important;
1651
- }
1652
- }
1653
- }
1654
- @include generate-motion-classes();
1655
-
1656
- // -----------------------------------------------------------------------------------------------------
1657
- // @ Rotate Animation
1658
- // -----------------------------------------------------------------------------------------------------
1659
- @mixin generate-rotate-animation-classes() {
1660
- // Define as durações desejadas para a animação de rotação
1661
- $durations: (1, 2, 3);
1662
- @each $duration in $durations {
1663
- .rotate-infinity-#{$duration}s {
1664
- animation: spin #{$duration}s infinite;
1665
- }
1666
- }
1667
- }
1668
- // Define a keyframes para a animação de rotação
1669
- @keyframes spin {
1670
- 0% {
1671
- transform: rotate(0deg);
1672
- }
1673
-
1674
- 100% {
1675
- transform: rotate(360deg);
1676
- }
1677
- }
1678
- @include generate-rotate-animation-classes();
1679
-
1680
- // -----------------------------------------------------------------------------------------------------
1681
- // @ Border Size Helpers
1682
- // -----------------------------------------------------------------------------------------------------
1683
- @mixin generate-line-clamp-classes($helper-breakpoints){
1684
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1685
- @include media-breakpoint($materialBreakpoint) {
1686
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1687
- @for $i from 0 through 6 {
1688
- // Classes para borda geral
1689
- .line-clamp#{$infix}-#{$i}{
1690
- overflow: hidden;
1691
- display: -webkit-box;
1692
- -webkit-box-orient: vertical;
1693
- -webkit-line-clamp: $i;
1694
- line-clamp: $i;
1695
- text-overflow: ellipsis;
1696
- word-break: break-word;
1697
- white-space: initial;
1698
- -webkit-box-orient: vertical;
1699
- }
1700
- }
1701
- .line-clamp#{$infix}-none{
1702
- overflow: visible;
1703
- display: block;
1704
- -webkit-box-orient: horizontal;
1705
- -webkit-line-clamp: none;
1706
- line-clamp: none;
1707
- }
1708
- }
1709
- }
1710
- }
1711
- @include generate-line-clamp-classes($helper-breakpoints);
1712
-
1713
- // -----------------------------------------------------------------------------------------------------
1714
- // @ Masonry
1715
- // -----------------------------------------------------------------------------------------------------
1716
- @mixin generate-masonry-classes($helper-breakpoints){
1717
- @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1718
- @include media-breakpoint($materialBreakpoint) {
1719
- $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1720
- @for $i from 1 through 12 {
1721
- // Classes para borda geral
1722
- .masonry#{$infix}-#{$i}{
1723
- column-count: $i;
1724
- > *{
1725
- break-inside: avoid;
1726
- display: inline-block;
1727
- width: 100%;
1728
- }
1729
- }
1730
- }
1731
- @for $i from 0 through 12 {
1732
- $size: $i * 4;
1733
- // Classes para borda geral
1734
- .masonry-gap#{$infix}-#{$size}{
1735
- column-gap: #{$size}px;
1736
- > *{
1737
- margin-bottom: #{$size}px;
1738
- }
1739
- }
1740
- }
1741
- }
1742
- }
1743
- }
1744
- @include generate-masonry-classes($helper-breakpoints);
1745
-
1746
-
1747
-
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
+ // @ Tracking classes (letter-spacing token-driven — --matcha-tracking-*)
833
+ // -----------------------------------------------------------------------------------------------------
834
+ @mixin generate-tracking-classes($helper-breakpoints) {
835
+ $tracking-names: display-hero, display, headline, overline, p-tiny;
836
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
837
+ @include media-breakpoint($materialBreakpoint) {
838
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
839
+ @each $name in $tracking-names {
840
+ .tracking#{$infix}-#{$name} {
841
+ letter-spacing: var(--matcha-tracking-#{$name});
842
+ }
843
+ .tracking#{$infix}-#{$name}--force {
844
+ letter-spacing: var(--matcha-tracking-#{$name}) !important;
845
+ }
846
+ }
847
+ }
848
+ }
849
+ }
850
+ @include generate-tracking-classes($helper-breakpoints);
851
+
852
+ // -----------------------------------------------------------------------------------------------------
853
+ // @ Line Height classes
854
+ // -----------------------------------------------------------------------------------------------------
855
+ @mixin generate-line-height-classes($helper-breakpoints) {
856
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
857
+ @include media-breakpoint($materialBreakpoint) {
858
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
859
+
860
+ $index: 0;
861
+ @while $index <= 100 {
862
+ $height: $index * 1;
863
+
864
+ .lh#{$infix}-#{$height} {
865
+ line-height: #{$height}px;
866
+ }
867
+
868
+ .lh#{$infix}-#{$height}--force {
869
+ line-height: #{$height}px !important;
870
+ }
871
+
872
+ $index: $index + 1;
873
+ }
874
+ }
875
+ }
876
+ }
877
+ @include generate-line-height-classes($helper-breakpoints);
878
+
879
+ // -----------------------------------------------------------------------------------------------------
880
+ // @ Text Styles (composite — Figma matcha/text/*) → size + weight + line-height (+ letter-spacing/transform)
881
+ // Uma classe aplica o text style INTEIRO, token-backed. Nomes seguem --matcha-text-* (canônico DS).
882
+ // Não colide com os utilitários text-* single-prop (center/uppercase/truncate/...): sufixos distintos.
883
+ // Pareamento size/weight/leading/tracking espelha matcha-theme/tokens/_emit-tokens.scss:103-148
884
+ // (weight por estilo não é tokenizado → mapeia pro --matcha-weight-* correspondente).
885
+ // -----------------------------------------------------------------------------------------------------
886
+ @mixin generate-text-style-classes($helper-breakpoints) {
887
+ // name: (size, weight, line-height, letter-spacing-or-null, text-transform-or-null)
888
+ $text-styles: (
889
+ 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),
890
+ display: (var(--matcha-text-display, 32px), var(--matcha-weight-bold, 700), var(--matcha-leading-display, 40px), var(--matcha-tracking-display, -0.3px), null),
891
+ headline: (var(--matcha-text-headline, 24px), var(--matcha-weight-bold, 700), var(--matcha-leading-headline, 32px), var(--matcha-tracking-headline, -0.3px), null),
892
+ title-lg: (var(--matcha-text-title-lg, 20px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-lg, 28px), null, null),
893
+ title-md: (var(--matcha-text-title-md, 18px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-md, 24px), null, null),
894
+ title-sm: (var(--matcha-text-title-sm, 16px), var(--matcha-weight-semibold, 600), var(--matcha-leading-title-sm, 22px), null, null),
895
+ title-xs: (var(--matcha-text-title-xs, 14px), var(--matcha-weight-extrabold, 800), var(--matcha-leading-title-xs, 20px), null, null),
896
+ body-lg: (var(--matcha-text-body-lg, 16px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-lg, 24px), null, null),
897
+ body-md: (var(--matcha-text-body-md, 14px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-md, 20px), null, null),
898
+ body-sm: (var(--matcha-text-body-sm, 12px), var(--matcha-weight-regular, 400), var(--matcha-leading-body-sm, 16px), null, null),
899
+ 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),
900
+ label-lg: (var(--matcha-text-label-lg, 16px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-lg, 22px), null, null),
901
+ label-md: (var(--matcha-text-label-md, 14px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-md, 20px), null, null),
902
+ label-sm: (var(--matcha-text-label-sm, 12px), var(--matcha-weight-medium, 500), var(--matcha-leading-label-sm, 16px), null, null),
903
+ overline: (var(--matcha-text-overline, 10px), var(--matcha-weight-semibold, 600), var(--matcha-leading-overline, 14px), var(--matcha-tracking-overline, 1px), uppercase),
904
+ );
905
+
906
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
907
+ @include media-breakpoint($materialBreakpoint) {
908
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
909
+
910
+ @each $name, $props in $text-styles {
911
+ $size: list.nth($props, 1);
912
+ $weight: list.nth($props, 2);
913
+ $leading: list.nth($props, 3);
914
+ $tracking: list.nth($props, 4);
915
+ $transform: list.nth($props, 5);
916
+
917
+ .text#{$infix}-#{$name} {
918
+ font-size: $size;
919
+ font-weight: $weight;
920
+ line-height: $leading;
921
+ @if $tracking != null { letter-spacing: $tracking; }
922
+ @if $transform != null { text-transform: $transform; }
923
+ }
924
+ .text#{$infix}-#{$name}--force {
925
+ font-size: $size !important;
926
+ font-weight: $weight !important;
927
+ line-height: $leading !important;
928
+ @if $tracking != null { letter-spacing: $tracking !important; }
929
+ @if $transform != null { text-transform: $transform !important; }
930
+ }
931
+ }
932
+ }
933
+ }
934
+ }
935
+ @include generate-text-style-classes($helper-breakpoints);
936
+
937
+ // -----------------------------------------------------------------------------------------------------
938
+ // @ Aspect Ratio classes
939
+ // -----------------------------------------------------------------------------------------------------
940
+ @mixin generate-aspect-ratio-classes($helper-breakpoints) {
941
+ // Aspect ratios definition
942
+ $aspect-ratios: (
943
+ 'auto': 'auto',
944
+ '1x1': '1/1',
945
+ '1x2': '1/2',
946
+ '2x1': '2/1',
947
+ '3x4': '3/4',
948
+ '4x3': '4/3',
949
+ '9x16': '9/16',
950
+ '16x9': '16/9',
951
+ 'half': '0.5',
952
+ 'inherit': 'inherit',
953
+ 'initial': 'initial',
954
+ 'unset': 'unset'
955
+ );
956
+
957
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
958
+ @include media-breakpoint($materialBreakpoint) {
959
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
960
+
961
+ @each $ratio, $value in $aspect-ratios {
962
+ $class-name: ".aspect-ratio#{$infix}-#{$ratio}";
963
+
964
+ #{$class-name} {
965
+ aspect-ratio: #{$value};
966
+ }
967
+
968
+ #{$class-name}--force {
969
+ aspect-ratio: #{$value} !important;
970
+ }
971
+ }
972
+ }
973
+ }
974
+ }
975
+ @include generate-aspect-ratio-classes($helper-breakpoints);
976
+
977
+ // -----------------------------------------------------------------------------------------------------
978
+ // @ Object Fit / Object Position classes
979
+ // -----------------------------------------------------------------------------------------------------
980
+ // Par natural do aspect-ratio acima: a proporção define a CAIXA, o object-fit define como a mídia
981
+ // se acomoda dentro dela. Sem isso, `aspect-ratio-16x9` num <img> distorce a imagem.
982
+ //
983
+ // Faltava, e a ausência custou: `docs/canon/matcha-card.md` do control-panel-v2 manda escrever
984
+ // `class="w-100-p h-100-p object-fit-cover"` na <img> do slot de mídia como reforço, e
985
+ // `events/event-thumb` já usava — sobre uma classe que não existia. O card aplica `object-fit: cover`
986
+ // no próprio SCSS, mas mirando `> img` com encapsulamento emulado, o seletor não alcança elemento
987
+ // PROJETADO, que era exatamente o caso. Ou seja: a imagem podia estar esticada, sem nada avisando.
988
+ @mixin generate-object-fit-classes($helper-breakpoints) {
989
+ $object-fits: (cover, contain, fill, none, scale-down);
990
+ $object-positions: (center, top, bottom, left, right);
991
+
992
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
993
+ @include media-breakpoint($materialBreakpoint) {
994
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
995
+
996
+ @each $fit in $object-fits {
997
+ .object-fit#{$infix}-#{$fit} {
998
+ object-fit: #{$fit};
999
+ }
1000
+
1001
+ .object-fit#{$infix}-#{$fit}--force {
1002
+ object-fit: #{$fit} !important;
1003
+ }
1004
+ }
1005
+
1006
+ @each $position in $object-positions {
1007
+ .object-position#{$infix}-#{$position} {
1008
+ object-position: #{$position};
1009
+ }
1010
+
1011
+ .object-position#{$infix}-#{$position}--force {
1012
+ object-position: #{$position} !important;
1013
+ }
1014
+ }
1015
+ }
1016
+ }
1017
+ }
1018
+ @include generate-object-fit-classes($helper-breakpoints);
1019
+
1020
+ // -----------------------------------------------------------------------------------------------------
1021
+ // @ Cursor classes
1022
+ // -----------------------------------------------------------------------------------------------------
1023
+ @mixin generate-cursor-classes($helper-breakpoints) {
1024
+ $cursor-types: (
1025
+ pointer,
1026
+ default,
1027
+ grab,
1028
+ grabbing,
1029
+ move,
1030
+ help,
1031
+ wait
1032
+ );
1033
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1034
+ @include media-breakpoint($materialBreakpoint) {
1035
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1036
+
1037
+ @for $i from 1 through list.length($cursor-types) {
1038
+ $cursor-type: list.nth($cursor-types, $i);
1039
+
1040
+ .cursor-#{$cursor-type}#{$infix} {
1041
+ cursor: #{$cursor-type};
1042
+ }
1043
+
1044
+ .cursor-#{$cursor-type}#{$infix}--force {
1045
+ cursor: #{$cursor-type} !important;
1046
+ }
1047
+ }
1048
+ }
1049
+ }
1050
+ }
1051
+ @include generate-cursor-classes($helper-breakpoints);
1052
+
1053
+ // -----------------------------------------------------------------------------------------------------
1054
+ // @ Pointer Events classes
1055
+ // -----------------------------------------------------------------------------------------------------
1056
+ @mixin generate-pointer-events-classes($helper-breakpoints) {
1057
+ $pointer-events: (
1058
+ auto,
1059
+ none,
1060
+ all,
1061
+ visible,
1062
+ visiblePainted,
1063
+ visibleFill,
1064
+ visibleStroke,
1065
+ painted,
1066
+ fill,
1067
+ stroke
1068
+ );
1069
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1070
+ @include media-breakpoint($materialBreakpoint) {
1071
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1072
+
1073
+ @for $i from 1 through list.length($pointer-events) {
1074
+ $pointer-event: list.nth($pointer-events, $i);
1075
+
1076
+ .pointer-events-#{$pointer-event}#{$infix} {
1077
+ pointer-events: #{$pointer-event};
1078
+ }
1079
+
1080
+ .pointer-events-#{$pointer-event}#{$infix}--force {
1081
+ pointer-events: #{$pointer-event} !important;
1082
+ }
1083
+ }
1084
+ }
1085
+ }
1086
+ }
1087
+ @include generate-pointer-events-classes($helper-breakpoints);
1088
+
1089
+
1090
+ // -----------------------------------------------------------------------------------------------------
1091
+ // @ Opacity
1092
+ // -----------------------------------------------------------------------------------------------------
1093
+ @mixin generate-opacity-classes($helper-breakpoints) {
1094
+ // Definindo os valores de opacidade e seus nomes de classe
1095
+ $opacity-values: (
1096
+ '0': 0,
1097
+ '01': 0.1,
1098
+ '02': 0.2,
1099
+ '03': 0.3,
1100
+ '04': 0.4,
1101
+ '05': 0.5,
1102
+ '06': 0.6,
1103
+ '07': 0.7,
1104
+ '08': 0.8,
1105
+ '09': 0.9,
1106
+ '10': 1.0,
1107
+ '1':1
1108
+ );
1109
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1110
+ @include media-breakpoint($materialBreakpoint) {
1111
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1112
+ @each $step, $opacity in $opacity-values {
1113
+ .opacity#{$infix}-#{$step} {
1114
+ opacity: $opacity;
1115
+ }
1116
+ .opacity#{$infix}-#{$step}--force {
1117
+ opacity: $opacity !important;
1118
+ }
1119
+ }
1120
+ }
1121
+ }
1122
+ }
1123
+ @include generate-opacity-classes($helper-breakpoints);
1124
+
1125
+ // -----------------------------------------------------------------------------------------------------
1126
+ // @ Float & List Style
1127
+ // -----------------------------------------------------------------------------------------------------
1128
+ @mixin generate-float-list-classes {
1129
+ .clearfix::after {
1130
+ content: "";
1131
+ clear: both;
1132
+ display: table;
1133
+ }
1134
+
1135
+ .float-left {
1136
+ float: left;
1137
+ }
1138
+
1139
+ .float-right {
1140
+ float: right;
1141
+ }
1142
+
1143
+ .list-style-none {
1144
+ list-style: none;
1145
+ }
1146
+
1147
+ .list-style-disc {
1148
+ list-style: disc;
1149
+ }
1150
+
1151
+ .list-style-dot {
1152
+ list-style: dot;
1153
+ }
1154
+ }
1155
+ @include generate-float-list-classes;
1156
+
1157
+ // -----------------------------------------------------------------------------------------------------
1158
+ // @ Text Decoration Helpers
1159
+ // -----------------------------------------------------------------------------------------------------
1160
+ @mixin generate-text-decoration-classes($helper-breakpoints){
1161
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1162
+ @include media-breakpoint($materialBreakpoint) {
1163
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1164
+
1165
+ .text#{$infix}-decoration-strike,
1166
+ .text#{$infix}-strike,
1167
+ .text#{$infix}-line-through {
1168
+ text-decoration: line-through;
1169
+ }
1170
+
1171
+ .text#{$infix}-decoration-strike--force,
1172
+ .text#{$infix}-strike--force,
1173
+ .text#{$infix}-line-through--force {
1174
+ text-decoration: line-through !important;
1175
+ }
1176
+
1177
+ .text#{$infix}-decoration-none,
1178
+ .text#{$infix}-none {
1179
+ text-decoration: none;
1180
+ }
1181
+
1182
+ .text#{$infix}-decoration-none--force,
1183
+ .text#{$infix}-none--force {
1184
+ text-decoration: none !important;
1185
+ }
1186
+
1187
+ .text#{$infix}-super {
1188
+ vertical-align: super;
1189
+ }
1190
+
1191
+ .text#{$infix}-super--force {
1192
+ vertical-align: super !important;
1193
+ }
1194
+
1195
+ .text#{$infix}-sub {
1196
+ vertical-align: sub;
1197
+ }
1198
+
1199
+ .text#{$infix}-sub--force {
1200
+ vertical-align: sub !important;
1201
+ }
1202
+ }
1203
+ }
1204
+ }
1205
+ @include generate-text-decoration-classes($helper-breakpoints);
1206
+
1207
+ // -----------------------------------------------------------------------------------------------------
1208
+ // @ Text Alignment and Transform Helpers
1209
+ // -----------------------------------------------------------------------------------------------------
1210
+ @mixin generate-text-alignment-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}-capitalize {
1216
+ text-transform: capitalize;
1217
+ }
1218
+
1219
+ .text#{$infix}-capitalize--force {
1220
+ text-transform: capitalize !important;
1221
+ }
1222
+
1223
+ .text#{$infix}-lowercase {
1224
+ text-transform: lowercase;
1225
+ }
1226
+
1227
+ .text#{$infix}-lowercase--force {
1228
+ text-transform: lowercase !important;
1229
+ }
1230
+
1231
+ .text#{$infix}-uppercase {
1232
+ text-transform: uppercase;
1233
+ }
1234
+
1235
+ .text#{$infix}-uppercase--force {
1236
+ text-transform: uppercase !important;
1237
+ }
1238
+
1239
+ .text#{$infix}-nowrap {
1240
+ white-space: nowrap;
1241
+ }
1242
+
1243
+ .text#{$infix}-left {
1244
+ text-align: left;
1245
+ }
1246
+
1247
+ .text#{$infix}-left--force {
1248
+ text-align: left !important;
1249
+ }
1250
+
1251
+ .text#{$infix}-center {
1252
+ text-align: center;
1253
+ }
1254
+
1255
+ .text#{$infix}-center--force {
1256
+ text-align: center !important;
1257
+ }
1258
+
1259
+ .text#{$infix}-right {
1260
+ text-align: right;
1261
+ }
1262
+
1263
+ .text#{$infix}-right--force {
1264
+ text-align: right !important;
1265
+ }
1266
+ }
1267
+ }
1268
+ }
1269
+ @include generate-text-alignment-classes($helper-breakpoints);
1270
+
1271
+ // -----------------------------------------------------------------------------------------------------
1272
+ // @ Text Spacing and Truncation Helpers
1273
+ // -----------------------------------------------------------------------------------------------------
1274
+ @mixin generate-text-spacing-classes($helper-breakpoints){
1275
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1276
+ @include media-breakpoint($materialBreakpoint) {
1277
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1278
+
1279
+ .text#{$infix}-boxed {
1280
+ border-radius: 2px;
1281
+ padding: 4px 8px;
1282
+ margin: 0 8px;
1283
+ font-size: 11px;
1284
+ font-weight: 600;
1285
+ white-space: nowrap;
1286
+ }
1287
+
1288
+ .text#{$infix}-truncate,
1289
+ .text#{$infix}-ellipsis {
1290
+ display: block;
1291
+ overflow: hidden;
1292
+ text-overflow: ellipsis;
1293
+ white-space: nowrap;
1294
+ }
1295
+ }
1296
+ }
1297
+ }
1298
+ @include generate-text-spacing-classes($helper-breakpoints);
1299
+
1300
+ // -----------------------------------------------------------------------------------------------------
1301
+ // @ Overflow Helpers
1302
+ // -----------------------------------------------------------------------------------------------------
1303
+ @mixin generate-overflow-classes($helper-breakpoints){
1304
+ $overflow-classes: (
1305
+ auto: auto,
1306
+ scroll: scroll,
1307
+ hidden: hidden,
1308
+ overlay: overlay
1309
+ );
1310
+
1311
+ $overflow-directions: (
1312
+ x: (auto: auto, scroll: scroll, hidden: hidden, overlay: overlay),
1313
+ y: (auto: auto, scroll: scroll, hidden: hidden, overlay: overlay)
1314
+ );
1315
+
1316
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1317
+ @include media-breakpoint($materialBreakpoint) {
1318
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1319
+
1320
+ // Classes para overflow geral
1321
+ @each $class, $value in $overflow-classes {
1322
+ .overflow#{$infix}-#{$class} {
1323
+ overflow: $value;
1324
+ }
1325
+ .overflow#{$infix}-#{$class}--force {
1326
+ overflow: $value !important;
1327
+ }
1328
+ }
1329
+
1330
+ // Classes para overflow no eixo x
1331
+ @each $class, $value in map.get($overflow-directions, x) {
1332
+ .overflow-x#{$infix}-#{$class} {
1333
+ overflow-x: $value;
1334
+ }
1335
+ .overflow-x#{$infix}-#{$class}--force {
1336
+ overflow-x: $value !important;
1337
+ }
1338
+ }
1339
+
1340
+ // Classes para overflow no eixo y
1341
+ @each $class, $value in map.get($overflow-directions, y) {
1342
+ .overflow-y#{$infix}-#{$class} {
1343
+ overflow-y: $value;
1344
+ }
1345
+ .overflow-y#{$infix}-#{$class}--force {
1346
+ overflow-y: $value !important;
1347
+ }
1348
+ }
1349
+ }
1350
+ }
1351
+ }
1352
+ @include generate-overflow-classes($helper-breakpoints);
1353
+
1354
+ // -----------------------------------------------------------------------------------------------------
1355
+ // @ Border Size Helpers
1356
+ // -----------------------------------------------------------------------------------------------------
1357
+ @mixin generate-border-size-classes($helper-breakpoints){
1358
+ $border-directions: (bottom: bb, top: bt, left: bl, right: br);
1359
+
1360
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1361
+ @include media-breakpoint($materialBreakpoint) {
1362
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1363
+
1364
+ @for $i from 0 through 4 {
1365
+ $border-value: $i * 2;
1366
+ $border-suffix: "-#{$border-value}";
1367
+
1368
+ // Classes para borda geral
1369
+ .border#{$infix}#{$border-suffix},
1370
+ .b#{$infix}#{$border-suffix} {
1371
+ border: #{$border-value}px solid;
1372
+ }
1373
+
1374
+ // Classes para bordas individuais
1375
+ @each $direction, $abbrev in $border-directions {
1376
+ .border-#{$direction}#{$infix}#{$border-suffix},
1377
+ .#{$abbrev}#{$infix}#{$border-suffix} {
1378
+ border-#{$direction}: #{$border-value}px solid;
1379
+ }
1380
+ .border-#{$direction}#{$infix}#{$border-suffix}--force,
1381
+ .#{$abbrev}#{$infix}#{$border-suffix}--force {
1382
+ border-#{$direction}: #{$border-value}px solid !important;
1383
+ }
1384
+ }
1385
+ }
1386
+ // Classe para borda nula
1387
+ .b#{$infix}-none,
1388
+ .border#{$infix}-none {
1389
+ border: none;
1390
+ }
1391
+ .b#{$infix}-none--force,
1392
+ .border#{$infix}-none--force {
1393
+ border: none !important;
1394
+ }
1395
+
1396
+ // Borda hairline (1px) o loop acima só emite pares (0/2/4/6/8).
1397
+ // 1px é o valor que faltava da família e é token DSV3: --matcha-border-hairline.
1398
+ .border#{$infix}-1,
1399
+ .b#{$infix}-1 {
1400
+ border: var(--matcha-border-hairline, 1px) solid;
1401
+ }
1402
+ .border#{$infix}-1--force,
1403
+ .b#{$infix}-1--force {
1404
+ border: var(--matcha-border-hairline, 1px) solid !important;
1405
+ }
1406
+ @each $direction, $abbrev in $border-directions {
1407
+ .border-#{$direction}#{$infix}-1,
1408
+ .#{$abbrev}#{$infix}-1 {
1409
+ border-#{$direction}: var(--matcha-border-hairline, 1px) solid;
1410
+ }
1411
+ .border-#{$direction}#{$infix}-1--force,
1412
+ .#{$abbrev}#{$infix}-1--force {
1413
+ border-#{$direction}: var(--matcha-border-hairline, 1px) solid !important;
1414
+ }
1415
+ }
1416
+ }
1417
+ }
1418
+
1419
+
1420
+ }
1421
+ @include generate-border-size-classes($helper-breakpoints);
1422
+
1423
+ // -----------------------------------------------------------------------------------------------------
1424
+ // @ Border Named Widths (token-backed — Figma matcha/border/{hairline,thin,medium,thick})
1425
+ // Espelha o gerador numérico acima, mas nomeado e ligado ao token. Cor herda currentColor
1426
+ // (cor de borda continua sendo token do tema — matcha-core não gera border-color).
1427
+ // -----------------------------------------------------------------------------------------------------
1428
+ @mixin generate-border-named-classes($helper-breakpoints){
1429
+ $border-named: (
1430
+ hairline: var(--matcha-border-hairline, 1px),
1431
+ thin: var(--matcha-border-thin, 2px),
1432
+ medium: var(--matcha-border-medium, 4px),
1433
+ thick: var(--matcha-border-thick, 8px),
1434
+ );
1435
+ $border-directions: (bottom: bb, top: bt, left: bl, right: br);
1436
+
1437
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1438
+ @include media-breakpoint($materialBreakpoint) {
1439
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1440
+
1441
+ @each $name, $width in $border-named {
1442
+ .border#{$infix}-#{$name},
1443
+ .b#{$infix}-#{$name} {
1444
+ border: $width solid;
1445
+ }
1446
+ .border#{$infix}-#{$name}--force,
1447
+ .b#{$infix}-#{$name}--force {
1448
+ border: $width solid !important;
1449
+ }
1450
+
1451
+ @each $direction, $abbrev in $border-directions {
1452
+ .border-#{$direction}#{$infix}-#{$name},
1453
+ .#{$abbrev}#{$infix}-#{$name} {
1454
+ border-#{$direction}: $width solid;
1455
+ }
1456
+ .border-#{$direction}#{$infix}-#{$name}--force,
1457
+ .#{$abbrev}#{$infix}-#{$name}--force {
1458
+ border-#{$direction}: $width solid !important;
1459
+ }
1460
+ }
1461
+ }
1462
+ }
1463
+ }
1464
+ }
1465
+ @include generate-border-named-classes($helper-breakpoints);
1466
+
1467
+ // -----------------------------------------------------------------------------------------------------
1468
+ // @ Border Style
1469
+ // -----------------------------------------------------------------------------------------------------
1470
+ @mixin generate-border-style-classes($helper-breakpoints){
1471
+ $border-styles: (
1472
+ solid: solid,
1473
+ dashed: dashed,
1474
+ dotted: dotted,
1475
+ double: double,
1476
+ groove: groove,
1477
+ ridge: ridge,
1478
+ inset: inset,
1479
+ outset: outset,
1480
+ none: none
1481
+ );
1482
+
1483
+ $border-directions: (
1484
+ bottom: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1485
+ top: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1486
+ left: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none),
1487
+ right: (solid: solid, dashed: dashed, dotted: dotted, double: double, groove: groove, ridge: ridge, inset: inset, outset: outset, none: none)
1488
+ );
1489
+
1490
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1491
+ @include media-breakpoint($materialBreakpoint) {
1492
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1493
+
1494
+ // Classes para estilo de borda geral
1495
+ @each $class, $value in $border-styles {
1496
+ .border-style#{$infix}-#{$class} {
1497
+ border-style: $value;
1498
+ }
1499
+ .border-style#{$infix}-#{$class}--force {
1500
+ border-style: $value !important;
1501
+ }
1502
+ }
1503
+ }
1504
+ }
1505
+ }
1506
+ @include generate-border-style-classes($helper-breakpoints);
1507
+
1508
+ // -----------------------------------------------------------------------------------------------------
1509
+ // @ Border Radius Helpers
1510
+ // -----------------------------------------------------------------------------------------------------
1511
+ @mixin generate-radius-classes($helper-breakpoints){
1512
+ $radius-directions: (bottom: b, top: t, left: l, right: r);
1513
+
1514
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1515
+ @include media-breakpoint($materialBreakpoint) {
1516
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1517
+
1518
+ @for $i from 0 through 12 {
1519
+ $radius-value: $i * 2;
1520
+ $radius-suffix: "-#{$radius-value}";
1521
+ $r: ds-radius($radius-value);
1522
+
1523
+ // Classes para borda geral
1524
+ .radius#{$infix}#{$radius-suffix} {
1525
+ border-radius: $r; // Sem !important
1526
+ }
1527
+
1528
+ // Classes para bordas individuais
1529
+ @each $direction, $abbrev in $radius-directions {
1530
+ @if $direction == bottom {
1531
+ .radius-#{$direction}#{$infix}#{$radius-suffix} {
1532
+ border-radius: 0 0 #{$r} #{$r}; // Sem !important
1533
+ }
1534
+
1535
+ .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1536
+ border-radius: 0 0 #{$r} #{$r} !important; // Com !important
1537
+ }
1538
+ } @else if $direction == top {
1539
+ .radius-#{$direction}#{$infix}#{$radius-suffix} {
1540
+ border-radius: #{$r} #{$r} 0 0; // Sem !important
1541
+ }
1542
+
1543
+ .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1544
+ border-radius: #{$r} #{$r} 0 0 !important; // Com !important
1545
+ }
1546
+ } @else if $direction == left {
1547
+ .radius-#{$direction}#{$infix}#{$radius-suffix} {
1548
+ border-radius: #{$r} 0 0 #{$r}; // Sem !important
1549
+ }
1550
+
1551
+ .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1552
+ border-radius: #{$r} 0 0 #{$r} !important; // Com !important
1553
+ }
1554
+ } @else if $direction == right {
1555
+ .radius-#{$direction}#{$infix}#{$radius-suffix} {
1556
+ border-radius: 0 #{$r} #{$r} 0; // Sem !important
1557
+ }
1558
+
1559
+ .radius-#{$direction}#{$infix}#{$radius-suffix}--force {
1560
+ border-radius: 0 #{$r} #{$r} 0 !important; // Com !important
1561
+ }
1562
+ }
1563
+ }
1564
+ }
1565
+ .radius#{$infix}-full {
1566
+ border-radius: 9999px;
1567
+ }
1568
+ .radius#{$infix}-full--force {
1569
+ border-radius: 9999px !important;
1570
+ }
1571
+ .radius#{$infix}-none {
1572
+ border-radius: 0;
1573
+ }
1574
+ .radius#{$infix}-none--force {
1575
+ border-radius: 0 !important;
1576
+ }
1577
+ }
1578
+ }
1579
+ // Classe para borda nula
1580
+ .border-none {
1581
+ border: none !important;
1582
+ }
1583
+ }
1584
+ @include generate-radius-classes($helper-breakpoints);
1585
+
1586
+ // -----------------------------------------------------------------------------------------------------
1587
+ // @ Shadow / Elevation (token-backed — Figma matcha/elevation/level-{1-4} → --matcha-shadow-*)
1588
+ // Classe utilitária CANÔNICA de sombra. NÃO confundir com o legado .elevation-z-* (Material,
1589
+ // deprecado, gerado no matcha-theme). Alternância light/dark vem do próprio token.
1590
+ // Fallbacks (light) via string.unquote() — a sombra é multi-camada (vírgulas) e não pode entrar
1591
+ // crua num mapa Sass. Mantidos fiéis a matcha-theme/tokens/_elevation-tokens.scss.
1592
+ // -----------------------------------------------------------------------------------------------------
1593
+ @mixin generate-shadow-classes() {
1594
+ $shadow-map: (
1595
+ 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))"),
1596
+ 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))"),
1597
+ 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))"),
1598
+ 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))"),
1599
+ );
1600
+
1601
+ @each $level, $value in $shadow-map {
1602
+ .shadow-#{$level} {
1603
+ box-shadow: $value;
1604
+ }
1605
+ .shadow-#{$level}--force {
1606
+ box-shadow: $value !important;
1607
+ }
1608
+ }
1609
+
1610
+ .shadow-none {
1611
+ box-shadow: none;
1612
+ }
1613
+ .shadow-none--force {
1614
+ box-shadow: none !important;
1615
+ }
1616
+ }
1617
+ @include generate-shadow-classes();
1618
+
1619
+ // -----------------------------------------------------------------------------------------------------
1620
+ // @ Hover - Show/Hide
1621
+ // -----------------------------------------------------------------------------------------------------
1622
+ @mixin generate-hover-show-hide-classes {
1623
+ .on-hover-show:hover {
1624
+ opacity: 1;
1625
+ }
1626
+ .on-hover-hide:hover {
1627
+ opacity: 0;
1628
+ }
1629
+ }
1630
+ @include generate-hover-show-hide-classes;
1631
+
1632
+ // -----------------------------------------------------------------------------------------------------
1633
+ // @ Transition
1634
+ // -----------------------------------------------------------------------------------------------------
1635
+ @mixin generate-transition-classes() {
1636
+ $durations: (100, 300);
1637
+ $easing: ('linear', 'ease-in', 'ease-out', 'ease-in-out');
1638
+ @each $duration in $durations {
1639
+ @each $ease in $easing {
1640
+ $class-suffix: if($ease == 'linear', 'l', if($ease == 'ease-in', 'ei', if($ease == 'ease-out', 'eo', 'eio')));
1641
+ .ts-#{$duration}-#{$class-suffix} {
1642
+ transition: all #{$duration}ms #{$ease};
1643
+ }
1644
+ }
1645
+ }
1646
+ }
1647
+ @include generate-transition-classes();
1648
+
1649
+ // -----------------------------------------------------------------------------------------------------
1650
+ // @ Motion — token-backed (Figma matcha/duration/*, matcha/easing/*)
1651
+ // Complementa o legado .ts-* (100/300ms hardcoded, mantido). Estas ligam nos tokens do DS.
1652
+ // .duration-* → transition-duration · .ease-* → transition-timing-function
1653
+ // .transition-* → atalho composto (all + duração + easing standard)
1654
+ // -----------------------------------------------------------------------------------------------------
1655
+ @mixin generate-motion-classes() {
1656
+ $duration-map: (
1657
+ instant: var(--matcha-duration-instant, 80ms),
1658
+ fast: var(--matcha-duration-fast, 200ms),
1659
+ normal: var(--matcha-duration-normal, 400ms),
1660
+ slow: var(--matcha-duration-slow, 600ms),
1661
+ );
1662
+ $easing-map: (
1663
+ standard: string.unquote("var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1))"),
1664
+ emphasized: string.unquote("var(--matcha-easing-emphasized, cubic-bezier(0.2, 0, 0, 1))"),
1665
+ decelerated: string.unquote("var(--matcha-easing-decelerated, cubic-bezier(0, 0, 0.2, 1))"),
1666
+ accelerated: string.unquote("var(--matcha-easing-accelerated, cubic-bezier(0.4, 0, 1, 1))"),
1667
+ );
1668
+ $standard-ease: string.unquote("var(--matcha-easing-standard, cubic-bezier(0.4, 0, 0.2, 1))");
1669
+
1670
+ @each $name, $value in $duration-map {
1671
+ .duration-#{$name} {
1672
+ transition-duration: $value;
1673
+ }
1674
+ .duration-#{$name}--force {
1675
+ transition-duration: $value !important;
1676
+ }
1677
+ }
1678
+
1679
+ @each $name, $value in $easing-map {
1680
+ .ease-#{$name} {
1681
+ transition-timing-function: $value;
1682
+ }
1683
+ .ease-#{$name}--force {
1684
+ transition-timing-function: $value !important;
1685
+ }
1686
+ }
1687
+
1688
+ @each $name, $value in $duration-map {
1689
+ .transition-#{$name} {
1690
+ transition: all $value $standard-ease;
1691
+ }
1692
+ .transition-#{$name}--force {
1693
+ transition: all $value $standard-ease !important;
1694
+ }
1695
+ }
1696
+ }
1697
+ @include generate-motion-classes();
1698
+
1699
+ // -----------------------------------------------------------------------------------------------------
1700
+ // @ Rotate Animation
1701
+ // -----------------------------------------------------------------------------------------------------
1702
+ @mixin generate-rotate-animation-classes() {
1703
+ // Define as durações desejadas para a animação de rotação
1704
+ $durations: (1, 2, 3);
1705
+ @each $duration in $durations {
1706
+ .rotate-infinity-#{$duration}s {
1707
+ animation: spin #{$duration}s infinite;
1708
+ }
1709
+ }
1710
+ }
1711
+ // Define a keyframes para a animação de rotação
1712
+ @keyframes spin {
1713
+ 0% {
1714
+ transform: rotate(0deg);
1715
+ }
1716
+
1717
+ 100% {
1718
+ transform: rotate(360deg);
1719
+ }
1720
+ }
1721
+ @include generate-rotate-animation-classes();
1722
+
1723
+ // -----------------------------------------------------------------------------------------------------
1724
+ // @ Border Size Helpers
1725
+ // -----------------------------------------------------------------------------------------------------
1726
+ @mixin generate-line-clamp-classes($helper-breakpoints){
1727
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1728
+ @include media-breakpoint($materialBreakpoint) {
1729
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1730
+ @for $i from 0 through 6 {
1731
+ // Classes para borda geral
1732
+ .line-clamp#{$infix}-#{$i}{
1733
+ overflow: hidden;
1734
+ display: -webkit-box;
1735
+ -webkit-box-orient: vertical;
1736
+ -webkit-line-clamp: $i;
1737
+ line-clamp: $i;
1738
+ text-overflow: ellipsis;
1739
+ word-break: break-word;
1740
+ white-space: initial;
1741
+ -webkit-box-orient: vertical;
1742
+ }
1743
+ }
1744
+ .line-clamp#{$infix}-none{
1745
+ overflow: visible;
1746
+ display: block;
1747
+ -webkit-box-orient: horizontal;
1748
+ -webkit-line-clamp: none;
1749
+ line-clamp: none;
1750
+ }
1751
+ }
1752
+ }
1753
+ }
1754
+ @include generate-line-clamp-classes($helper-breakpoints);
1755
+
1756
+ // -----------------------------------------------------------------------------------------------------
1757
+ // @ Masonry
1758
+ // -----------------------------------------------------------------------------------------------------
1759
+ @mixin generate-masonry-classes($helper-breakpoints){
1760
+ @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
1761
+ @include media-breakpoint($materialBreakpoint) {
1762
+ $infix: if($materialBreakpoint == null, "", "-#{$breakpoint}");
1763
+ @for $i from 1 through 12 {
1764
+ // Classes para borda geral
1765
+ .masonry#{$infix}-#{$i}{
1766
+ column-count: $i;
1767
+ > *{
1768
+ break-inside: avoid;
1769
+ display: inline-block;
1770
+ width: 100%;
1771
+ }
1772
+ }
1773
+ }
1774
+ @for $i from 0 through 12 {
1775
+ $size: $i * 4;
1776
+ // Classes para borda geral
1777
+ .masonry-gap#{$infix}-#{$size}{
1778
+ column-gap: #{$size}px;
1779
+ > *{
1780
+ margin-bottom: #{$size}px;
1781
+ }
1782
+ }
1783
+ }
1784
+ }
1785
+ }
1786
+ }
1787
+ @include generate-masonry-classes($helper-breakpoints);
1788
+
1789
+
1790
+