@inchurch/matcha-theme 22.28.4 → 22.29.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.
@@ -181,6 +181,11 @@ $-matcha-required-seeds: (surface-bg, surface, text-primary, accent, primary, su
181
181
  $derived: map.merge($derived, (
182
182
  accent-2: $accent-2,
183
183
  accent-2-contrast: matcha-text-on($accent-2),
184
+ // Espelha accent-text-on (linha ~168): mesmo cálculo do contrast, mas com
185
+ // nome dedicado a foreground de TEXTO — na rota de tokens estáticos os dois
186
+ // divergem (o -contrast lá é branco fixo, 1:1 Figma), então quem quer texto
187
+ // legível deve mirar text-on nas duas rotas.
188
+ accent-2-text-on: matcha-text-on($accent-2),
184
189
  accent-2-alpha: rgba($accent-2, .1),
185
190
  accent-2-surface: color.mix($accent-2, $surface-bg, 14%),
186
191
  ));
@@ -408,8 +408,10 @@ matcha-button-toggle {
408
408
  width: 100%;
409
409
 
410
410
  // Children flex-share — each button takes equal width across the row.
411
- // SEM min-width: 0 o botão nunca encolhe abaixo do conteúdo
412
- // (min-content); quando nem isso cabe, o overflow-x do grupo rola.
411
+ // O piso de encolhimento é o `min-width` do size do próprio botão
412
+ // (matcha-buttons.scss) NÃO o min-content: o botão tem
413
+ // `overflow: hidden`, o que anula a automatic minimum size do
414
+ // flexbox. Quando nem esse piso cabe, o overflow-x do grupo rola.
413
415
  > button[matcha-button],
414
416
  > a[matcha-button] {
415
417
  flex: 1 1 0;
@@ -47,6 +47,18 @@
47
47
  }
48
48
 
49
49
  // ── Size classes (responsive, aligned with Figma XS/SM/MD/LG/XL) ────────────
50
+ //
51
+ // Cada size define `min-width` igual à sua `height`: o botão nunca fica mais
52
+ // estreito que alto. Sem esse piso a largura é só `padding + conteúdo`, e um
53
+ // label curto ("OK", "X") vira um retângulo VERTICAL — no XS, 23×28. Com o
54
+ // piso o pior caso é um quadrado, com o conteúdo centrado pelo
55
+ // `justify-content: center` do bloco estrutural. Label longo nunca atinge o
56
+ // piso, então nada muda onde já estava certo.
57
+ //
58
+ // Efeito colateral desejado em flex container: o botão tem `overflow: hidden`,
59
+ // o que já anula o `min-width: auto` (a automatic minimum size do flexbox só
60
+ // vale para item com `overflow: visible`) — ou seja, hoje ele encolhe até ~0 e
61
+ // corta o label. O piso troca esse colapso por um mínimo quadrado.
50
62
 
51
63
  @mixin generate-matcha-button-size-classes($helper-breakpoints) {
52
64
  @each $breakpoint, $materialBreakpoint in $helper-breakpoints {
@@ -62,6 +74,7 @@
62
74
  line-height: var(--matcha-leading-p-tiny, 14px);
63
75
  letter-spacing: var(--matcha-letter-spacing-caption, 0.3px);
64
76
  height: 28px;
77
+ min-width: 28px;
65
78
  gap: var(--matcha-space-025, 2px);
66
79
  }
67
80
 
@@ -73,6 +86,7 @@
73
86
  font-weight: var(--matcha-weight-medium, 500);
74
87
  line-height: var(--matcha-leading-label-sm, 19px);
75
88
  height: 32px;
89
+ min-width: 32px;
76
90
  gap: var(--matcha-space-050, 4px);
77
91
  }
78
92
 
@@ -84,6 +98,7 @@
84
98
  font-weight: var(--matcha-weight-medium, 500);
85
99
  line-height: var(--matcha-leading-md, 20px);
86
100
  height: 40px;
101
+ min-width: 40px;
87
102
  gap: var(--matcha-space-100, 8px);
88
103
  }
89
104
 
@@ -95,6 +110,7 @@
95
110
  font-weight: var(--matcha-weight-semibold, 600);
96
111
  line-height: var(--matcha-leading-label-lg, 22px);
97
112
  height: 48px;
113
+ min-width: 48px;
98
114
  gap: var(--matcha-space-100, 8px);
99
115
  }
