@inchurch/matcha-theme 22.40.0 → 22.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/abstracts/_colors.scss +291 -291
  2. package/abstracts/_elevation.scss +108 -108
  3. package/abstracts/_functions.scss +321 -321
  4. package/abstracts/_media-breakpoint.scss +26 -26
  5. package/abstracts/_theme-api.scss +224 -224
  6. package/abstracts/_typography.scss +128 -128
  7. package/base/_reset.scss +487 -487
  8. package/components/app-page-header.scss +260 -260
  9. package/components/matcha-accordion.scss +297 -297
  10. package/components/matcha-audio-player.scss +31 -31
  11. package/components/matcha-autocomplete.scss +145 -145
  12. package/components/matcha-avatar.scss +426 -426
  13. package/components/matcha-badge.scss +120 -120
  14. package/components/matcha-breadcrumb.scss +231 -231
  15. package/components/matcha-button-toggle.scss +484 -484
  16. package/components/matcha-buttons.scss +973 -973
  17. package/components/matcha-calendar.scss +253 -253
  18. package/components/matcha-cards.scss +212 -212
  19. package/components/matcha-chart-card.scss +53 -53
  20. package/components/matcha-checkbox.scss +266 -266
  21. package/components/matcha-chip.scss +311 -311
  22. package/components/matcha-color-pick.scss +34 -34
  23. package/components/matcha-command-palette.scss +316 -316
  24. package/components/matcha-crop.scss +419 -419
  25. package/components/matcha-date.scss +81 -81
  26. package/components/matcha-divider.scss +100 -100
  27. package/components/matcha-draggable.scss +23 -23
  28. package/components/matcha-drawer.scss +376 -376
  29. package/components/matcha-drop-image.scss +14 -14
  30. package/components/matcha-drop-list.scss +430 -430
  31. package/components/matcha-emoji.scss +69 -69
  32. package/components/matcha-empty-state.scss +230 -230
  33. package/components/matcha-file-uploader.scss +650 -650
  34. package/components/matcha-flag.scss +103 -103
  35. package/components/matcha-footer.scss +91 -91
  36. package/components/matcha-form-field.scss +883 -883
  37. package/components/matcha-form-section.scss +100 -100
  38. package/components/matcha-header.scss +135 -135
  39. package/components/matcha-highlight.scss +164 -164
  40. package/components/matcha-hint-text.scss +90 -90
  41. package/components/matcha-horizontal-tree.scss +247 -247
  42. package/components/matcha-icon.scss +111 -111
  43. package/components/matcha-image.scss +60 -60
  44. package/components/matcha-list.scss +211 -211
  45. package/components/matcha-menu.scss +99 -99
  46. package/components/matcha-modal.scss +210 -210
  47. package/components/matcha-nav.scss +770 -770
  48. package/components/matcha-notification.scss +417 -417
  49. package/components/matcha-option.scss +170 -170
  50. package/components/matcha-page-builder.scss +4196 -4196
  51. package/components/matcha-paginator.scss +699 -699
  52. package/components/matcha-panel.scss +216 -216
  53. package/components/matcha-period.scss +174 -174
  54. package/components/matcha-profile-card.scss +50 -50
  55. package/components/matcha-progress-bar.scss +355 -355
  56. package/components/matcha-radio.scss +325 -325
  57. package/components/matcha-ripple.scss +7 -7
  58. package/components/matcha-scrollbar.scss +33 -33
  59. package/components/matcha-scrollbox-shadow.scss +120 -120
  60. package/components/matcha-section.scss +102 -102
  61. package/components/matcha-select-multiple.scss +56 -56
  62. package/components/matcha-select.scss +643 -629
  63. package/components/matcha-skeleton.scss +182 -182
  64. package/components/matcha-slide-toggle.scss +369 -369
  65. package/components/matcha-slider.scss +285 -285
  66. package/components/matcha-snack-bar.scss +259 -259
  67. package/components/matcha-spin.scss +164 -164
  68. package/components/matcha-spinner.scss +97 -97
  69. package/components/matcha-stepper.scss +376 -376
  70. package/components/matcha-table-cell.scss +107 -107
  71. package/components/matcha-table.scss +722 -722
  72. package/components/matcha-tabs.scss +642 -642
  73. package/components/matcha-text-editor.scss +111 -111
  74. package/components/matcha-time.scss +33 -33
  75. package/components/matcha-timepicker.scss +13 -13
  76. package/components/matcha-toolbar.scss +366 -366
  77. package/components/matcha-tooltip.scss +235 -235
  78. package/components/matcha-tree-view.scss +658 -658
  79. package/layout/matcha-page-layout.scss +778 -778
  80. package/main.scss +334 -334
  81. package/package.json +1 -1
  82. package/tokens/_animations-tokens.scss +37 -37
  83. package/tokens/_breakpoints-tokens.scss +35 -35
  84. package/tokens/_color-tokens.scss +288 -288
  85. package/tokens/_elevation-tokens.scss +33 -33
  86. package/tokens/_emit-tokens.scss +329 -329
  87. package/tokens/_material-palette.scss +1149 -1149
  88. package/tokens/_primitives.scss +98 -98
  89. package/tokens/_semantic-aliases.scss +120 -120
  90. package/tokens/_spacing-tokens.scss +94 -94
  91. package/tokens/_static-tokens.scss +137 -137
  92. package/tokens/_typography-tokens.scss +65 -65
  93. package/vendors/charts.scss +90 -90
