@inchurch/matcha-theme 20.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +303 -0
  2. package/abstracts/_colors.scss +405 -0
  3. package/abstracts/_elevation.scss +102 -0
  4. package/abstracts/_functions.scss +1213 -0
  5. package/abstracts/_media-breakpoint.scss +23 -0
  6. package/abstracts/_typography.scss +127 -0
  7. package/base/_reset.scss +438 -0
  8. package/components/matcha-accordion.scss +157 -0
  9. package/components/matcha-audio-player.scss +32 -0
  10. package/components/matcha-autocomplete.scss +134 -0
  11. package/components/matcha-avatar.scss +161 -0
  12. package/components/matcha-badge.scss +120 -0
  13. package/components/matcha-breadcrumb.scss +126 -0
  14. package/components/matcha-button-toggle.scss +363 -0
  15. package/components/matcha-buttons.scss +784 -0
  16. package/components/matcha-calendar.scss +154 -0
  17. package/components/matcha-cards.scss +205 -0
  18. package/components/matcha-chart-card.scss +60 -0
  19. package/components/matcha-checkbox.scss +554 -0
  20. package/components/matcha-chip.scss +212 -0
  21. package/components/matcha-color-pick.scss +35 -0
  22. package/components/matcha-command-palette.scss +89 -0
  23. package/components/matcha-crop.scss +172 -0
  24. package/components/matcha-date.scss +81 -0
  25. package/components/matcha-divider.scss +45 -0
  26. package/components/matcha-draggable.scss +24 -0
  27. package/components/matcha-drawer.scss +235 -0
  28. package/components/matcha-drop-list.scss +390 -0
  29. package/components/matcha-emoji.scss +69 -0
  30. package/components/matcha-empty-state.scss +118 -0
  31. package/components/matcha-flag.scss +62 -0
  32. package/components/matcha-footer.scss +187 -0
  33. package/components/matcha-form-field.scss +552 -0
  34. package/components/matcha-form-section.scss +101 -0
  35. package/components/matcha-header.scss +325 -0
  36. package/components/matcha-highlight.scss +296 -0
  37. package/components/matcha-hint-text.scss +66 -0
  38. package/components/matcha-horizontal-tree.scss +317 -0
  39. package/components/matcha-icon.scss +106 -0
  40. package/components/matcha-image.scss +62 -0
  41. package/components/matcha-list.scss +212 -0
  42. package/components/matcha-menu.scss +86 -0
  43. package/components/matcha-modal.scss +234 -0
  44. package/components/matcha-nav.scss +450 -0
  45. package/components/matcha-notification.scss +197 -0
  46. package/components/matcha-option.scss +95 -0
  47. package/components/matcha-page-builder.scss +4186 -0
  48. package/components/matcha-paginator.scss +235 -0
  49. package/components/matcha-panel.scss +167 -0
  50. package/components/matcha-profile-card.scss +50 -0
  51. package/components/matcha-progress-bar.scss +209 -0
  52. package/components/matcha-radio.scss +528 -0
  53. package/components/matcha-ripple.scss +7 -0
  54. package/components/matcha-scrollbar.scss +35 -0
  55. package/components/matcha-scrollbox-shadow.scss +123 -0
  56. package/components/matcha-section.scss +105 -0
  57. package/components/matcha-select.scss +661 -0
  58. package/components/matcha-skeleton.scss +138 -0
  59. package/components/matcha-slide-toggle.scss +590 -0
  60. package/components/matcha-slider.scss +188 -0
  61. package/components/matcha-snack-bar.scss +266 -0
  62. package/components/matcha-spin.scss +252 -0
  63. package/components/matcha-spinner.scss +78 -0
  64. package/components/matcha-stepper.scss +177 -0
  65. package/components/matcha-table-cell.scss +41 -0
  66. package/components/matcha-table.scss +785 -0
  67. package/components/matcha-tabs.scss +469 -0
  68. package/components/matcha-text-editor.scss +151 -0
  69. package/components/matcha-time.scss +33 -0
  70. package/components/matcha-timepicker.scss +13 -0
  71. package/components/matcha-toolbar.scss +206 -0
  72. package/components/matcha-tooltip.scss +128 -0
  73. package/components/matcha-uploader.scss +215 -0
  74. package/css/matcha-style.css +76772 -0
  75. package/fonts/CircularStd-Black.eot +0 -0
  76. package/fonts/CircularStd-Black.svg +3426 -0
  77. package/fonts/CircularStd-Black.ttf +0 -0
  78. package/fonts/CircularStd-Black.woff +0 -0
  79. package/fonts/CircularStd-Black.woff2 +0 -0
  80. package/fonts/CircularStd-Bold.eot +0 -0
  81. package/fonts/CircularStd-Bold.otf +0 -0
  82. package/fonts/CircularStd-Bold.svg +13532 -0
  83. package/fonts/CircularStd-Bold.ttf +0 -0
  84. package/fonts/CircularStd-Bold.woff +0 -0
  85. package/fonts/CircularStd-Bold.woff2 +0 -0
  86. package/fonts/CircularStd-Medium.eot +0 -0
  87. package/fonts/CircularStd-Medium.otf +0 -0
  88. package/fonts/CircularStd-Medium.svg +13511 -0
  89. package/fonts/CircularStd-Medium.ttf +0 -0
  90. package/fonts/CircularStd-Medium.woff +0 -0
  91. package/fonts/CircularStd-Medium.woff2 +0 -0
  92. package/fonts/CircularStd-Regular.eot +0 -0
  93. package/fonts/CircularStd-Regular.otf +0 -0
  94. package/fonts/CircularStd-Regular.svg +2378 -0
  95. package/fonts/CircularStd-Regular.ttf +0 -0
  96. package/fonts/CircularStd-Regular.woff +0 -0
  97. package/fonts/CircularStd-Regular.woff2 +0 -0
  98. package/main.scss +262 -0
  99. package/package.json +11 -0
  100. package/tokens/_animations-tokens.scss +37 -0
  101. package/tokens/_breakpoints-tokens.scss +26 -0
  102. package/tokens/_color-tokens.scss +1153 -0
  103. package/tokens/_css-custom-properties.scss +568 -0
  104. package/tokens/_elevation-tokens.scss +33 -0
  105. package/tokens/_spacing-tokens.scss +94 -0
  106. package/tokens/_typography-tokens.scss +65 -0
  107. package/vendors/angular-editor.scss +56 -0
  108. package/vendors/angular-material-fixes.scss +297 -0
  109. package/vendors/calendar.scss +2880 -0
  110. package/vendors/charts.scss +92 -0
  111. package/vendors/ng5-slider.scss +56 -0
  112. package/vendors/ngx-material-timepicker.scss +50 -0