100
116
 
@@ -106,6 +122,7 @@
106
122
  font-weight: var(--matcha-weight-semibold, 600);
107
123
  line-height: var(--matcha-leading-label-lg, 22px);
108
124
  height: 56px;
125
+ min-width: 56px;
109
126
  gap: var(--matcha-space-100, 8px);
110
127
  }
111
128
  }
@@ -126,6 +143,7 @@ a[matcha-link] {
126
143
  font-weight: var(--matcha-weight-medium, 500);
127
144
  font-family: inherit;
128
145
  height: px-to-rem(40px); // default MD; overridden by size attribute selectors
146
+ min-width: px-to-rem(40px); // piso quadrado do default MD; ver mixin de sizes
129
147
  appearance: auto;
130
148
  text-rendering: auto;
131
149
  letter-spacing: var(--matcha-letter-spacing-button, 0.2px);
@@ -245,6 +263,14 @@ a[matcha-link] {
245
263
  background: transparent;
246
264
  }
247
265
 
266
+ // Link legado é texto inline (padding 0) — o piso quadrado do size viraria
267
+ // espaço morto clicável em volta do label, então cai aqui.
268
+ // O `:not([outline])` é deliberado: o combo [outline][link] é um botão com
269
+ // borda e padding real (bloco acima), esse MANTÉM o piso.
270
+ &[link]:not([link="false"]):not([outline]) {
271
+ min-width: 0;
272
+ }
273
+
248
274
  // ── matcha-link specific (Figma spec 16914:500) ──
249
275
  // SM=11/14 Regular letter 0.3 · MD=14/20 Medium · LG=16/22 SemiBold
250
276
  // Hover/Active → underline automático. Underline=true → permanente.
@@ -253,6 +279,7 @@ a[matcha-link] {
253
279
  height: auto;
254
280
  min-height: 0;
255
281
  max-height: none;
282
+ min-width: 0; // texto inline não tem piso quadrado (ver mixin de sizes)
256
283
  padding: 0;
257
284
  background: transparent;
258
285
  border-radius: 0;
@@ -25,10 +25,21 @@
25
25
  // Default fill = accent
26
26
  --matcha-progress-fill: var(--matcha-color-accent);
27
27
 
28
+ // Foreground do label inline, em duas alturas:
29
+ // • on-fill → sobre a barra preenchida. Cada semântica já tem o seu par
30
+ // `<nome>-contrast` ("o foreground correto sobre esta cor"),
31
+ // então não há contraste calculado à mão em lugar nenhum.
32
+ // • on-track → sobre o rail não preenchido (disabled-bg).
33
+ // O default accent-contrast resolve pra rgba(0,0,0,.87) nos dois modos — o
34
+ // mesmo valor que estava cravado antes, então o caso default não muda de cor.
35
+ --matcha-progress-label-on-fill: var(--matcha-color-accent-contrast);
36
+ --matcha-progress-label-on-track: var(--matcha-color-fg);
37
+
28
38
  // Bind por color attr → CSS var (mesma estratégia do slider/spinner)
29
39
  @each $name, $fn in $semantic-colors {
30
40
  &[color="#{$name}"] {
31
41
  --matcha-progress-fill: var(--matcha-color-#{$name});
42
+ --matcha-progress-label-on-fill: var(--matcha-color-#{$name}-contrast);
32
43
  }
33
44
  }
34
45
  }
@@ -62,23 +73,48 @@ matcha-progress-bar {
62
73
  overflow: hidden;
63
74
  }
64
75
 
65
- // Fill determinate (standard + informative)
76
+ // Fill determinate (standard + informative).
77
+ // position/z-index colocam o fill ENTRE os dois labels (bg z-1 · fill z-2 · fg z-3),
78
+ // que é o que faz o fill opaco mascarar o label de trás no trecho preenchido.
66
79
  .progress-fill {
67
- display: flex;
68
- align-items: center;
80
+ position: relative;
81
+ z-index: 2;
69
82
  height: 100%;
70
83
  background-color: var(--matcha-progress-fill);
71
84
  border-radius: var(--matcha-radius-sm, 2px);
72
85
  transition: width var(--matcha-duration-fast, 200ms) ease;
73
86
  }
74
87
 
75
- // Inline label (standard sm/md)
76
- .progress-fill__label {
88
+ // ── Inline label (standard sm/md) ──────────────────────────────────────
89
+ // Base comum aos dois labels. Ambos cobrem o track inteiro (inset: 0), então
90
+ // ficam alinhados pixel a pixel e a única diferença entre eles é cor + clip.
91
+ // Se a tipografia divergir entre os dois, o recorte desalinha e aparece degrau
92
+ // na borda do fill — por isso size/weight moram num seletor só (blocos de size
93
+ // abaixo miram .progress-text, nunca um dos dois isolado).
94
+ .progress-text {
95
+ position: absolute;
96
+ inset: 0;
97
+ display: flex;
98
+ align-items: center;
77
99
  padding-left: var(--matcha-space-100, 8px);
78
100
  font-family: var(--matcha-font-family);
79
- // Figma: text inverse/escuro sobre fill claro (accent é claro em dark mode)
80
- color: rgba(0, 0, 0, 0.87);
81
101
  white-space: nowrap;
102
+ pointer-events: none;
103
+ }
104
+
105
+ // Trecho NÃO preenchido: atrás do fill, cor que contrasta com o track.
106
+ .progress-text-bg {
107
+ z-index: 1;
108
+ color: var(--matcha-progress-label-on-track);
109
+ }
110
+
111
+ // Trecho preenchido: na frente do fill, cor que contrasta com o fill.
112
+ // clip-path recorta na largura exata do progresso; a transition acompanha
113
+ // a mesma duração da width do fill pra recorte e barra andarem juntos.
114
+ .progress-text-fg {
115
+ z-index: 3;
116
+ color: var(--matcha-progress-label-on-fill);
117
+ transition: clip-path var(--matcha-duration-fast, 200ms) ease;
82
118
  }
83
119
 
84
120
  // Indeterminate animation (standard, sem progress) — Material-style dual-scan.
@@ -126,7 +162,7 @@ matcha-progress-bar {
126
162
  &[size="sm"], &[size="small"] {
127
163
  .progress { height: var(--matcha-space-200, 16px); border-radius: var(--matcha-radius-md, 4px); }
128
164
  .progress-fill { border-radius: var(--matcha-radius-md, 4px); }
129
- .progress-fill__label {
165
+ .progress-text {
130
166
  font-size: var(--matcha-text-p-tiny, 11px);
131
167
  font-weight: var(--matcha-weight-regular, 400);
132
168
  line-height: var(--matcha-leading-p-tiny, 14px);
@@ -136,7 +172,7 @@ matcha-progress-bar {
136
172
  &[size="md"], &[size="medium"] {
137
173
  .progress { height: var(--matcha-space-400, 32px); border-radius: var(--matcha-radius-md, 4px); }
138
174
  .progress-fill { border-radius: var(--matcha-radius-md, 4px); }
139
- .progress-fill__label {
175
+ .progress-text {
140
176
  font-size: var(--matcha-text-label-md, 14px);
141
177
  font-weight: var(--matcha-weight-medium, 500);
142
178
  line-height: var(--matcha-leading-label-md, 20px);
@@ -289,6 +325,7 @@ matcha-progress-bar[type="segmented"] {
289
325
  @media (prefers-reduced-motion: reduce) {
290
326
  matcha-progress-bar {
291
327
  .progress-fill { transition: none; }
328
+ .progress-text-fg { transition: none; }
292
329
  .progress-indeterminate,
293
330
  .progress-indeterminate::before,
294
331
  .progress-indeterminate::after { animation: none; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inchurch/matcha-theme",
3
- "version": "22.28.4",
3
+ "version": "22.29.0",
4
4
  "description": "Themes for matcha-design-system",
5
5
  "main": "main.scss",
6
6
  "scripts": {
@@ -154,7 +154,15 @@ $matcha-color-tokens: (
154
154
  // ── Accent Secondary (teal — 4 tokens Figma matcha/color/accent-2/*) ─────
155
155
  // Light #00796b (teal-700) | Dark #4fb7ad (teal-light)
156
156
  accent-2: (light: #00796b, dark: #4fb7ad),
157
+ // accent-2-contrast 1:1 Figma DSV3: {common.white} em AMBOS os modos. Serve no Light
158
+ // (#00796b + branco = 5.3:1), mas NÃO no Dark: accent-2 clareia pra #4fb7ad e o branco
159
+ // cai pra ~2.3:1 (reprova AA). Mesma situação do accent/contrast — por isso a saída é a
160
+ // mesma: um accent-2/text-on dedicado a FOREGROUND DE TEXTO, que inverte por modo.
161
+ // O -contrast fica intacto, fiel ao Figma (drift = o Figma vence).
157
162
  accent-2-contrast: (light: #ffffff, dark: #ffffff),
163
+ // Espelha accent-text-on. Valores batem com matcha-text-on() (rota whitelabel):
164
+ // yiq(#00796b)=83 → #ffffff · yiq(#4fb7ad)=151 → #1a1d21.
165
+ accent-2-text-on: (light: #ffffff, dark: #1a1d21),
158
166
  accent-2-alpha: (light: rgba(#00796b, .10), dark: rgba(#4fb7ad, .12)),
159
167
  accent-2-surface: (light: #e0f0ee, dark: #1d332e),
160
168
 
@@ -215,7 +223,7 @@ $matcha-color-tokens: (
215
223
  info-surface-hover: (light: #ebeefa, dark: #0f141e),
216
224
  info-surface-pressed: (light: #d8def5, dark: #131f31),
217
225
 
218
- // ── Palette (18) — matcha/color/palette/* ────────────────────────────────
226
+ // ── Palette (19) — matcha/color/palette/* ────────────────────────────────
219
227
  palette-teal: (light: #00796b, dark: #4fb7ad),
220
228
  palette-teal-light: (light: #4fb7ad, dark: #009688),
221
229
  palette-teal-alpha: (light: rgba(#00796b, .1), dark: rgba(#4fb7ad, .1)),
@@ -225,6 +233,12 @@ $matcha-color-tokens: (
225
233
  palette-purple: (light: #9c27b0, dark: #bb6ac8),
226
234
  palette-purple-light: (light: #bb6ac8, dark: #9c27b0),
227
235
  palette-purple-alpha: (light: rgba(#9c27b0, .1), dark: rgba(#bb6ac8, .1)),
236
+ // Contraste (texto sobre a cor sólida), mesmo critério dos chart-series-*-contrast.
237
+ // Light #9c27b0 + branco = 5.6:1 · Dark #bb6ac8 + preto .87 = ~7:1 (AA nos 2 modos).
238
+ // Só o purple tem o par por enquanto: é a única cor da paleta usada como fill de
239
+ // superfície com texto em cima (barra de Jornada do dashboard). As outras ganham o
240
+ // seu quando aparecer o caso — não gerar 6 pares especulativos.
241
+ palette-purple-contrast: (light: #ffffff, dark: rgba(0, 0, 0, .87)),
228
242
  palette-pink: (light: #d81b60, dark: #e46291),
229
243
  palette-pink-light: (light: #e46291, dark: #d81b60),
230
244
  palette-pink-alpha: (light: rgba(#d81b60, .1), dark: rgba(#e46291, .1)),