@@ -1,426 +1,426 @@
1
- // =============================================================================
2
- // matcha-avatar.scss — Avatar component (photo, initials, placeholder + status)
3
- // Aligned with Figma Avatar/Matcha: XS(24) SM(32) MD(40) LG(56) XL(80) 2XL(96)
4
- //
5
- // Estado visual (size/color/status/disabled/placeholder) é selecionado por
6
- // ATRIBUTO no host (`matcha-avatar[size="medium"]`), não por classe — mesmo
7
- // padrão já usado pelo `ring` abaixo e pelo `outline`/`link` do matcha-button.
8
- // A classe `.matcha-avatar` na bolinha interna é só identidade estrutural.
9
- // =============================================================================
10
-
11
- // ── Structural (outside mixin) ──────────────────────────────────────────────
12
-
13
- // Host — SEMPRE inline-flex, incondicional (não depende de haver conteúdo
14
- // projetado). Com zero filhos em matcha-avatar-name/-caption/slot genérico,
15
- // um flex container de um único item (a bolinha) renderiza idêntico a um
16
- // avatar bare de hoje — não precisa de @ContentChild pra alternar layout.
17
- matcha-avatar {
18
- display: inline-flex;
19
- align-items: center;
20
- gap: var(--matcha-space-100, 8px);
21
-
22
- &[orientation="stacked"] {
23
- flex-direction: column;
24
- text-align: center;
25
- }
26
- }
27
-
28
- .matcha-avatar-text {
29
- display: flex;
30
- flex-direction: column;
31
- min-width: 0;
32
- }
33
-
34
- matcha-avatar-name {
35
- display: block;
36
- color: var(--matcha-color-text-primary);
37
- font-weight: var(--matcha-weight-medium, 500);
38
- overflow: hidden;
39
- text-overflow: ellipsis;
40
- white-space: nowrap;
41
- }
42
-
43
- matcha-avatar-caption {
44
- display: block;
45
- color: var(--matcha-color-text-muted);
46
- font-weight: var(--matcha-weight-regular, 400);
47
- font-variant-numeric: tabular-nums;
48
- overflow: hidden;
49
- text-overflow: ellipsis;
50
- white-space: nowrap;
51
- }
52
-
53
- .matcha-avatar {
54
- display: inline-flex;
55
- align-items: center;
56
- justify-content: center;
57
- position: relative;
58
- // SEM overflow:hidden — o status indicator fica no canto fora do círculo
59
- // visível e seria cortado. A <img> com border-radius inherit já se arredonda
60
- // sozinha; SVG e Initials ficam dentro dos bounds.
61
- border-radius: var(--matcha-radius-pill, 9999px);
62
-
63
- font-weight: var(--matcha-weight-medium, 500);
64
- user-select: none;
65
- flex-shrink: 0;
66
- }
67
-
68
- // =============================================================================
69
- // Ring colored (additive) — controlado pelo [ring] @Input do component.
70
- // 2px solid + halo alpha externo. Não ocupa layout (box-shadow puro).
71
- //
72
- // Aplicado no .matcha-avatar INNER (não no host) porque o inner é quem tem
73
- // width/height/border-radius:pill — box-shadow segue o radius desse elemento
74
- // e renderiza circular. No host (inline default) sairia retangular.
75
- //
76
- // Os 6 tokens semânticos resolvem inteiro aqui via seletor de atributo — var()
77
- // direto, sem custom property nem lookup no componente. Halo (glow externo) só
78
- // em accent/success/warn/danger; primary/neutral só têm o anel sólido. Cor
79
- // literal (hex/rgb/var arbitrário) é o ÚNICO caso que passa pela custom
80
- // property --matcha-avatar-ring-color (não dá pra enumerar seletor de atributo
81
- // pra valor arbitrário) — branch de fallback no final, sem halo.
82
- // =============================================================================
83
- matcha-avatar[ring="accent"] .matcha-avatar {
84
- box-shadow:
85
- 0 0 0 2px transparent,
86
- 0 0 0 3px var(--matcha-color-accent),
87
- 0 0 0 5px var(--matcha-color-accent-alpha, rgba(0, 148, 0, 0.10));
88
- }
89
-
90
- matcha-avatar[ring="success"] .matcha-avatar {
91
- box-shadow:
92
- 0 0 0 2px transparent,
93
- 0 0 0 3px var(--matcha-color-success),
94
- 0 0 0 5px var(--matcha-color-success-alpha, rgba(22, 163, 74, 0.10));
95
- }
96
-
97
- matcha-avatar[ring="warn"] .matcha-avatar {
98
- box-shadow:
99
- 0 0 0 2px transparent,
100
- 0 0 0 3px var(--matcha-color-warn),
101
- 0 0 0 5px var(--matcha-color-warn-alpha, rgba(245, 158, 11, 0.10));
102
- }
103
-
104
- matcha-avatar[ring="danger"] .matcha-avatar {
105
- box-shadow:
106
- 0 0 0 2px transparent,
107
- 0 0 0 3px var(--matcha-color-danger),
108
- 0 0 0 5px var(--matcha-color-danger-alpha, rgba(239, 68, 68, 0.10));
109
- }
110
-
111
- matcha-avatar[ring="primary"] .matcha-avatar {
112
- box-shadow:
113
- 0 0 0 2px transparent,
114
- 0 0 0 3px var(--matcha-color-primary);
115
- }
116
-
117
- matcha-avatar[ring="neutral"] .matcha-avatar {
118
- box-shadow:
119
- 0 0 0 2px transparent,
120
- 0 0 0 3px var(--matcha-color-surface-border);
121
- }
122
-
123
- // Fallback — [ring] presente mas não é nenhum dos 6 tokens acima (cor literal).
124
- matcha-avatar[ring]:not([ring="accent"]):not([ring="success"]):not([ring="warn"]):not([ring="danger"]):not([ring="primary"]):not([ring="neutral"]) .matcha-avatar {
125
- box-shadow:
126
- 0 0 0 2px transparent,
127
- 0 0 0 3px var(--matcha-avatar-ring-color, currentColor);
128
- }
129
-
130
- // ── Sizes — Canonical 5-step scale: tiny 24 · small 40 · medium 56 · large 80 · huge 96.
131
- // O setter do [size] já normaliza os apelidos abreviados (xs/sm/md/lg/xl/2xl) pro nome
132
- // canônico antes de refletir o atributo — só precisa dos 5 branches aqui.
133
- // NOTE: --matcha-avatar-* tokens ainda carregam os nomes abreviados legados; retierar pra
134
- // tiny/small/medium/large/huge do lado Figma/DSV3 é trabalho separado (design-driven).
135
- matcha-avatar[size="tiny"] .matcha-avatar {
136
- width: var(--matcha-avatar-xs, 24px);
137
- height: var(--matcha-avatar-xs, 24px);
138
- font-size: var(--matcha-text-2xs, 10px);
139
- line-height: 1;
140
- }
141
-
142
- matcha-avatar[size="small"] .matcha-avatar {
143
- width: var(--matcha-avatar-md, 40px);
144
- height: var(--matcha-avatar-md, 40px);
145
- font-size: var(--matcha-text-md, 14px);
146
- line-height: 1;
147
- }
148
-
149
- matcha-avatar[size="medium"] .matcha-avatar {
150
- width: var(--matcha-avatar-lg, 56px);
151
- height: var(--matcha-avatar-lg, 56px);
152
- font-size: var(--matcha-text-2xl, 20px);
153
- line-height: 1;
154
- }
155
-
156
- matcha-avatar[size="large"] .matcha-avatar {
157
- width: var(--matcha-avatar-xl, 80px);
158
- height: var(--matcha-avatar-xl, 80px);
159
- font-size: var(--matcha-text-3xl, 24px);
160
- line-height: 1;
161
- }
162
-
163
- matcha-avatar[size="huge"] .matcha-avatar {
164
- width: var(--matcha-avatar-2xl, 96px);
165
- height: var(--matcha-avatar-2xl, 96px);
166
- font-size: var(--matcha-text-4xl, 32px);
167
- line-height: 1;
168
- }
169
-
170
- // ── Tipografia de matcha-avatar-name/-caption por [size] — mesmo [size] que
171
- // já governa a bolinha, sem input separado nem seletor de irmão.
172
- matcha-avatar[size="tiny"] {
173
- matcha-avatar-name { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
174
- matcha-avatar-caption { font-size: var(--matcha-text-xs, 11px); line-height: var(--matcha-leading-xs, 14px); }
175
- }
176
- matcha-avatar[size="small"] {
177
- matcha-avatar-name { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
178
- matcha-avatar-caption { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
179
- }
180
- matcha-avatar[size="medium"] {
181
- matcha-avatar-name { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
182
- matcha-avatar-caption { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
183
- }
184
- matcha-avatar[size="large"] {
185
- matcha-avatar-name { font-size: var(--matcha-text-xl, 18px); line-height: var(--matcha-leading-xl, 24px); }
186
- matcha-avatar-caption { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
187
- }
188
- matcha-avatar[size="huge"] {
189
- matcha-avatar-name { font-size: var(--matcha-text-title-lg, 20px); line-height: var(--matcha-leading-title-lg, 28px); }
190
- matcha-avatar-caption { font-size: var(--matcha-text-xl, 18px); line-height: var(--matcha-leading-xl, 24px); }
191
- }
192
-
193
- // ── Stacked (hero/profile header) — tipografia maior, negrito, centralizada.
194
- matcha-avatar[orientation="stacked"] {
195
- &[size="tiny"], &[size="small"] {
196
- matcha-avatar-name { font-size: var(--matcha-text-title-sm, 16px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-sm, 22px); }
197
- matcha-avatar-caption { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
198
- }
199
- &[size="medium"], &[size="large"] {
200
- matcha-avatar-name { font-size: var(--matcha-text-title-md, 18px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-md, 24px); }
201
- matcha-avatar-caption { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
202
- }
203
- &[size="huge"] {
204
- matcha-avatar-name { font-size: var(--matcha-text-title-lg, 20px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-lg, 28px); }
205
- matcha-avatar-caption { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
206
- }
207
- }
208
-
209
- .matcha-avatar {
210
- // ── Image ──
211
- .matcha-avatar-image {
212
- width: 100%;
213
- height: 100%;
214
- object-fit: cover;
215
- border-radius: inherit;
216
- }
217
-
218
- // ── Initials ──
219
- .matcha-avatar-initials {
220
- font-weight: var(--matcha-weight-medium, 500);
221
- text-transform: uppercase;
222
- letter-spacing: var(--matcha-letter-spacing-wide, 0.5px);
223
- }
224
-
225
- // ── Placeholder icon ──
226
- .matcha-avatar-icon {
227
- width: 100%;
228
- height: 100%;
229
- }
230
- }
231
-
232
- // ── Disabled ─────────────────────────────────────────────────────────────────
233
- // `.color-disabled` preservado como gatilho manual alternativo (pré-existente,
234
- // não gerido pelo componente) — `[disabled]` é o gatilho canônico hoje.
235
- matcha-avatar[disabled] .matcha-avatar,
236
- .matcha-avatar.color-disabled {
237
- opacity: var(--matcha-opacity-disabled, 0.38);
238
- pointer-events: none;
239
- }
240
-
241
- // ── Placeholder — vazado canônico (Figma matcha/avatar 5668:32088) ──────────
242
- // SVG usa fill-rule=evenodd: disco preenchido com currentColor + silhueta vazada.
243
- // `currentColor` do disco precisa ser a COR DA MARCA (não o contrast da .color class
244
- // global, que é branco/preto). Override aqui força o token de palette.
245
- matcha-avatar[placeholder] .matcha-avatar {
246
- background: transparent !important;
247
- }
248
-
249
- matcha-avatar[color="primary"][placeholder] .matcha-avatar { color: var(--matcha-color-primary) !important; }
250
- matcha-avatar[color="light-blue"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-light-blue) !important; }
251
- matcha-avatar[color="pink"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-pink) !important; }
252
- matcha-avatar[color="teal"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-teal) !important; }
253
- matcha-avatar[color="purple"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-purple) !important; }
254
- matcha-avatar[color="orange"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-orange) !important; }
255
- matcha-avatar[color="yellow"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-yellow) !important; }
256
- matcha-avatar[color="neutral"][placeholder] .matcha-avatar { color: var(--matcha-color-icon-default) !important; }
257
-
258
- // Neutral em Initials — cinza canônico Figma (icon-default).
259
- matcha-avatar[color="neutral"]:not([placeholder]) .matcha-avatar {
260
- background: var(--matcha-color-icon-default);
261
- }
262
-
263
- // ── Initials — bg + fg por cor (primary semântico + 6 da palette Figma DSV3) ─
264
- // O palette inverte por tema (light=tons saturados, dark=tons claros). text-primary
265
- // também inverte (#1a1d21 light / #e8eaed dark). Combinar os dois → contraste péssimo
266
- // em dark mode (1.2-2.9:1 FAIL). Por isso fg da palette é fixed-per-color, não token-based.
267
- // `primary` é semântico — usa `--matcha-color-primary-contrast`, já resolvido por tema.
268
- //
269
- // Light mode: pink/teal/purple bg escuros → fg branco. light-blue/orange/yellow bg
270
- // claros → fg preto (light-blue precisa #000 puro pra AA por 0.08).
271
- // Dark mode: todos os bg ficam lighter → fg preto funciona em tudo (5-12:1).
272
-
273
- matcha-avatar[color="primary"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-primary); }
274
- matcha-avatar[color="light-blue"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-light-blue); }
275
- matcha-avatar[color="pink"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-pink); }
276
- matcha-avatar[color="teal"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-teal); }
277
- matcha-avatar[color="purple"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-purple); }
278
- matcha-avatar[color="orange"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-orange); }
279
- matcha-avatar[color="yellow"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-yellow); }
280
-
281
- matcha-avatar[color="primary"]:not([placeholder]) .matcha-avatar {
282
- color: var(--matcha-color-primary-contrast);
283
- }
284
-
285
- // Light mode — bgs saturados (pink/teal/purple = escuros), fg branco passa AA.
286
- // orange/yellow/light-blue = claros, fg precisa ser dark (#000 pra light-blue por margem).
287
- .theme-default-light matcha-avatar[color="light-blue"]:not([placeholder]) .matcha-avatar { color: #000; } // 5.42:1 AA
288
- .theme-default-light matcha-avatar[color="pink"]:not([placeholder]) .matcha-avatar { color: #fff; } // 4.95:1 AA
289
- .theme-default-light matcha-avatar[color="teal"]:not([placeholder]) .matcha-avatar { color: #fff; } // 5.32:1 AA
290
- .theme-default-light matcha-avatar[color="purple"]:not([placeholder]) .matcha-avatar { color: #fff; } // 6.30:1 AA
291
- .theme-default-light matcha-avatar[color="orange"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 4.59:1 AA
292
- .theme-default-light matcha-avatar[color="yellow"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 8.52:1 AAA
293
- .theme-default-light matcha-avatar[color="neutral"]:not([placeholder]) .matcha-avatar { color: #fff; } // icon-default #5f656b vs #fff = 5.18:1 AA
294
-
295
- // Dark mode — todos os bgs ficam lighter (#54c5f7, #e46291, #4fb7ad, etc).
296
- // Texto branco falha em todos. Texto dark funciona em todos.
297
- .theme-default-dark matcha-avatar[color="light-blue"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 8.87:1 AAA
298
- .theme-default-dark matcha-avatar[color="pink"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 5.35:1 AA
299
- .theme-default-dark matcha-avatar[color="teal"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 7.22:1 AAA
300
- .theme-default-dark matcha-avatar[color="purple"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 4.98:1 AA
301
- .theme-default-dark matcha-avatar[color="orange"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 8.58:1 AAA
302
- .theme-default-dark matcha-avatar[color="yellow"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 11.94:1 AAA
303
- .theme-default-dark matcha-avatar[color="neutral"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // icon-default #9aa0a6 vs #1a1a1a = 5.97:1 AA
304
-
305
- // ── Avatar Group — empilhamento horizontal com overlap + overflow "+N" ──────
306
- // Substitui a composição manual (SCSS local) feita nas telas. -10px de overlap
307
- // é um offset visual bespoke (não genérico) — mantido literal de propósito.
308
- .matcha-avatar-group {
309
- display: inline-flex;
310
- align-items: center;
311
-
312
- matcha-avatar {
313
- margin-left: -10px;
314
- border: var(--matcha-border-thin, 2px) solid var(--matcha-color-surface-card);
315
- border-radius: var(--matcha-radius-pill, 9999px);
316
-
317
- &:first-child {
318
- margin-left: 0;
319
- }
320
- }
321
-
322
- &__more {
323
- margin-left: var(--matcha-space-100, 8px);
324
- font-size: var(--matcha-text-sm, 12px);
325
- font-weight: var(--matcha-weight-semibold, 600);
326
- color: var(--matcha-color-text-secondary);
327
- }
328
- }
329
-
330
- // ── Screen reader only utility (visualmente oculto, lido por AT) ────────────
331
- .matcha-avatar-sr-only {
332
- position: absolute;
333
- width: 1px;
334
- height: 1px;
335
- padding: 0;
336
- margin: -1px;
337
- overflow: hidden;
338
- clip: rect(0, 0, 0, 0);
339
- white-space: nowrap;
340
- border: 0;
341
- }
342
-
343
- // ── Status indicator ────────────────────────────────────────────────────────
344
- // Cores estruturais (online/offline/busy) ficam fora do mixin pra renderizar
345
- // independente de classe de tema (`theme-default-light`, etc.). Tokens com
346
- // fallback hardcoded resolvem o caso de tema não inicializado.
347
-
348
- .matcha-avatar-status {
349
- position: absolute;
350
- bottom: 0;
351
- right: 0;
352
- border-radius: var(--matcha-radius-pill, 9999px);
353
- border: var(--matcha-border-thin, 2px) solid var(--matcha-color-surface-card, #fff);
354
- box-sizing: border-box;
355
-
356
- // Size scales with avatar — keyed off [size] do host, não classe.
357
- matcha-avatar[size="tiny"] & { width: var(--matcha-avatar-status-xs, 8px); height: var(--matcha-avatar-status-xs, 8px); }
358
- matcha-avatar[size="small"] & { width: var(--matcha-avatar-status-sm, 10px); height: var(--matcha-avatar-status-sm, 10px); }
359
- matcha-avatar[size="medium"] & { width: var(--matcha-avatar-status-md, 12px); height: var(--matcha-avatar-status-md, 12px); }
360
- matcha-avatar[size="large"] & { width: var(--matcha-avatar-status-lg, 14px); height: var(--matcha-avatar-status-lg, 14px); }
361
- matcha-avatar[size="huge"] & { width: var(--matcha-avatar-status-2xl, 18px); height: var(--matcha-avatar-status-2xl, 18px); }
362
- }
363
-
364
- // Cores estruturais — fallback hardcoded pra funcionar mesmo sem tema.
365
- matcha-avatar[status="online"] .matcha-avatar-status { background-color: var(--matcha-color-success, #16a34a); }
366
- matcha-avatar[status="offline"] .matcha-avatar-status { background-color: var(--matcha-color-text-placeholder, #9ca3af); }
367
- matcha-avatar[status="busy"] .matcha-avatar-status { background-color: var(--matcha-color-danger, #dc2626); }
368
-
369
- // ── Theme mixin ─────────────────────────────────────────────────────────────
370
-
371
- @mixin matcha-avatar-theme($theme) {
372
- matcha-avatar[disabled] .matcha-avatar,
373
- .matcha-avatar.color-disabled {
374
- background-color: var(--matcha-color-disabled-bg);
375
- color: var(--matcha-color-disabled-fg);
376
- }
377
-
378
- // Status border-color por tema (estrutural já resolve cores de fundo via tokens).
379
- .matcha-avatar-status {
380
- border-color: var(--matcha-color-surface-card);
381
- }
382
- }
383
-
384
- // =============================================================================
385
- // A11y / modernity media queries
386
- // =============================================================================
387
-
388
- // Forced colors (Windows High Contrast) — bg colors podem virar invisíveis,
389
- // usar SelectedItem/Highlight pros estados, CanvasText/Canvas pra borders.
390
- @media (forced-colors: active) {
391
- .matcha-avatar {
392
- border: 1px solid CanvasText;
393
- }
394
-
395
- matcha-avatar[disabled] .matcha-avatar,
396
- .matcha-avatar.color-disabled {
397
- opacity: 0.5;
398
- border-color: GrayText;
399
- }
400
-
401
- // Status dot — em high-contrast as 3 cores ficam idênticas. Compensamos
402
- // com pattern visual: online=fill, offline=outline, busy=outline duplo.
403
- .matcha-avatar-status {
404
- background: SelectedItem !important;
405
- border: 2px solid Canvas !important;
406
- }
407
-
408
- matcha-avatar[status="offline"] .matcha-avatar-status {
409
- background: Canvas !important;
410
- border: 2px solid CanvasText !important;
411
- }
412
-
413
- matcha-avatar[status="busy"] .matcha-avatar-status {
414
- background: SelectedItem !important;
415
- box-shadow: 0 0 0 2px Canvas, 0 0 0 4px CanvasText;
416
- }
417
- }
418
-
419
- // Reduced motion — mata todas transitions/animations.
420
- @media (prefers-reduced-motion: reduce) {
421
- .matcha-avatar,
422
- .matcha-avatar-status {
423
- transition: none !important;
424
- animation: none !important;
425
- }
426
- }
1
+ // =============================================================================
2
+ // matcha-avatar.scss — Avatar component (photo, initials, placeholder + status)
3
+ // Aligned with Figma Avatar/Matcha: XS(24) SM(32) MD(40) LG(56) XL(80) 2XL(96)
4
+ //
5
+ // Estado visual (size/color/status/disabled/placeholder) é selecionado por
6
+ // ATRIBUTO no host (`matcha-avatar[size="medium"]`), não por classe — mesmo
7
+ // padrão já usado pelo `ring` abaixo e pelo `outline`/`link` do matcha-button.
8
+ // A classe `.matcha-avatar` na bolinha interna é só identidade estrutural.
9
+ // =============================================================================
10
+
11
+ // ── Structural (outside mixin) ──────────────────────────────────────────────
12
+
13
+ // Host — SEMPRE inline-flex, incondicional (não depende de haver conteúdo
14
+ // projetado). Com zero filhos em matcha-avatar-name/-caption/slot genérico,
15
+ // um flex container de um único item (a bolinha) renderiza idêntico a um
16
+ // avatar bare de hoje — não precisa de @ContentChild pra alternar layout.
17
+ matcha-avatar {
18
+ display: inline-flex;
19
+ align-items: center;
20
+ gap: var(--matcha-space-100, 8px);
21
+
22
+ &[orientation="stacked"] {
23
+ flex-direction: column;
24
+ text-align: center;
25
+ }
26
+ }
27
+
28
+ .matcha-avatar-text {
29
+ display: flex;
30
+ flex-direction: column;
31
+ min-width: 0;
32
+ }
33
+
34
+ matcha-avatar-name {
35
+ display: block;
36
+ color: var(--matcha-color-text-primary);
37
+ font-weight: var(--matcha-weight-medium, 500);
38
+ overflow: hidden;
39
+ text-overflow: ellipsis;
40
+ white-space: nowrap;
41
+ }
42
+
43
+ matcha-avatar-caption {
44
+ display: block;
45
+ color: var(--matcha-color-text-muted);
46
+ font-weight: var(--matcha-weight-regular, 400);
47
+ font-variant-numeric: tabular-nums;
48
+ overflow: hidden;
49
+ text-overflow: ellipsis;
50
+ white-space: nowrap;
51
+ }
52
+
53
+ .matcha-avatar {
54
+ display: inline-flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ position: relative;
58
+ // SEM overflow:hidden — o status indicator fica no canto fora do círculo
59
+ // visível e seria cortado. A <img> com border-radius inherit já se arredonda
60
+ // sozinha; SVG e Initials ficam dentro dos bounds.
61
+ border-radius: var(--matcha-radius-pill, 9999px);
62
+
63
+ font-weight: var(--matcha-weight-medium, 500);
64
+ user-select: none;
65
+ flex-shrink: 0;
66
+ }
67
+
68
+ // =============================================================================
69
+ // Ring colored (additive) — controlado pelo [ring] @Input do component.
70
+ // 2px solid + halo alpha externo. Não ocupa layout (box-shadow puro).
71
+ //
72
+ // Aplicado no .matcha-avatar INNER (não no host) porque o inner é quem tem
73
+ // width/height/border-radius:pill — box-shadow segue o radius desse elemento
74
+ // e renderiza circular. No host (inline default) sairia retangular.
75
+ //
76
+ // Os 6 tokens semânticos resolvem inteiro aqui via seletor de atributo — var()
77
+ // direto, sem custom property nem lookup no componente. Halo (glow externo) só
78
+ // em accent/success/warn/danger; primary/neutral só têm o anel sólido. Cor
79
+ // literal (hex/rgb/var arbitrário) é o ÚNICO caso que passa pela custom
80
+ // property --matcha-avatar-ring-color (não dá pra enumerar seletor de atributo
81
+ // pra valor arbitrário) — branch de fallback no final, sem halo.
82
+ // =============================================================================
83
+ matcha-avatar[ring="accent"] .matcha-avatar {
84
+ box-shadow:
85
+ 0 0 0 2px transparent,
86
+ 0 0 0 3px var(--matcha-color-accent),
87
+ 0 0 0 5px var(--matcha-color-accent-alpha, rgba(0, 148, 0, 0.10));
88
+ }
89
+
90
+ matcha-avatar[ring="success"] .matcha-avatar {
91
+ box-shadow:
92
+ 0 0 0 2px transparent,
93
+ 0 0 0 3px var(--matcha-color-success),
94
+ 0 0 0 5px var(--matcha-color-success-alpha, rgba(22, 163, 74, 0.10));
95
+ }
96
+
97
+ matcha-avatar[ring="warn"] .matcha-avatar {
98
+ box-shadow:
99
+ 0 0 0 2px transparent,
100
+ 0 0 0 3px var(--matcha-color-warn),
101
+ 0 0 0 5px var(--matcha-color-warn-alpha, rgba(245, 158, 11, 0.10));
102
+ }
103
+
104
+ matcha-avatar[ring="danger"] .matcha-avatar {
105
+ box-shadow:
106
+ 0 0 0 2px transparent,
107
+ 0 0 0 3px var(--matcha-color-danger),
108
+ 0 0 0 5px var(--matcha-color-danger-alpha, rgba(239, 68, 68, 0.10));
109
+ }
110
+
111
+ matcha-avatar[ring="primary"] .matcha-avatar {
112
+ box-shadow:
113
+ 0 0 0 2px transparent,
114
+ 0 0 0 3px var(--matcha-color-primary);
115
+ }
116
+
117
+ matcha-avatar[ring="neutral"] .matcha-avatar {
118
+ box-shadow:
119
+ 0 0 0 2px transparent,
120
+ 0 0 0 3px var(--matcha-color-surface-border);
121
+ }
122
+
123
+ // Fallback — [ring] presente mas não é nenhum dos 6 tokens acima (cor literal).
124
+ matcha-avatar[ring]:not([ring="accent"]):not([ring="success"]):not([ring="warn"]):not([ring="danger"]):not([ring="primary"]):not([ring="neutral"]) .matcha-avatar {
125
+ box-shadow:
126
+ 0 0 0 2px transparent,
127
+ 0 0 0 3px var(--matcha-avatar-ring-color, currentColor);
128
+ }
129
+
130
+ // ── Sizes — Canonical 5-step scale: tiny 24 · small 40 · medium 56 · large 80 · huge 96.
131
+ // O setter do [size] já normaliza os apelidos abreviados (xs/sm/md/lg/xl/2xl) pro nome
132
+ // canônico antes de refletir o atributo — só precisa dos 5 branches aqui.
133
+ // NOTE: --matcha-avatar-* tokens ainda carregam os nomes abreviados legados; retierar pra
134
+ // tiny/small/medium/large/huge do lado Figma/DSV3 é trabalho separado (design-driven).
135
+ matcha-avatar[size="tiny"] .matcha-avatar {
136
+ width: var(--matcha-avatar-xs, 24px);
137
+ height: var(--matcha-avatar-xs, 24px);
138
+ font-size: var(--matcha-text-2xs, 10px);
139
+ line-height: 1;
140
+ }
141
+
142
+ matcha-avatar[size="small"] .matcha-avatar {
143
+ width: var(--matcha-avatar-md, 40px);
144
+ height: var(--matcha-avatar-md, 40px);
145
+ font-size: var(--matcha-text-md, 14px);
146
+ line-height: 1;
147
+ }
148
+
149
+ matcha-avatar[size="medium"] .matcha-avatar {
150
+ width: var(--matcha-avatar-lg, 56px);
151
+ height: var(--matcha-avatar-lg, 56px);
152
+ font-size: var(--matcha-text-2xl, 20px);
153
+ line-height: 1;
154
+ }
155
+
156
+ matcha-avatar[size="large"] .matcha-avatar {
157
+ width: var(--matcha-avatar-xl, 80px);
158
+ height: var(--matcha-avatar-xl, 80px);
159
+ font-size: var(--matcha-text-3xl, 24px);
160
+ line-height: 1;
161
+ }
162
+
163
+ matcha-avatar[size="huge"] .matcha-avatar {
164
+ width: var(--matcha-avatar-2xl, 96px);
165
+ height: var(--matcha-avatar-2xl, 96px);
166
+ font-size: var(--matcha-text-4xl, 32px);
167
+ line-height: 1;
168
+ }
169
+
170
+ // ── Tipografia de matcha-avatar-name/-caption por [size] — mesmo [size] que
171
+ // já governa a bolinha, sem input separado nem seletor de irmão.
172
+ matcha-avatar[size="tiny"] {
173
+ matcha-avatar-name { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
174
+ matcha-avatar-caption { font-size: var(--matcha-text-xs, 11px); line-height: var(--matcha-leading-xs, 14px); }
175
+ }
176
+ matcha-avatar[size="small"] {
177
+ matcha-avatar-name { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
178
+ matcha-avatar-caption { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
179
+ }
180
+ matcha-avatar[size="medium"] {
181
+ matcha-avatar-name { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
182
+ matcha-avatar-caption { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
183
+ }
184
+ matcha-avatar[size="large"] {
185
+ matcha-avatar-name { font-size: var(--matcha-text-xl, 18px); line-height: var(--matcha-leading-xl, 24px); }
186
+ matcha-avatar-caption { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
187
+ }
188
+ matcha-avatar[size="huge"] {
189
+ matcha-avatar-name { font-size: var(--matcha-text-title-lg, 20px); line-height: var(--matcha-leading-title-lg, 28px); }
190
+ matcha-avatar-caption { font-size: var(--matcha-text-xl, 18px); line-height: var(--matcha-leading-xl, 24px); }
191
+ }
192
+
193
+ // ── Stacked (hero/profile header) — tipografia maior, negrito, centralizada.
194
+ matcha-avatar[orientation="stacked"] {
195
+ &[size="tiny"], &[size="small"] {
196
+ matcha-avatar-name { font-size: var(--matcha-text-title-sm, 16px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-sm, 22px); }
197
+ matcha-avatar-caption { font-size: var(--matcha-text-sm, 12px); line-height: var(--matcha-leading-sm, 16px); }
198
+ }
199
+ &[size="medium"], &[size="large"] {
200
+ matcha-avatar-name { font-size: var(--matcha-text-title-md, 18px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-md, 24px); }
201
+ matcha-avatar-caption { font-size: var(--matcha-text-md, 14px); line-height: var(--matcha-leading-md, 20px); }
202
+ }
203
+ &[size="huge"] {
204
+ matcha-avatar-name { font-size: var(--matcha-text-title-lg, 20px); font-weight: var(--matcha-weight-bold, 700); line-height: var(--matcha-leading-title-lg, 28px); }
205
+ matcha-avatar-caption { font-size: var(--matcha-text-lg, 16px); line-height: var(--matcha-leading-lg, 24px); }
206
+ }
207
+ }
208
+
209
+ .matcha-avatar {
210
+ // ── Image ──
211
+ .matcha-avatar-image {
212
+ width: 100%;
213
+ height: 100%;
214
+ object-fit: cover;
215
+ border-radius: inherit;
216
+ }
217
+
218
+ // ── Initials ──
219
+ .matcha-avatar-initials {
220
+ font-weight: var(--matcha-weight-medium, 500);
221
+ text-transform: uppercase;
222
+ letter-spacing: var(--matcha-letter-spacing-wide, 0.5px);
223
+ }
224
+
225
+ // ── Placeholder icon ──
226
+ .matcha-avatar-icon {
227
+ width: 100%;
228
+ height: 100%;
229
+ }
230
+ }
231
+
232
+ // ── Disabled ─────────────────────────────────────────────────────────────────
233
+ // `.color-disabled` preservado como gatilho manual alternativo (pré-existente,
234
+ // não gerido pelo componente) — `[disabled]` é o gatilho canônico hoje.
235
+ matcha-avatar[disabled] .matcha-avatar,
236
+ .matcha-avatar.color-disabled {
237
+ opacity: var(--matcha-opacity-disabled, 0.38);
238
+ pointer-events: none;
239
+ }
240
+
241
+ // ── Placeholder — vazado canônico (Figma matcha/avatar 5668:32088) ──────────
242
+ // SVG usa fill-rule=evenodd: disco preenchido com currentColor + silhueta vazada.
243
+ // `currentColor` do disco precisa ser a COR DA MARCA (não o contrast da .color class
244
+ // global, que é branco/preto). Override aqui força o token de palette.
245
+ matcha-avatar[placeholder] .matcha-avatar {
246
+ background: transparent !important;
247
+ }
248
+
249
+ matcha-avatar[color="primary"][placeholder] .matcha-avatar { color: var(--matcha-color-primary) !important; }
250
+ matcha-avatar[color="light-blue"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-light-blue) !important; }
251
+ matcha-avatar[color="pink"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-pink) !important; }
252
+ matcha-avatar[color="teal"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-teal) !important; }
253
+ matcha-avatar[color="purple"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-purple) !important; }
254
+ matcha-avatar[color="orange"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-orange) !important; }
255
+ matcha-avatar[color="yellow"][placeholder] .matcha-avatar { color: var(--matcha-color-palette-yellow) !important; }
256
+ matcha-avatar[color="neutral"][placeholder] .matcha-avatar { color: var(--matcha-color-icon-default) !important; }
257
+
258
+ // Neutral em Initials — cinza canônico Figma (icon-default).
259
+ matcha-avatar[color="neutral"]:not([placeholder]) .matcha-avatar {
260
+ background: var(--matcha-color-icon-default);
261
+ }
262
+
263
+ // ── Initials — bg + fg por cor (primary semântico + 6 da palette Figma DSV3) ─
264
+ // O palette inverte por tema (light=tons saturados, dark=tons claros). text-primary
265
+ // também inverte (#1a1d21 light / #e8eaed dark). Combinar os dois → contraste péssimo
266
+ // em dark mode (1.2-2.9:1 FAIL). Por isso fg da palette é fixed-per-color, não token-based.
267
+ // `primary` é semântico — usa `--matcha-color-primary-contrast`, já resolvido por tema.
268
+ //
269
+ // Light mode: pink/teal/purple bg escuros → fg branco. light-blue/orange/yellow bg
270
+ // claros → fg preto (light-blue precisa #000 puro pra AA por 0.08).
271
+ // Dark mode: todos os bg ficam lighter → fg preto funciona em tudo (5-12:1).
272
+
273
+ matcha-avatar[color="primary"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-primary); }
274
+ matcha-avatar[color="light-blue"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-light-blue); }
275
+ matcha-avatar[color="pink"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-pink); }
276
+ matcha-avatar[color="teal"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-teal); }
277
+ matcha-avatar[color="purple"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-purple); }
278
+ matcha-avatar[color="orange"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-orange); }
279
+ matcha-avatar[color="yellow"]:not([placeholder]) .matcha-avatar { background: var(--matcha-color-palette-yellow); }
280
+
281
+ matcha-avatar[color="primary"]:not([placeholder]) .matcha-avatar {
282
+ color: var(--matcha-color-primary-contrast);
283
+ }
284
+
285
+ // Light mode — bgs saturados (pink/teal/purple = escuros), fg branco passa AA.
286
+ // orange/yellow/light-blue = claros, fg precisa ser dark (#000 pra light-blue por margem).
287
+ .theme-default-light matcha-avatar[color="light-blue"]:not([placeholder]) .matcha-avatar { color: #000; } // 5.42:1 AA
288
+ .theme-default-light matcha-avatar[color="pink"]:not([placeholder]) .matcha-avatar { color: #fff; } // 4.95:1 AA
289
+ .theme-default-light matcha-avatar[color="teal"]:not([placeholder]) .matcha-avatar { color: #fff; } // 5.32:1 AA
290
+ .theme-default-light matcha-avatar[color="purple"]:not([placeholder]) .matcha-avatar { color: #fff; } // 6.30:1 AA
291
+ .theme-default-light matcha-avatar[color="orange"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 4.59:1 AA
292
+ .theme-default-light matcha-avatar[color="yellow"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 8.52:1 AAA
293
+ .theme-default-light matcha-avatar[color="neutral"]:not([placeholder]) .matcha-avatar { color: #fff; } // icon-default #5f656b vs #fff = 5.18:1 AA
294
+
295
+ // Dark mode — todos os bgs ficam lighter (#54c5f7, #e46291, #4fb7ad, etc).
296
+ // Texto branco falha em todos. Texto dark funciona em todos.
297
+ .theme-default-dark matcha-avatar[color="light-blue"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 8.87:1 AAA
298
+ .theme-default-dark matcha-avatar[color="pink"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 5.35:1 AA
299
+ .theme-default-dark matcha-avatar[color="teal"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 7.22:1 AAA
300
+ .theme-default-dark matcha-avatar[color="purple"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 4.98:1 AA
301
+ .theme-default-dark matcha-avatar[color="orange"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 8.58:1 AAA
302
+ .theme-default-dark matcha-avatar[color="yellow"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // 11.94:1 AAA
303
+ .theme-default-dark matcha-avatar[color="neutral"]:not([placeholder]) .matcha-avatar { color: #1a1a1a; } // icon-default #9aa0a6 vs #1a1a1a = 5.97:1 AA
304
+
305
+ // ── Avatar Group — empilhamento horizontal com overlap + overflow "+N" ──────
306
+ // Substitui a composição manual (SCSS local) feita nas telas. -10px de overlap
307
+ // é um offset visual bespoke (não genérico) — mantido literal de propósito.
308
+ .matcha-avatar-group {
309
+ display: inline-flex;
310
+ align-items: center;
311
+
312
+ matcha-avatar {
313
+ margin-left: -10px;
314
+ border: var(--matcha-border-thin, 2px) solid var(--matcha-color-surface-card);
315
+ border-radius: var(--matcha-radius-pill, 9999px);
316
+
317
+ &:first-child {
318
+ margin-left: 0;
319
+ }
320
+ }
321
+
322
+ &__more {
323
+ margin-left: var(--matcha-space-100, 8px);
324
+ font-size: var(--matcha-text-sm, 12px);
325
+ font-weight: var(--matcha-weight-semibold, 600);
326
+ color: var(--matcha-color-text-secondary);
327
+ }
328
+ }
329
+
330
+ // ── Screen reader only utility (visualmente oculto, lido por AT) ────────────
331
+ .matcha-avatar-sr-only {
332
+ position: absolute;
333
+ width: 1px;
334
+ height: 1px;
335
+ padding: 0;
336
+ margin: -1px;
337
+ overflow: hidden;
338
+ clip: rect(0, 0, 0, 0);
339
+ white-space: nowrap;
340
+ border: 0;
341
+ }
342
+
343
+ // ── Status indicator ────────────────────────────────────────────────────────
344
+ // Cores estruturais (online/offline/busy) ficam fora do mixin pra renderizar
345
+ // independente de classe de tema (`theme-default-light`, etc.). Tokens com
346
+ // fallback hardcoded resolvem o caso de tema não inicializado.
347
+
348
+ .matcha-avatar-status {
349
+ position: absolute;
350
+ bottom: 0;
351
+ right: 0;
352
+ border-radius: var(--matcha-radius-pill, 9999px);
353
+ border: var(--matcha-border-thin, 2px) solid var(--matcha-color-surface-card, #fff);
354
+ box-sizing: border-box;
355
+
356
+ // Size scales with avatar — keyed off [size] do host, não classe.
357
+ matcha-avatar[size="tiny"] & { width: var(--matcha-avatar-status-xs, 8px); height: var(--matcha-avatar-status-xs, 8px); }
358
+ matcha-avatar[size="small"] & { width: var(--matcha-avatar-status-sm, 10px); height: var(--matcha-avatar-status-sm, 10px); }
359
+ matcha-avatar[size="medium"] & { width: var(--matcha-avatar-status-md, 12px); height: var(--matcha-avatar-status-md, 12px); }
360
+ matcha-avatar[size="large"] & { width: var(--matcha-avatar-status-lg, 14px); height: var(--matcha-avatar-status-lg, 14px); }
361
+ matcha-avatar[size="huge"] & { width: var(--matcha-avatar-status-2xl, 18px); height: var(--matcha-avatar-status-2xl, 18px); }
362
+ }
363
+
364
+ // Cores estruturais — fallback hardcoded pra funcionar mesmo sem tema.
365
+ matcha-avatar[status="online"] .matcha-avatar-status { background-color: var(--matcha-color-success, #16a34a); }
366
+ matcha-avatar[status="offline"] .matcha-avatar-status { background-color: var(--matcha-color-text-placeholder, #9ca3af); }
367
+ matcha-avatar[status="busy"] .matcha-avatar-status { background-color: var(--matcha-color-danger, #dc2626); }
368
+
369
+ // ── Theme mixin ─────────────────────────────────────────────────────────────
370
+
371
+ @mixin matcha-avatar-theme($theme) {
372
+ matcha-avatar[disabled] .matcha-avatar,
373
+ .matcha-avatar.color-disabled {
374
+ background-color: var(--matcha-color-disabled-bg);
375
+ color: var(--matcha-color-disabled-fg);
376
+ }
377
+
378
+ // Status border-color por tema (estrutural já resolve cores de fundo via tokens).
379
+ .matcha-avatar-status {
380
+ border-color: var(--matcha-color-surface-card);
381
+ }
382
+ }
383
+
384
+ // =============================================================================
385
+ // A11y / modernity media queries
386
+ // =============================================================================
387
+
388
+ // Forced colors (Windows High Contrast) — bg colors podem virar invisíveis,
389
+ // usar SelectedItem/Highlight pros estados, CanvasText/Canvas pra borders.
390
+ @media (forced-colors: active) {
391
+ .matcha-avatar {
392
+ border: 1px solid CanvasText;
393
+ }
394
+
395
+ matcha-avatar[disabled] .matcha-avatar,
396
+ .matcha-avatar.color-disabled {
397
+ opacity: 0.5;
398
+ border-color: GrayText;
399
+ }
400
+
401
+ // Status dot — em high-contrast as 3 cores ficam idênticas. Compensamos
402
+ // com pattern visual: online=fill, offline=outline, busy=outline duplo.
403
+ .matcha-avatar-status {
404
+ background: SelectedItem !important;
405
+ border: 2px solid Canvas !important;
406
+ }
407
+
408
+ matcha-avatar[status="offline"] .matcha-avatar-status {
409
+ background: Canvas !important;
410
+ border: 2px solid CanvasText !important;
411
+ }
412
+
413
+ matcha-avatar[status="busy"] .matcha-avatar-status {
414
+ background: SelectedItem !important;
415
+ box-shadow: 0 0 0 2px Canvas, 0 0 0 4px CanvasText;
416
+ }
417
+ }
418
+
419
+ // Reduced motion — mata todas transitions/animations.
420
+ @media (prefers-reduced-motion: reduce) {
421
+ .matcha-avatar,
422
+ .matcha-avatar-status {
423
+ transition: none !important;
424
+ animation: none !important;
425
+ }
426
+ }