@@ -0,0 +1,590 @@
1
+ // =============================================================================
2
+ // matcha-slide-toggle.scss — Migração Fase 3.1
3
+ //
4
+ // Template B: replaced element com child container
5
+ // - input[type="checkbox"] é replaced element (::before/::after são pseudo-elementos
6
+ // internos do browser para track/thumb, não suportam state layer externo)
7
+ // - label é o container hit area → recebe o state layer (::before)
8
+ // - Pattern: color: getXxx($theme) no label → currentColor funciona no ::before
9
+ //
10
+ // Mudanças:
11
+ // [3.1-A] State layer em label (container do replaced element)
12
+ // [3.1-B] cursor: not-allowed + opacity no .matcha-slide-toggle-disabled removidos
13
+ // [3.1-C] Disabled: tokens semânticos no mixin
14
+ // [3.1-D] :focus-within no mixin (foco está no input dentro do label)
15
+ // [3.1-E] transition: all → transições específicas
16
+ // [3.1-F] @media (prefers-reduced-motion: reduce) adicionado
17
+ // [3.1-G] :not([disabled]) guards via seletor de contexto do pai
18
+ // =============================================================================
19
+
20
+ @mixin matcha-slide-toggle-theme($theme) {
21
+ matcha-slide-toggle {
22
+ // Figma matcha/switch (14510:226): track off sem fill + stroke text-label, thumb off text-primary
23
+ input[type="checkbox"] {
24
+ &::before {
25
+ background-color: transparent;
26
+ border-color: var(--matcha-color-text-label, #{getGrey($theme)});
27
+ }
28
+
29
+ &::after {
30
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
31
+ background-color: var(--matcha-color-text-primary);
32
+ }
33
+ }
34
+
35
+ // ── Sem cor / accent ───────────────────────────────────────────────
36
+ &:not([color]),
37
+ &[color="accent"] {
38
+ // [3.1-A] color no label → currentColor para o state layer
39
+ label {
40
+ color: var(--matcha-color-accent, #{getAccent($theme)});
41
+ }
42
+
43
+ input[type="checkbox"] {
44
+ &:checked {
45
+ &::before {
46
+ background-color: var(--matcha-color-accent, #{getAccent($theme)});
47
+ border-color: var(--matcha-color-accent, #{getAccent($theme)});
48
+ }
49
+
50
+ &::after {
51
+ background-color: getAccentContrast($theme);
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ // ── Paleta: red ────────────────────────────────────────────────────
58
+ &[color="red"] {
59
+ label { color: getRed($theme); } // [3.1-A]
60
+
61
+ input[type="checkbox"]:checked::before {
62
+ background-color: getRed($theme);
63
+ border-color: getRed($theme);
64
+ }
65
+
66
+ input[type="checkbox"]:checked::after {
67
+ background-color: getRedContrast($theme);
68
+ }
69
+ }
70
+
71
+ // ── Paleta: pink ───────────────────────────────────────────────────
72
+ &[color="pink"] {
73
+ label { color: getPink($theme); } // [3.1-A]
74
+
75
+ input[type="checkbox"]:checked::before {
76
+ background-color: getPink($theme);
77
+ border-color: getPink($theme);
78
+ }
79
+
80
+ input[type="checkbox"]:checked::after {
81
+ background-color: getPinkContrast($theme);
82
+ }
83
+ }
84
+
85
+ // ── Paleta: purple ─────────────────────────────────────────────────
86
+ &[color="purple"] {
87
+ label { color: getPurple($theme); } // [3.1-A]
88
+
89
+ input[type="checkbox"]:checked::before {
90
+ background-color: getPurple($theme);
91
+ border-color: getPurple($theme);
92
+ }
93
+
94
+ input[type="checkbox"]:checked::after {
95
+ background-color: getPurpleContrast($theme);
96
+ }
97
+ }
98
+
99
+ // ── Paleta: deep-purple ────────────────────────────────────────────
100
+ &[color="deep-purple"] {
101
+ label { color: getDeepPurple($theme); } // [3.1-A]
102
+
103
+ input[type="checkbox"]:checked::before {
104
+ background-color: getDeepPurple($theme);
105
+ border-color: getDeepPurple($theme);
106
+ }
107
+
108
+ input[type="checkbox"]:checked::after {
109
+ background-color: getDeepPurpleContrast($theme);
110
+ }
111
+ }
112
+
113
+ // ── Paleta: indigo ─────────────────────────────────────────────────
114
+ &[color="indigo"] {
115
+ label { color: getIndigo($theme); } // [3.1-A]
116
+
117
+ input[type="checkbox"]:checked::before {
118
+ background-color: getIndigo($theme);
119
+ border-color: getIndigo($theme);
120
+ }
121
+
122
+ input[type="checkbox"]:checked::after {
123
+ background-color: getIndigoContrast($theme);
124
+ }
125
+ }
126
+
127
+ // ── Paleta: blue ───────────────────────────────────────────────────
128
+ &[color="blue"] {
129
+ label { color: getBlue($theme); } // [3.1-A]
130
+
131
+ input[type="checkbox"]:checked::before {
132
+ background-color: getBlue($theme);
133
+ border-color: getBlue($theme);
134
+ }
135
+
136
+ input[type="checkbox"]:checked::after {
137
+ background-color: getBlueContrast($theme);
138
+ }
139
+ }
140
+
141
+ // ── Paleta: light-blue ─────────────────────────────────────────────
142
+ &[color="light-blue"] {
143
+ label { color: getLightBlue($theme); } // [3.1-A]
144
+
145
+ input[type="checkbox"]:checked::before {
146
+ background-color: getLightBlue($theme);
147
+ border-color: getLightBlue($theme);
148
+ }
149
+
150
+ input[type="checkbox"]:checked::after {
151
+ background-color: getLightBlueContrast($theme);
152
+ }
153
+ }
154
+
155
+ // ── Paleta: cyan ───────────────────────────────────────────────────
156
+ &[color="cyan"] {
157
+ label { color: getCyan($theme); } // [3.1-A]
158
+
159
+ input[type="checkbox"]:checked::before {
160
+ background-color: getCyan($theme);
161
+ border-color: getCyan($theme);
162
+ }
163
+
164
+ input[type="checkbox"]:checked::after {
165
+ background-color: getCyanContrast($theme);
166
+ }
167
+ }
168
+
169
+ // ── Paleta: teal ───────────────────────────────────────────────────
170
+ &[color="teal"] {
171
+ label { color: getTeal($theme); } // [3.1-A]
172
+
173
+ input[type="checkbox"]:checked::before {
174
+ background-color: getTeal($theme);
175
+ border-color: getTeal($theme);
176
+ }
177
+
178
+ input[type="checkbox"]:checked::after {
179
+ background-color: getTealContrast($theme);
180
+ }
181
+ }
182
+
183
+ // ── Paleta: green ──────────────────────────────────────────────────
184
+ &[color="green"] {
185
+ label { color: getGreen($theme); } // [3.1-A]
186
+
187
+ input[type="checkbox"]:checked::before {
188
+ background-color: getGreen($theme);
189
+ border-color: getGreen($theme);
190
+ }
191
+
192
+ input[type="checkbox"]:checked::after {
193
+ background-color: getGreenContrast($theme);
194
+ }
195
+ }
196
+
197
+ // ── Paleta: light-green ────────────────────────────────────────────
198
+ &[color="light-green"] {
199
+ label { color: getLightGreen($theme); } // [3.1-A]
200
+
201
+ input[type="checkbox"]:checked::before {
202
+ background-color: getLightGreen($theme);
203
+ border-color: getLightGreen($theme);
204
+ }
205
+
206
+ input[type="checkbox"]:checked::after {
207
+ background-color: getLightGreenContrast($theme);
208
+ }
209
+ }
210
+
211
+ // ── Paleta: lime ───────────────────────────────────────────────────
212
+ &[color="lime"] {
213
+ label { color: getLime($theme); } // [3.1-A]
214
+
215
+ input[type="checkbox"]:checked::before {
216
+ background-color: getLime($theme);
217
+ border-color: getLime($theme);
218
+ }
219
+
220
+ input[type="checkbox"]:checked::after {
221
+ background-color: getLimeContrast($theme);
222
+ }
223
+ }
224
+
225
+ // ── Paleta: yellow ─────────────────────────────────────────────────
226
+ &[color="yellow"] {
227
+ label { color: getYellow($theme); } // [3.1-A]
228
+
229
+ input[type="checkbox"]:checked::before {
230
+ background-color: getYellow($theme);
231
+ border-color: getYellow($theme);
232
+ }
233
+
234
+ input[type="checkbox"]:checked::after {
235
+ background-color: getYellowContrast($theme);
236
+ }
237
+ }
238
+
239
+ // ── Paleta: amber ──────────────────────────────────────────────────
240
+ &[color="amber"] {
241
+ label { color: getAmber($theme); } // [3.1-A]
242
+
243
+ input[type="checkbox"]:checked::before {
244
+ background-color: getAmber($theme);
245
+ border-color: getAmber($theme);
246
+ }
247
+
248
+ input[type="checkbox"]:checked::after {
249
+ background-color: getAmberContrast($theme);
250
+ }
251
+ }
252
+
253
+ // ── Paleta: orange ─────────────────────────────────────────────────
254
+ &[color="orange"] {
255
+ label { color: getOrange($theme); } // [3.1-A]
256
+
257
+ input[type="checkbox"]:checked::before {
258
+ background-color: getOrange($theme);
259
+ border-color: getOrange($theme);
260
+ }
261
+
262
+ input[type="checkbox"]:checked::after {
263
+ background-color: getOrangeContrast($theme);
264
+ }
265
+ }
266
+
267
+ // ── Paleta: deep-orange ────────────────────────────────────────────
268
+ &[color="deep-orange"] {
269
+ label { color: getDeepOrange($theme); } // [3.1-A]
270
+
271
+ input[type="checkbox"]:checked::before {
272
+ background-color: getDeepOrange($theme);
273
+ border-color: getDeepOrange($theme);
274
+ }
275
+
276
+ input[type="checkbox"]:checked::after {
277
+ background-color: getDeepOrangeContrast($theme);
278
+ }
279
+ }
280
+
281
+ // ── Paleta: brown ──────────────────────────────────────────────────
282
+ &[color="brown"] {
283
+ label { color: getBrown($theme); } // [3.1-A]
284
+
285
+ input[type="checkbox"]:checked::before {
286
+ background-color: getBrown($theme);
287
+ border-color: getBrown($theme);
288
+ }
289
+
290
+ input[type="checkbox"]:checked::after {
291
+ background-color: getBrownContrast($theme);
292
+ }
293
+ }
294
+
295
+ // ── Paleta: grey ───────────────────────────────────────────────────
296
+ &[color="grey"] {
297
+ label { color: getGrey($theme); } // [3.1-A]
298
+
299
+ input[type="checkbox"]:checked::before {
300
+ background-color: getGrey($theme);
301
+ border-color: getGrey($theme);
302
+ }
303
+
304
+ input[type="checkbox"]:checked::after {
305
+ background-color: getGreyContrast($theme);
306
+ }
307
+ }
308
+
309
+ // ── Paleta: blue-grey ──────────────────────────────────────────────
310
+ &[color="blue-grey"] {
311
+ label { color: getBlueGrey($theme); } // [3.1-A]
312
+
313
+ input[type="checkbox"]:checked::before {
314
+ background-color: getBlueGrey($theme);
315
+ border-color: getBlueGrey($theme);
316
+ }
317
+
318
+ input[type="checkbox"]:checked::after {
319
+ background-color: getBlueGreyContrast($theme);
320
+ }
321
+ }
322
+
323
+ // ── Semântica: primary ─────────────────────────────────────────────
324
+ &[color="primary"] {
325
+ label { color: var(--matcha-color-primary, #{getPrimary($theme)}); } // [3.1-A]
326
+
327
+ input[type="checkbox"]:checked::before {
328
+ background-color: var(--matcha-color-primary, #{getPrimary($theme)});
329
+ border-color: var(--matcha-color-primary, #{getPrimary($theme)});
330
+ }
331
+
332
+ input[type="checkbox"]:checked::after {
333
+ background-color: getPrimaryContrast($theme);
334
+ }
335
+ }
336
+
337
+ // ── Semântica: success ─────────────────────────────────────────────
338
+ &[color="success"] {
339
+ label { color: getSuccess($theme); } // [3.1-A]
340
+
341
+ input[type="checkbox"]:checked::before {
342
+ background-color: getSuccess($theme);
343
+ border-color: getSuccess($theme);
344
+ }
345
+
346
+ input[type="checkbox"]:checked::after {
347
+ background-color: getSuccessContrast($theme);
348
+ }
349
+ }
350
+
351
+ // ── Semântica: warn ────────────────────────────────────────────────
352
+ &[color="warn"] {
353
+ label { color: getWarn($theme); } // [3.1-A]
354
+
355
+ input[type="checkbox"]:checked::before {
356
+ background-color: getWarn($theme);
357
+ border-color: getWarn($theme);
358
+ }
359
+
360
+ input[type="checkbox"]:checked::after {
361
+ background-color: getWarnContrast($theme);
362
+ }
363
+ }
364
+
365
+ // ── Semântica: danger ──────────────────────────────────────────────
366
+ &[color="danger"] {
367
+ label { color: getDanger($theme); } // [3.1-A]
368
+
369
+ input[type="checkbox"]:checked::before {
370
+ background-color: getDanger($theme);
371
+ border-color: getDanger($theme);
372
+ }
373
+
374
+ input[type="checkbox"]:checked::after {
375
+ background-color: getDangerContrast($theme);
376
+ }
377
+ }
378
+
379
+ // ── Semântica: info ────────────────────────────────────────────────
380
+ &[color="info"] {
381
+ label { color: getInfo($theme); } // [3.1-A]
382
+
383
+ input[type="checkbox"]:checked::before {
384
+ background-color: getInfo($theme);
385
+ border-color: getInfo($theme);
386
+ }
387
+
388
+ input[type="checkbox"]:checked::after {
389
+ background-color: getInfoContrast($theme);
390
+ }
391
+ }
392
+
393
+ // ── Error state (aligned with Figma State=Error) ──────────────────
394
+ &.matcha-slide-toggle-error,
395
+ &[error] {
396
+ input[type="checkbox"] {
397
+ &::before {
398
+ border-color: var(--matcha-color-danger, #{getDanger($theme)});
399
+ }
400
+
401
+ &:checked::before {
402
+ background-color: var(--matcha-color-danger, #{getDanger($theme)});
403
+ border-color: var(--matcha-color-danger, #{getDanger($theme)});
404
+ }
405
+ }
406
+ }
407
+
408
+ // ── Loading state (aligned with Figma State=Loading) ────────────────
409
+ &.matcha-slide-toggle-loading,
410
+ &[loading] {
411
+ pointer-events: none;
412
+
413
+ input[type="checkbox"]::after {
414
+ animation: matcha-toggle-loading 800ms linear infinite;
415
+ }
416
+ }
417
+
418
+ // ── [3.1-C] Disabled — tokens semânticos (sem opacity no host) ─────
419
+ &[disabled] {
420
+ label {
421
+ color: var(--matcha-color-disabled-fg, #{getDisabledBgContrast($theme)});
422
+ }
423
+
424
+ input[type="checkbox"] {
425
+ &::before {
426
+ background-color: var(--matcha-color-disabled-bg, #{getDisabled($theme)});
427
+ border-color: var(--matcha-color-disabled-bg, #{getDisabled($theme)});
428
+ }
429
+
430
+ &::after {
431
+ background-color: var(--matcha-color-disabled-fg, #{getDisabledBgContrast($theme)});
432
+ }
433
+ }
434
+ }
435
+
436
+ // Focus ring: só em navegação por teclado (não mostra em clique com mouse).
437
+ // :has(input:focus-visible) — apenas mostra outline quando o input interno
438
+ // tem focus-visible (keyboard nav), não em :focus geral (mouse click).
439
+ label:has(input:focus-visible) {
440
+ outline: var(--matcha-state-focus-ring-width, 2px) solid
441
+ var(--matcha-color-primary, #{getPrimary($theme)});
442
+ outline-offset: var(--matcha-state-focus-ring-offset, 2px);
443
+ }
444
+
445
+ // Label padrão — Figma: text-primary (não text-label cinza)
446
+ .matcha-slide-toggle-label {
447
+ color: var(--matcha-color-text-primary);
448
+ }
449
+ }
450
+ }
451
+
452
+
453
+ // =============================================================================
454
+ // Bloco estrutural — fora do mixin de tema
455
+ // =============================================================================
456
+
457
+ // [3.1-A] label recebe o state layer
458
+ // input[type="checkbox"] é replaced element — state layer externo vai no container (label)
459
+ matcha-slide-toggle label {
460
+ position: relative;
461
+ overflow: hidden;
462
+
463
+ // State layer — segue INTERACTION-SYSTEM.md template B
464
+ &::before {
465
+ content: '';
466
+ position: absolute;
467
+ inset: 0;
468
+ background: currentColor; // usa color: getXxx($theme) definido no mixin por variante
469
+ opacity: 0;
470
+ pointer-events: none;
471
+ transition: opacity var(--matcha-duration-instant, 80ms) linear;
472
+ }
473
+ }
474
+
475
+ // [3.1-G] Hover/active: [disabled] está em matcha-slide-toggle (pai), não no label
476
+ // Seletor de contexto do pai evita ativar o state layer quando desabilitado
477
+ matcha-slide-toggle:not([disabled]) label:hover::before { opacity: var(--matcha-state-hover, 0.08); }
478
+ matcha-slide-toggle:not([disabled]) label:active::before { opacity: var(--matcha-state-active, 0.12); }
479
+
480
+ matcha-slide-toggle {
481
+ label {
482
+ display: inline-flex;
483
+ align-items: center;
484
+ gap: var(--matcha-space-100, 8px); // Figma: gap 8 entre switch e content
485
+ cursor: pointer;
486
+ -webkit-tap-highlight-color: transparent;
487
+ vertical-align: middle;
488
+
489
+ .matcha-slide-toggle-label {
490
+ font-family: var(--matcha-font-family, 'Manrope', sans-serif);
491
+ font-size: var(--matcha-text-body-md, 14px);
492
+ line-height: 20px;
493
+ font-weight: 400;
494
+ user-select: none;
495
+ }
496
+ }
497
+
498
+ // [3.1-B] Disabled — sem cursor: not-allowed, sem opacity no host
499
+ // pointer-events: none bloqueia interação; cores via tokens no mixin
500
+ &[disabled] {
501
+ pointer-events: none;
502
+
503
+ label {
504
+ cursor: default;
505
+ }
506
+ }
507
+
508
+ input[type="checkbox"] {
509
+ appearance: none;
510
+ -webkit-appearance: none;
511
+ position: relative;
512
+ display: inline-block;
513
+ width: 36px;
514
+ height: 20px;
515
+ margin: 0;
516
+ outline: none;
517
+ cursor: pointer;
518
+ vertical-align: middle;
519
+ min-width: 36px; // garante que não fique < 36px
520
+ flex-shrink: 0; // se estiver dentro de um container flex
521
+
522
+ &::before {
523
+ content: "";
524
+ position: absolute;
525
+ top: 50%;
526
+ left: 0;
527
+ transform: translateY(-50%);
528
+ width: 100%;
529
+ height: 20px;
530
+ border-width: 2px;
531
+ border-style: solid;
532
+ border-radius: var(--matcha-radius-xl, 16px);
533
+ box-sizing: border-box;
534
+
535
+ // [3.1-E] transition específico (não 'all')
536
+ transition: background-color 0.15s linear;
537
+ }
538
+
539
+ // Figma matcha/switch: thumb 12×12 off → 16×16 on (14510:226)
540
+ &::after {
541
+ content: "";
542
+ position: absolute;
543
+ top: 4px;
544
+ left: 4px;
545
+ width: 12px;
546
+ height: 12px;
547
+ border-radius: 50%;
548
+
549
+ transition:
550
+ transform 0.15s cubic-bezier(0.4, 0, 0.2, 1),
551
+ width 0.15s cubic-bezier(0.4, 0, 0.2, 1),
552
+ height 0.15s cubic-bezier(0.4, 0, 0.2, 1),
553
+ top 0.15s cubic-bezier(0.4, 0, 0.2, 1),
554
+ left 0.15s cubic-bezier(0.4, 0, 0.2, 1),
555
+ background-color 0.15s linear,
556
+ outline 0.1s ease-out;
557
+ }
558
+
559
+ &:checked {
560
+ &::after {
561
+ top: 2px;
562
+ left: 2px;
563
+ width: 16px;
564
+ height: 16px;
565
+ transform: translateX(16px); // desliza 16px (36 - 16 - 2×2 = 16)
566
+ }
567
+ }
568
+
569
+ &:focus-visible::after {
570
+ outline-offset: 2px;
571
+ }
572
+ }
573
+
574
+ // ── Loading animation ──
575
+ @keyframes matcha-toggle-loading {
576
+ 0% { opacity: 1; }
577
+ 50% { opacity: 0.4; }
578
+ 100% { opacity: 1; }
579
+ }
580
+
581
+ // [3.1-F] Movimento reduzido — obrigatório (WCAG 2.3.3)
582
+ @media (prefers-reduced-motion: reduce) {
583
+ input[type="checkbox"] {
584
+ &::before { transition: none; }
585
+ &::after { transition: none; animation: none; }
586
+ }
587
+
588
+ label::before { transition: none; }
589
+ }
590
+ }