@aurea-uds/core 0.24.1 → 0.27.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/dist/aurea.css +219 -123
  2. package/package.json +1 -1
package/dist/aurea.css CHANGED
@@ -47,6 +47,7 @@
47
47
  --focus-width:2px;
48
48
  --focus-offset:2px;
49
49
  --opacity-disabled:0.5;
50
+ --shadow-sm:0 2px 4px rgba(0,0,0,0.04), 0 1px 2px rgba(0,0,0,0.06), 0 0 1px rgba(0,0,0,0.06);
50
51
  --shadow-md:0 16px 42px rgba(0,0,0,0.28);
51
52
  --shadow-lg:0 28px 80px rgba(0,0,0,0.42);
52
53
  --duration-fast:120ms;
@@ -129,53 +130,54 @@
129
130
  --tracking-widest:0.12em;
130
131
  }
131
132
  [data-theme="dark"]{
132
- --background:oklch(0.145 0 0);
133
- --foreground:oklch(0.985 0 0);
134
- --card:oklch(0.205 0 0);
135
- --card-foreground:oklch(0.985 0 0);
136
- --popover:oklch(0.205 0 0);
137
- --popover-foreground:oklch(0.985 0 0);
133
+ --background:#1f1f1f;
134
+ --foreground:#ffffff;
135
+ --card:#292929;
136
+ --card-foreground:#ffffff;
137
+ --popover:#292929;
138
+ --popover-foreground:#ffffff;
138
139
  --primary:var(--brand-yellow);
139
140
  --primary-foreground:var(--brand-yellow-foreground);
140
141
  --link:var(--brand-yellow);
141
142
  --link-hover:var(--brand-yellow);
142
- --secondary:oklch(0.274 0.006 286.033);
143
- --secondary-foreground:oklch(0.985 0 0);
144
- --muted:oklch(0.269 0 0);
145
- --muted-foreground:oklch(0.708 0 0);
146
- --accent:oklch(0.269 0 0);
147
- --accent-foreground:oklch(0.985 0 0);
148
- --destructive:oklch(0.704 0.191 22.216);
149
- --destructive-foreground:oklch(0.2 0.02 22);
150
- --border:oklch(1 0 0 / 0.1);
151
- --input:oklch(1 0 0 / 0.15);
152
- --ring:oklch(0.556 0 0);
143
+ --secondary:#333333;
144
+ --secondary-foreground:#ffffff;
145
+ --muted:#333333;
146
+ --muted-foreground:#adadad;
147
+ --accent:#333333;
148
+ --accent-foreground:#ffffff;
149
+ --destructive:#c50f1f;
150
+ --destructive-foreground:#ffffff;
151
+ --border:#525252;
152
+ --input:#525252;
153
+ --ring:#666666;
153
154
  --chart-1:oklch(0.809 0.105 251.813);
154
155
  --chart-2:oklch(0.623 0.214 259.815);
155
156
  --chart-3:oklch(0.546 0.245 262.881);
156
157
  --chart-4:oklch(0.488 0.243 264.376);
157
158
  --chart-5:oklch(0.424 0.199 265.638);
158
- --sidebar:oklch(0.205 0 0);
159
- --sidebar-foreground:oklch(0.985 0 0);
159
+ --sidebar:#292929;
160
+ --sidebar-foreground:#ffffff;
160
161
  --sidebar-primary:var(--brand-yellow);
161
162
  --sidebar-primary-foreground:var(--brand-yellow-foreground);
162
- --sidebar-accent:oklch(0.269 0 0);
163
- --sidebar-accent-foreground:oklch(0.985 0 0);
164
- --sidebar-border:oklch(1 0 0 / 0.1);
165
- --sidebar-ring:oklch(0.556 0 0);
163
+ --sidebar-accent:#333333;
164
+ --sidebar-accent-foreground:#ffffff;
165
+ --sidebar-border:#525252;
166
+ --sidebar-ring:#666666;
166
167
  --surface-1:var(--card);
167
168
  --surface-2:var(--secondary);
168
169
  --surface-3:var(--muted);
169
- --surface-inset:oklch(0.145 0 0);
170
- --surface-hover:oklch(0.3 0 0);
170
+ --surface-inset:#141414;
171
+ --surface-hover:#383838;
171
172
  --foreground-strong:var(--foreground);
172
- --subtle-foreground:oklch(0.76 0 0);
173
- --border-strong:oklch(0.58 0 0);
173
+ --subtle-foreground:#adadad;
174
+ --border-strong:#adadad;
174
175
  --field-bg:var(--muted);
175
- --overlay:oklch(0 0 0 / 0.74);
176
+ --overlay:oklch(0 0 0 / 0.5);
176
177
  --primary-hover:oklch(0.835 0.19 89);
177
178
  --primary-active:oklch(0.74 0.17 84);
178
- --secondary-hover:oklch(0.31 0.006 286.033);
179
+ --secondary-hover:#3d3d3d;
180
+ --segment:oklch(0.3964 0.01 285.93);
179
181
  --focus:var(--primary);
180
182
  --focus-strong:var(--primary);
181
183
  --primary-emphasis:var(--primary);
@@ -183,95 +185,131 @@
183
185
  --control-selected:var(--primary);
184
186
  --control-selected-foreground:var(--primary-foreground);
185
187
  --selection:oklch(0.795 0.184 86.047 / 0.22);
186
- --success-bg:oklch(0.42 0.11 150 / 0.36);
187
- --warning-bg:oklch(0.34 0.08 60 / 0.64);
188
- --danger-bg:oklch(0.32 0.1 22 / 0.62);
189
- --info-bg:oklch(0.29 0.08 260 / 0.62);
190
- --warning-400:var(--warning);
191
- --success:#42d392;
192
- --success-foreground:oklch(0.2 0.02 160);
193
- --success-hover:oklch(0.83 0.145 160);
194
- --info:#8ec5ff;
195
- --info-foreground:oklch(0.2 0.02 250);
196
- --info-hover:oklch(0.86 0.075 250);
197
- --warning:oklch(0.72 0.175 60);
198
- --warning-foreground:oklch(0.2 0.02 60);
199
- --warning-hover:oklch(0.78 0.16 60);
188
+ --success-bg:#052505;
189
+ --warning-bg:#4a1e04;
190
+ --danger-bg:#3b0509;
191
+ --info-bg:#002440;
192
+ --category-red:oklch(0.85 0.08 25);
193
+ --category-red-bg:oklch(0.28 0.07 25 / 0.62);
194
+ --category-orange:oklch(0.76 0.13 55);
195
+ --category-orange-bg:oklch(0.36 0.089 55 / 0.62);
196
+ --category-green:oklch(0.85 0.13 150);
197
+ --category-green-bg:oklch(0.28 0.07 150 / 0.62);
198
+ --category-teal:oklch(0.76 0.13 180);
199
+ --category-teal-bg:oklch(0.36 0.065 180 / 0.62);
200
+ --category-cyan:oklch(0.85 0.098 225);
201
+ --category-cyan-bg:oklch(0.28 0.053 225 / 0.62);
202
+ --category-blue:oklch(0.76 0.121 260);
203
+ --category-blue-bg:oklch(0.36 0.09 260 / 0.62);
204
+ --category-violet:oklch(0.85 0.086 300);
205
+ --category-violet-bg:oklch(0.28 0.07 300 / 0.62);
206
+ --category-pink:oklch(0.76 0.13 350);
207
+ --category-pink-bg:oklch(0.36 0.09 350 / 0.62);
208
+ --warning-400:#faa06b;
209
+ --success-400:#54b054;
210
+ --danger-400:#eeacb2;
211
+ --info-400:#5caae5;
212
+ --success:#107c10;
213
+ --success-foreground:#ffffff;
214
+ --success-hover:#0e700e;
215
+ --info:#0078d4;
216
+ --info-foreground:#ffffff;
217
+ --info-hover:#006cbf;
218
+ --warning:#f7630c;
219
+ --warning-foreground:#242424;
220
+ --warning-hover:#de590b;
200
221
  }
201
222
  [data-theme="light"]{
202
- --background:oklch(0.965 0 0);
203
- --foreground:oklch(0.145 0 0);
204
- --card:oklch(1 0 0);
205
- --card-foreground:oklch(0.145 0 0);
206
- --popover:oklch(1 0 0);
207
- --popover-foreground:oklch(0.145 0 0);
223
+ --background:#f5f5f5;
224
+ --foreground:#242424;
225
+ --card:#ffffff;
226
+ --card-foreground:#242424;
227
+ --popover:#ffffff;
228
+ --popover-foreground:#242424;
208
229
  --primary:var(--brand-yellow);
209
230
  --primary-foreground:var(--brand-yellow-foreground);
210
231
  --link:oklch(0.52 0.106 86.047);
211
232
  --link-hover:oklch(0.44 0.106 86.047);
212
- --secondary:oklch(0.94 0 0);
213
- --secondary-foreground:oklch(0.21 0.006 285.885);
233
+ --secondary:#ebebeb;
234
+ --secondary-foreground:#242424;
214
235
  --muted:var(--secondary);
215
- --muted-foreground:oklch(0.43 0 0);
236
+ --muted-foreground:#616161;
216
237
  --accent:var(--secondary);
217
- --accent-foreground:oklch(0.205 0 0);
218
- --destructive:oklch(0.577 0.245 27.325);
219
- --destructive-foreground:oklch(0.985 0 0);
220
- --border:oklch(0.89 0 0);
221
- --input:oklch(0.922 0 0);
222
- --ring:oklch(0.708 0 0);
238
+ --accent-foreground:#242424;
239
+ --destructive:#c50f1f;
240
+ --destructive-foreground:#ffffff;
241
+ --border:#e0e0e0;
242
+ --input:#e0e0e0;
243
+ --ring:#d1d1d1;
223
244
  --chart-1:oklch(0.809 0.105 251.813);
224
245
  --chart-2:oklch(0.623 0.214 259.815);
225
246
  --chart-3:oklch(0.546 0.245 262.881);
226
247
  --chart-4:oklch(0.488 0.243 264.376);
227
248
  --chart-5:oklch(0.424 0.199 265.638);
228
249
  --sidebar:var(--card);
229
- --sidebar-foreground:oklch(0.145 0 0);
250
+ --sidebar-foreground:#242424;
230
251
  --sidebar-primary:var(--primary-emphasis);
231
252
  --sidebar-primary-foreground:var(--brand-yellow-foreground);
232
253
  --sidebar-accent:var(--secondary);
233
- --sidebar-accent-foreground:oklch(0.205 0 0);
234
- --sidebar-border:oklch(0.89 0 0);
235
- --sidebar-ring:oklch(0.708 0 0);
254
+ --sidebar-accent-foreground:#242424;
255
+ --sidebar-border:#e0e0e0;
256
+ --sidebar-ring:#d1d1d1;
236
257
  --surface-1:var(--card);
237
258
  --surface-2:var(--secondary);
238
259
  --surface-3:var(--muted);
239
- --surface-inset:oklch(0.955 0 0);
240
- --surface-hover:oklch(0.925 0 0);
260
+ --surface-inset:#f0f0f0;
261
+ --surface-hover:#e6e6e6;
241
262
  --foreground-strong:var(--foreground);
242
- --subtle-foreground:oklch(0.43 0 0);
243
- --border-strong:oklch(0.56 0 0);
263
+ --subtle-foreground:#616161;
264
+ --border-strong:#616161;
244
265
  --field-bg:var(--muted);
245
- --overlay:oklch(0.145 0 0 / 0.4);
266
+ --overlay:oklch(0 0 0 / 0.4);
246
267
  --primary-hover:oklch(0.835 0.19 89);
247
268
  --primary-active:oklch(0.74 0.17 84);
248
269
  --secondary-hover:var(--surface-hover);
270
+ --segment:oklch(1 0 0);
249
271
  --focus:var(--primary);
250
272
  --focus-strong:var(--brand-yellow-foreground);
251
273
  --primary-emphasis:var(--brand-yellow-text);
252
274
  --primary-outline:var(--brand-yellow-text);
253
275
  --control-selected:var(--brand-yellow-foreground);
254
276
  --control-selected-foreground:oklch(0.985 0 0);
255
- --success-400:var(--success);
256
- --warning-400:var(--warning);
257
- --danger-400:#9f2330;
258
- --info-400:var(--info);
277
+ --success-400:#0e700e;
278
+ --warning-400:#8a3707;
279
+ --danger-400:#b10e1c;
280
+ --info-400:#006cbf;
259
281
  --oracle-300:var(--chart-4);
260
282
  --oracle-400:var(--chart-4);
261
283
  --selection:oklch(0.795 0.184 86.047 / 0.18);
262
- --success-bg:oklch(0.94 0.05 150);
263
- --warning-bg:oklch(0.95 0.06 61);
264
- --danger-bg:oklch(0.95 0.05 22);
265
- --info-bg:oklch(0.95 0.045 260);
266
- --success:#0f6b3e;
267
- --success-foreground:oklch(0.985 0 0);
268
- --success-hover:oklch(0.4 0.1 155);
269
- --info:#164f9d;
270
- --info-foreground:oklch(0.985 0 0);
271
- --info-hover:oklch(0.38 0.13 258);
272
- --warning:oklch(0.525 0.131 61);
273
- --warning-foreground:oklch(0.985 0 0);
274
- --warning-hover:oklch(0.47 0.115 61);
284
+ --success-bg:#f1faf1;
285
+ --warning-bg:#fff9f5;
286
+ --danger-bg:#fdf3f4;
287
+ --info-bg:#f3f9fd;
288
+ --category-red:oklch(0.52 0.15 25);
289
+ --category-red-bg:oklch(0.96 0.019 25);
290
+ --category-orange:oklch(0.47 0.115 55);
291
+ --category-orange-bg:oklch(0.925 0.044 55);
292
+ --category-green:oklch(0.52 0.141 150);
293
+ --category-green-bg:oklch(0.96 0.035 150);
294
+ --category-teal:oklch(0.47 0.084 180);
295
+ --category-teal-bg:oklch(0.925 0.055 180);
296
+ --category-cyan:oklch(0.52 0.097 225);
297
+ --category-cyan-bg:oklch(0.96 0.025 225);
298
+ --category-blue:oklch(0.47 0.15 260);
299
+ --category-blue-bg:oklch(0.925 0.035 260);
300
+ --category-violet:oklch(0.52 0.15 300);
301
+ --category-violet-bg:oklch(0.96 0.022 300);
302
+ --category-pink:oklch(0.47 0.15 350);
303
+ --category-pink-bg:oklch(0.925 0.044 350);
304
+ --success:#107c10;
305
+ --success-foreground:#ffffff;
306
+ --success-hover:#0e700e;
307
+ --info:#0078d4;
308
+ --info-foreground:#ffffff;
309
+ --info-hover:#006cbf;
310
+ --warning:#f7630c;
311
+ --warning-foreground:#242424;
312
+ --warning-hover:#de590b;
275
313
  }
276
314
  [data-brand="lory"][data-theme="dark"]{
277
315
  --background:oklch(0.16 0.018 250);
@@ -295,6 +333,7 @@
295
333
  --secondary:oklch(0.245 0.02 250);
296
334
  --secondary-foreground:oklch(0.96 0.006 250);
297
335
  --secondary-hover:oklch(0.28 0.02 250);
336
+ --segment:oklch(0.312 0.02 250);
298
337
  --muted:oklch(0.19 0.02 250);
299
338
  --muted-foreground:oklch(0.72 0.015 250);
300
339
  --subtle-foreground:oklch(0.58 0.016 250);
@@ -437,7 +476,17 @@ body { margin:0; background:var(--background); color:var(--foreground); font-fam
437
476
  ::selection { background:var(--selection); }
438
477
  button,input,textarea,select { font:inherit; }
439
478
  button,a,[role="button"],input,textarea,select { outline:none; }
440
- :focus-visible { outline:var(--focus-width) solid var(--focus-strong); outline-offset:var(--focus-offset); box-shadow:none; border-color:var(--focus-strong)!important; }
479
+ :focus-visible { outline:var(--focus-width) solid var(--focus-strong); outline-offset:var(--focus-offset); box-shadow:none; }
480
+ /* UMA LINHA SÓ (ADR-0059, 08/10/2026). O anel afastado, sozinho, é uma linha — mas na peça que tem
481
+ BORDA PRÓPRIA ele desenhava borda + vão + anel: duas linhas, em 39 peças medidas no catálogo. E a
482
+ regra de cima pintava TODA borda de amarelo com `!important`, o que dava uma segunda linha até no
483
+ botão de borda transparente, depois da transição. Agora só a peça com borda muda a borda: ela
484
+ passa para a cor do foco e o anel ENCOSTA nela, sem vão — uma faixa só, de borda + anel, como o
485
+ anel colado do campo da referência principal. A peça sem borda (o botão cheio, a aba) continua com
486
+ o vão: colado, o anel amarelo sumiria no botão amarelo.
487
+ Quem cobra que nenhuma peça ficou de fora é o catálogo inteiro, no navegador:
488
+ `tests/visual/foco-uma-linha.spec.ts`. */
489
+ :is(.input,.textarea,.select,.btn-outline,.btn-primary-outline,.btn-danger-outline,.media-control,.card,.code-block,.graph-node-body):focus-visible { outline-offset:0; border-color:var(--focus-strong); }
441
490
  button { color:inherit; }
442
491
  /* O link NÃO é `--primary`. Medido em 22/08/2026 com o axe e depois à mão: o amarelo da
443
492
  marca sobre o fundo do tema CLARO dá 1,73:1, e o AA de texto (WCAG 1.4.3) pede 4,5:1 —
@@ -803,7 +852,9 @@ img,svg { display:block; }
803
852
  /* O rótulo de grupo também sai da escala da LATERAL, pelo mesmo motivo: `--subtle-foreground` é
804
853
  apagado contra a página, e contra um painel escuro num tema claro ele some. Derivado do próprio
805
854
  `--sidebar-foreground` em vez de token novo — a lateral não publica um "muted" dela. */
806
- .sidebar-group-label { margin:var(--space-3) var(--space-3) var(--space-1); color:color-mix(in oklab, var(--sidebar-foreground) 62%, transparent); font-size:var(--text-xs); font-weight:var(--weight-medium); letter-spacing:var(--tracking-widest); text-transform:uppercase; }
855
+ /* 72% e não 62% desde a 0.27.0 (ADR-0061): com a letra da paleta nova (#242424, menos preta) os 62%
856
+ davam 4,4:1 sobre o branco — o axe pegou na varredura. 72% é o cinza de texto apagado da paleta. */
857
+ .sidebar-group-label { margin:var(--space-3) var(--space-3) var(--space-1); color:color-mix(in oklab, var(--sidebar-foreground) 72%, transparent); font-size:var(--text-xs); font-weight:var(--weight-medium); letter-spacing:var(--tracking-widest); text-transform:uppercase; }
807
858
  .sidebar-sub { padding-inline-start:var(--space-5); }
808
859
  /* RECOLHIDA — a lateral vira trilho de ícones. O rótulo NÃO some do DOM: o React troca a
809
860
  classe dele por `.sr-only`, então quem usa leitor de tela continua ouvindo o nome. Ícone
@@ -1245,11 +1296,11 @@ img,svg { display:block; }
1245
1296
  .btn-primary-outline:hover:not(:disabled) { --btn-bg:color-mix(in oklab, var(--primary) 14%, transparent); }
1246
1297
  .btn-primary-ghost { --btn-bg:transparent; --btn-fg:var(--primary); --btn-border:transparent; }
1247
1298
  .btn-primary-ghost:hover:not(:disabled) { --btn-bg:color-mix(in oklab, var(--primary) 14%, transparent); }
1248
- .btn-danger-outline { --btn-bg:transparent; --btn-fg:var(--destructive); --btn-border:var(--destructive); }
1299
+ .btn-danger-outline { --btn-bg:transparent; --btn-fg:var(--danger-400); --btn-border:var(--danger-400); }
1249
1300
  .btn-danger-outline:hover:not(:disabled):not([aria-disabled="true"]) { --btn-bg:color-mix(in oklab, var(--destructive) 14%, transparent); }
1250
- .btn-danger-ghost { --btn-bg:transparent; --btn-fg:var(--destructive); --btn-border:transparent; }
1301
+ .btn-danger-ghost { --btn-bg:transparent; --btn-fg:var(--danger-400); --btn-border:transparent; }
1251
1302
  .btn-danger-ghost:hover:not(:disabled):not([aria-disabled="true"]) { --btn-bg:color-mix(in oklab, var(--destructive) 14%, transparent); }
1252
- [data-theme="light"] .btn-danger-outline:where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *),[data-theme="light"] .btn-danger-ghost:where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *),[data-theme="light"] .btn-link-danger:where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *) { --btn-fg:color-mix(in oklab, var(--destructive) 62%, var(--foreground)); }
1303
+ [data-theme="light"] .btn-danger-outline:where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *),[data-theme="light"] .btn-danger-ghost:where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *),[data-theme="light"] .btn-link-danger:where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *) { --btn-fg:var(--danger-400); }
1253
1304
  /* A MESMA correção para a marca, que estava faltando. Medido em 21/08/2026 na varredura de AA
1254
1305
  da matriz de tom: `.btn-primary-outline` e `.btn-primary-ghost` pintavam o rótulo com
1255
1306
  `--primary` cru, e no tema claro isso dá **1.73:1** — reprovação grave, em componente
@@ -1269,7 +1320,7 @@ img,svg { display:block; }
1269
1320
  .btn-link:hover:not(:disabled):not([aria-disabled="true"]) { text-decoration-thickness:2px; }
1270
1321
  .btn-link-primary { --btn-fg:var(--primary); }
1271
1322
  [data-theme="light"] .btn-link-primary:where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *) { --btn-fg:color-mix(in oklab, var(--primary) 45%, var(--foreground)); }
1272
- .btn-link-danger { --btn-fg:var(--destructive); }
1323
+ .btn-link-danger { --btn-fg:var(--danger-400); }
1273
1324
  /* pressed entra na linguagem única de "selecionado" acima; só-ícone não leva o fio. */
1274
1325
  /* Kbd — a tecla que dispara a ação, dentro ou fora do botão. Peça própria, não decoração. */
1275
1326
  .kbd { display:inline-flex; align-items:center; justify-content:center; gap:2px; min-width:20px; height:20px; padding:0 6px; border:1px solid var(--border-strong); border-radius:var(--radius-sm); background:var(--secondary); color:var(--muted-foreground); font:500 11px/1 var(--font-code); }
@@ -1312,24 +1363,26 @@ img,svg { display:block; }
1312
1363
  .btn-solid.btn-tone-info:hover:not(:disabled) { --btn-bg:var(--info-hover); --btn-fg:var(--info-foreground); }
1313
1364
  .btn-solid.btn-tone-warning { --btn-bg:var(--warning); --btn-fg:var(--warning-foreground); --btn-border:transparent; }
1314
1365
  .btn-solid.btn-tone-warning:hover:not(:disabled) { --btn-bg:var(--warning-hover); --btn-fg:var(--warning-foreground); }
1315
- /* e o mesmo tom SEM caixa: contorno, fantasma, link e navegação. O token de tom já é
1316
- "esta cor, legível contra a superfície DESTE tema", então não há correção por tema aqui. */
1366
+ /* e o mesmo tom SEM caixa: contorno, fantasma, link e navegação. ⚠ Desde a 0.27.0 (ADR-0061) o
1367
+ token de tom (`--success`) é o FUNDO cheio — a mesma cor funda nos dois temas —, e não serve
1368
+ de letra no escuro. Letra, ícone, borda e barra sobre a superfície usam o par de letra
1369
+ (`--success-400`, `--info-400`, `--warning-400`, `--danger-400`), que cada tema ajusta. */
1317
1370
  .btn-tone-brand,.btn-tone-brand:hover:not(:disabled) { --btn-fg:var(--primary); }
1318
1371
  [data-theme="light"] .btn-tone-brand:where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *),[data-theme="light"] .btn-tone-brand:hover:not(:disabled):where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *) { --btn-fg:color-mix(in oklab, var(--primary) 45%, var(--foreground)); }
1319
1372
  .btn-outline.btn-tone-brand { --btn-border:var(--primary); }
1320
1373
  .btn-tone-brand:not(.btn-link):hover:not(:disabled) { --btn-bg:color-mix(in oklab, var(--primary) 14%, transparent); }
1321
- .btn-tone-danger,.btn-tone-danger:hover:not(:disabled) { --btn-fg:var(--destructive); }
1322
- [data-theme="light"] .btn-tone-danger:where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *),[data-theme="light"] .btn-tone-danger:hover:not(:disabled):where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *) { --btn-fg:color-mix(in oklab, var(--destructive) 62%, var(--foreground)); }
1323
- .btn-outline.btn-tone-danger { --btn-border:var(--destructive); }
1374
+ .btn-tone-danger,.btn-tone-danger:hover:not(:disabled) { --btn-fg:var(--danger-400); }
1375
+ [data-theme="light"] .btn-tone-danger:where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *),[data-theme="light"] .btn-tone-danger:hover:not(:disabled):where(:not([data-theme="dark"] *),[data-theme="dark"] [data-theme="light"] *) { --btn-fg:var(--danger-400); }
1376
+ .btn-outline.btn-tone-danger { --btn-border:var(--danger-400); }
1324
1377
  .btn-tone-danger:not(.btn-link):hover:not(:disabled) { --btn-bg:color-mix(in oklab, var(--destructive) 14%, transparent); }
1325
- .btn-tone-success,.btn-tone-success:hover:not(:disabled) { --btn-fg:var(--success); }
1326
- .btn-outline.btn-tone-success { --btn-border:var(--success); }
1378
+ .btn-tone-success,.btn-tone-success:hover:not(:disabled) { --btn-fg:var(--success-400); }
1379
+ .btn-outline.btn-tone-success { --btn-border:var(--success-400); }
1327
1380
  .btn-tone-success:not(.btn-link):not(.btn-solid):hover:not(:disabled) { --btn-bg:color-mix(in oklab, var(--success) 14%, transparent); }
1328
- .btn-tone-info,.btn-tone-info:hover:not(:disabled) { --btn-fg:var(--info); }
1329
- .btn-outline.btn-tone-info { --btn-border:var(--info); }
1381
+ .btn-tone-info,.btn-tone-info:hover:not(:disabled) { --btn-fg:var(--info-400); }
1382
+ .btn-outline.btn-tone-info { --btn-border:var(--info-400); }
1330
1383
  .btn-tone-info:not(.btn-link):not(.btn-solid):hover:not(:disabled) { --btn-bg:color-mix(in oklab, var(--info) 14%, transparent); }
1331
- .btn-tone-warning,.btn-tone-warning:hover:not(:disabled) { --btn-fg:var(--warning); }
1332
- .btn-outline.btn-tone-warning { --btn-border:var(--warning); }
1384
+ .btn-tone-warning,.btn-tone-warning:hover:not(:disabled) { --btn-fg:var(--warning-400); }
1385
+ .btn-outline.btn-tone-warning { --btn-border:var(--warning-400); }
1333
1386
  .btn-tone-warning:not(.btn-link):not(.btn-solid):hover:not(:disabled) { --btn-bg:color-mix(in oklab, var(--warning) 14%, transparent); }
1334
1387
  .btn-nav:hover:not(:disabled):not([aria-disabled="true"]) { --btn-fg:var(--foreground); }
1335
1388
  /* O botão só de ícone é REDONDO, em todos os tamanhos — decisão do Victor, 25/09/2026
@@ -1463,7 +1516,7 @@ img,svg { display:block; }
1463
1516
  contorno do input de dentro ficaria escondido atrás da borda do grupo. */
1464
1517
  .input-group { display:flex; flex-wrap:wrap; align-items:center; inline-size:100%; min-inline-size:0; min-block-size:var(--control-h-md); background:var(--field-bg); border:1px solid var(--border-strong); border-radius:var(--radius-control); transition:border-color var(--duration-fast),box-shadow var(--duration-fast); }
1465
1518
  .input-group:hover { border-color:var(--border); }
1466
- .input-group:focus-within { outline:var(--focus-width) solid var(--focus-strong); outline-offset:var(--focus-offset); }
1519
+ .input-group:focus-within { outline:var(--focus-width) solid var(--focus-strong); outline-offset:0; border-color:var(--focus-strong); }
1467
1520
  .input-group:has(.input-sm) { min-block-size:var(--control-h-sm); }
1468
1521
  .input-group:has(.input-lg) { min-block-size:var(--control-h-lg); }
1469
1522
  /* O controle dentro do grupo abre mão da própria moldura: quem desenha a caixa é o grupo. */
@@ -1598,7 +1651,12 @@ img,svg { display:block; }
1598
1651
  .control-mark-lg { --step-h:var(--control-h-lg); }
1599
1652
  .checkbox .control-mark { border-radius:5px; } .radio .control-mark { border-radius:50%; }
1600
1653
  .checkbox input:checked + .control-mark { background:var(--control-selected); border-color:var(--control-selected); color:var(--control-selected-foreground); }
1601
- .checkbox input:focus-visible + .control-mark,.radio input:focus-visible + .control-mark,.switch input:focus-visible + .switch-track { outline:var(--focus-width) solid var(--focus-strong); outline-offset:var(--focus-offset); }
1654
+ .checkbox input:focus-visible + .control-mark,.radio input:focus-visible + .control-mark,.switch input:focus-visible + .switch-track { outline:var(--focus-width) solid var(--focus-strong); outline-offset:0; border-color:var(--focus-strong); }
1655
+ /* Cheia com a cor do foco (marcada, ligada), a peça volta ao VÃO (ADR-0059): colado, o anel sumiria
1656
+ no recheio, como no botão amarelo. A borda dela já é da cor do recheio, então continua uma linha
1657
+ só — é o que a referência principal faz no checkbox e no switch. Inválida, a borda é vermelha e o
1658
+ anel volta a colar (vermelho, pela regra do inválido). */
1659
+ .checkbox input:focus-visible:checked:not([aria-invalid="true"],:user-invalid) + .control-mark,.switch input:focus-visible:checked:not([aria-invalid="true"],:user-invalid) + .switch-track { outline-offset:var(--focus-offset); }
1602
1660
  .checkbox input:checked + .control-mark:after { content:""; width:8px; height:4px; border-left:2px solid currentColor; border-bottom:2px solid currentColor; transform:rotate(-45deg) translateY(-1px); }
1603
1661
  .radio input:checked + .control-mark:after { content:""; width:8px; height:8px; border-radius:50%; background:var(--control-selected); }
1604
1662
  .switch { display:inline-flex; align-items:center; gap:10px; cursor:pointer; } .switch input { position:absolute; opacity:0; }
@@ -1646,7 +1704,7 @@ img,svg { display:block; }
1646
1704
  os filhos esticam sozinhos (align-items é stretch por padrão) e a conta fecha nas TRÊS. */
1647
1705
  .segmented { display:inline-flex; gap:3px; padding:3px; min-height:var(--control-h-md); border-radius:var(--radius-control); background:var(--muted); border:1px solid transparent; box-shadow:none; }
1648
1706
  .segmented button { padding:0 14px; border:0; border-radius:var(--radius-control); color:var(--muted-foreground); background:transparent; cursor:pointer; }
1649
- .segmented button.active { color:var(--foreground); background:var(--secondary); box-shadow:none; border:0; }
1707
+ .segmented button.active { color:var(--foreground); background:var(--segment); box-shadow:var(--shadow-sm); border:0; }
1650
1708
  /* `fullWidth` (A5, 06/10/2026): ocupa a linha, e cada segmento cresce a partir do rótulo sem
1651
1709
  encolher abaixo dele — o mesmo desenho do nativo. `1 0 auto` e não `1` (= `1 1 0%`): base zero
1652
1710
  reparte a largura em partes iguais, e é isso que quebrava o rótulo no nativo rodando no
@@ -1666,6 +1724,11 @@ img,svg { display:block; }
1666
1724
  dos 4.5:1 do AA, então o rótulo aprofunda com --foreground e segue âmbar. */
1667
1725
  .is-selected,.btn-nav[aria-current]:not([aria-current="false"]),.btn[aria-pressed="true"],
1668
1726
  .segmented button.active { --btn-bg:var(--secondary); --btn-fg:var(--primary); position:relative; background:var(--secondary); color:var(--primary); }
1727
+ /* A CÁPSULA ELEVADA que a regra acima promete, e que no trilho não se via (ADR-0059, 08/10/2026):
1728
+ o segmento aceso e a aba escolhida vivem sobre --muted, e --secondary dava 1:1 contra ele no
1729
+ claro e 1,02:1 no escuro. Sobre o trilho a cápsula é --segment, com a sombra pequena — como a
1730
+ aba da referência principal. O rótulo na cor da marca e o fio continuam. */
1731
+ .segmented button.active { --btn-bg:var(--segment); background:var(--segment); box-shadow:var(--shadow-sm); }
1669
1732
  /* O ATIVO DA NAV DA LATERAL sai da escala DELA, e não da página (20/08/2026, o Victor viu sob a
1670
1733
  marca `lory`). Ele dividia esta regra com o `.segmented`, que vive no conteúdo — e `--secondary`
1671
1734
  é quase branco no tema claro. Numa lateral escura isso desenhava uma pílula branca com texto
@@ -1771,10 +1834,22 @@ img,svg { display:block; }
1771
1834
  o contador cai sobre a cor da marca e precisa da mesma inversão do botão primário. Os outros
1772
1835
  seis deixam o contador sobre a superfície da barra, onde ele já se lê. */
1773
1836
 
1774
- .badge-success { --badge-accent:var(--success-400); color:var(--success-400); background:var(--success-bg); border-color:color-mix(in srgb,var(--success-400) 35%,var(--border)); }
1775
- .badge-warning { --badge-accent:var(--warning-400); color:var(--warning-400); background:var(--warning-bg); border-color:color-mix(in srgb,var(--warning-400) 35%,var(--border)); }
1776
- .badge-danger { --badge-accent:var(--danger-400); color:var(--danger-400); background:var(--danger-bg); border-color:color-mix(in srgb,var(--danger-400) 35%,var(--border)); }
1777
- .badge-info,.badge-running { --badge-accent:var(--info-400); color:var(--info-400); background:var(--info-bg); border-color:color-mix(in srgb,var(--info-400) 35%,var(--border)); }
1837
+ .badge-success { --badge-accent:var(--success-400); --badge-fill:var(--success); --badge-on:var(--success-foreground); color:var(--success-400); background:var(--success-bg); border-color:color-mix(in srgb,var(--success-400) 35%,var(--border)); }
1838
+ .badge-warning { --badge-accent:var(--warning-400); --badge-fill:var(--warning); --badge-on:var(--warning-foreground); color:var(--warning-400); background:var(--warning-bg); border-color:color-mix(in srgb,var(--warning-400) 35%,var(--border)); }
1839
+ .badge-danger { --badge-accent:var(--danger-400); --badge-fill:var(--destructive); --badge-on:var(--destructive-foreground); color:var(--danger-400); background:var(--danger-bg); border-color:color-mix(in srgb,var(--danger-400) 35%,var(--border)); }
1840
+ .badge-info,.badge-running { --badge-accent:var(--info-400); --badge-fill:var(--info); --badge-on:var(--info-foreground); color:var(--info-400); background:var(--info-bg); border-color:color-mix(in srgb,var(--info-400) 35%,var(--border)); }
1841
+ /* AS OITO CORES DE CATEGORIA (GAR-07, ADR-0060, 09/10/2026): marcam GRUPO, não estado — "Motos" e
1842
+ "Carros" num site de notícias. Mesma receita dos quatro propósitos acima (acento, fundo suave e
1843
+ o fio misturado com a borda), e por isso as três ênfases valem para elas sem regra nova. O
1844
+ amarelo fica de fora: é da marca. Quem cobra o AA nos dois temas é o `badge-categoria.spec.ts`. */
1845
+ .badge-red { --badge-accent:var(--category-red); color:var(--category-red); background:var(--category-red-bg); border-color:color-mix(in srgb,var(--category-red) 35%,var(--border)); }
1846
+ .badge-orange { --badge-accent:var(--category-orange); color:var(--category-orange); background:var(--category-orange-bg); border-color:color-mix(in srgb,var(--category-orange) 35%,var(--border)); }
1847
+ .badge-green { --badge-accent:var(--category-green); color:var(--category-green); background:var(--category-green-bg); border-color:color-mix(in srgb,var(--category-green) 35%,var(--border)); }
1848
+ .badge-teal { --badge-accent:var(--category-teal); color:var(--category-teal); background:var(--category-teal-bg); border-color:color-mix(in srgb,var(--category-teal) 35%,var(--border)); }
1849
+ .badge-cyan { --badge-accent:var(--category-cyan); color:var(--category-cyan); background:var(--category-cyan-bg); border-color:color-mix(in srgb,var(--category-cyan) 35%,var(--border)); }
1850
+ .badge-blue { --badge-accent:var(--category-blue); color:var(--category-blue); background:var(--category-blue-bg); border-color:color-mix(in srgb,var(--category-blue) 35%,var(--border)); }
1851
+ .badge-violet { --badge-accent:var(--category-violet); color:var(--category-violet); background:var(--category-violet-bg); border-color:color-mix(in srgb,var(--category-violet) 35%,var(--border)); }
1852
+ .badge-pink { --badge-accent:var(--category-pink); color:var(--category-pink); background:var(--category-pink-bg); border-color:color-mix(in srgb,var(--category-pink) 35%,var(--border)); }
1778
1853
  /* ── AS TRÊS ÊNFASES — e elas vêm DEPOIS das variantes de propósito ─────────────────
1779
1854
  Cada variante declara só o ACENTO; as ênfases saem dele. Antes cada variante escrevia
1780
1855
  cor + fundo + borda na mão, e uma ênfase nova custaria seis regras novas.
@@ -1784,7 +1859,10 @@ img,svg { display:block; }
1784
1859
  número do `soft`. É a mesma armadilha que o `.banner` e o `.data-list` já pagaram aqui.
1785
1860
  `--background` como texto do sólido serve aos DOIS temas porque o acento já vira com o
1786
1861
  tema: `--success-400` é verde CLARO no escuro e verde ESCURO no claro. */
1787
- .badge-solid { background:var(--badge-accent); color:var(--background); border-color:transparent; }
1862
+ /* O selo CHEIO de estado é o botão cheio do mesmo tom (ADR-0061): a mesma cor funda e a mesma letra
1863
+ (`--badge-fill`/`--badge-on`). Quem não declara o par (as categorias, a marca, o neutro) segue
1864
+ enchendo com o acento, como antes. */
1865
+ .badge-solid { background:var(--badge-fill, var(--badge-accent)); color:var(--badge-on, var(--background)); border-color:transparent; }
1788
1866
  .badge-outline { background:transparent; color:var(--badge-accent); border-color:var(--badge-accent); }
1789
1867
  .status-dot { width:8px; height:8px; border-radius:50%; background:currentColor; box-shadow:0 0 0 3px color-mix(in srgb,currentColor 14%,transparent); }
1790
1868
  /* Status: condição operacional (DIRECTION §3.6) — NÃO é o pill do Badge; é ponto + rótulo
@@ -1793,10 +1871,10 @@ img,svg { display:block; }
1793
1871
  nomes operacionais e os semânticos apontam pro mesmo par de tokens de propósito. */
1794
1872
  .status { display:inline-flex; align-items:center; gap:var(--space-2); color:var(--muted-foreground); font-size:var(--text-sm); }
1795
1873
  .status-label { color:var(--foreground); }
1796
- .status-online,.status-success { color:var(--success); }
1797
- .status-away,.status-warning { color:var(--warning); }
1874
+ .status-online,.status-success { color:var(--success-400); }
1875
+ .status-away,.status-warning { color:var(--warning-400); }
1798
1876
  .status-busy,.status-danger { color:var(--danger-400); }
1799
- .status-running,.status-info { color:var(--info); }
1877
+ .status-running,.status-info { color:var(--info-400); }
1800
1878
  /* offline é o único que NÃO é "mais uma cor": --subtle-foreground e --muted-foreground
1801
1879
  colapsam no MESMO valor no tema claro, então offline sairia idêntico ao neutral. Ponto
1802
1880
  VAZADO resolve nos dois temas e ainda diz a coisa certa (ausência, não outro estado).
@@ -1857,7 +1935,7 @@ img,svg { display:block; }
1857
1935
  .alert h4,.alert strong { display:block; margin:0 0 2px; font-size:var(--text-sm); } .alert p { margin:0; color:var(--muted-foreground); font-size:var(--text-sm); }
1858
1936
  /* A cor do glifo é a da variante, senão o ícone vira enfeite cinza e não repete o sinal.
1859
1937
  Só o ícone DIRETO do alerta: um ícone dentro do corpo (num botão, num link) é do corpo. */
1860
- .alert>.icon { color:var(--info); } .alert-success>.icon { color:var(--success); } .alert-warning>.icon { color:var(--warning); } .alert-danger>.icon { color:var(--danger-400); }
1938
+ .alert>.icon { color:var(--info-400); } .alert-success>.icon { color:var(--success-400); } .alert-warning>.icon { color:var(--warning-400); } .alert-danger>.icon { color:var(--danger-400); }
1861
1939
  .banner strong { font-size:var(--text-sm); } .banner p { margin:0; color:var(--muted-foreground); font-size:var(--text-sm); }
1862
1940
  @media (max-width:640px) { .banner { grid-template-columns:auto minmax(0,1fr); } .banner>:last-child { grid-column:2; justify-self:start; } }
1863
1941
  .progress { height:8px; overflow:hidden; border-radius:999px; background:var(--surface-3); }
@@ -1869,10 +1947,10 @@ img,svg { display:block; }
1869
1947
  .progress-field { display:grid; gap:var(--space-1); }
1870
1948
  .progress-detail { justify-self:end; color:var(--muted-foreground); font-size:var(--text-sm); font-weight:var(--weight-medium); font-variant-numeric:tabular-nums; }
1871
1949
  .progress-tone-neutral>span { background:var(--muted-foreground); }
1872
- .progress-tone-success>span { background:var(--success); }
1873
- .progress-tone-warning>span { background:var(--warning); }
1874
- .progress-tone-danger>span { background:var(--destructive); }
1875
- .progress-tone-info>span { background:var(--info); }
1950
+ .progress-tone-success>span { background:var(--success-400); }
1951
+ .progress-tone-warning>span { background:var(--warning-400); }
1952
+ .progress-tone-danger>span { background:var(--danger-400); }
1953
+ .progress-tone-info>span { background:var(--info-400); }
1876
1954
  /* Sem total, um pedaço de 2/5 corre pelo trilho: os números da referência (a largura de 2/5, de -100% a 350%
1877
1955
  da própria largura, 1,5 s, a curva dela). A referência anda com `translateX`; aqui anda a MARGEM LÓGICA
1878
1956
  (de -40% a 140% do trilho, o mesmo percurso), para correr ao contrário na escrita da direita para
@@ -1905,7 +1983,7 @@ img,svg { display:block; }
1905
1983
  sai serrilhada, que é o mesmo defeito que o `.btn-group-vertical` resolve com `stretch`. */
1906
1984
  .tabs[data-orientation="vertical"] .tab { min-block-size:var(--control-h-md); text-align:start; }
1907
1985
  .tab { position:relative; padding:0 14px; border:0; border-radius:var(--radius-control); background:transparent; color:var(--muted-foreground); cursor:pointer; }
1908
- .tab.active,.tab[data-active] { color:var(--foreground); background:var(--secondary); } .tab.active:after,.tab[data-active]:after { display:none; }
1986
+ .tab.active,.tab[data-active] { color:var(--foreground); background:var(--segment); box-shadow:var(--shadow-sm); } .tab.active:after,.tab[data-active]:after { display:none; }
1909
1987
  /* `panel="plain"` (MNT-05 e C9, 06/10/2026): o painel sem caixa, como o painel de abas da
1910
1988
  referência. Sem recheio dos lados — o conteúdo começa na linha do que está fora do `Tabs` —, e o
1911
1989
  espaço de cima é o mesmo `space-3` do painel do nativo. Na vertical, quem separa é o `gap` da
@@ -2023,13 +2101,27 @@ img,svg { display:block; }
2023
2101
  /* O "+N" é um avatar como os outros — mesma caixa, mesma borda —, só que menor por dentro e sem
2024
2102
  peso de nome próprio: ele conta, não identifica. */
2025
2103
  .avatar-count { background:var(--secondary); color:var(--muted-foreground); font-size:var(--text-xs); font-weight:var(--weight-medium); }
2026
- .kpi { display:flex; flex-direction:column; gap:5px; }
2104
+ .kpi { display:flex; flex-direction:column; gap:var(--space-1); }
2027
2105
  /* O NÚMERO do KPI (08/10/2026, pedido de um consumidor com baixa visão): a ficha sempre prometeu
2028
2106
  `--text-3xl`, e o CSS nunca aplicou — medido no navegador, o valor saía com 14, igual ao rótulo,
2029
2107
  e a tendência com 11,7 (o `small` do navegador encolhe a letra). O número é a razão do
2030
2108
  componente; os algarismos ficam tabulares para não dançar quando o valor muda. */
2031
2109
  .kpi > strong { font-size:var(--text-3xl); line-height:var(--leading-tight); font-variant-numeric:tabular-nums; }
2032
2110
  .kpi > small { font-size:var(--text-sm); }
2111
+ /* A TENDÊNCIA COM DIREÇÃO (GAR-09, ADR-0060, 09/10/2026): seta, palavra para o leitor de tela e cor,
2112
+ nunca a cor sozinha. A seta é o `trend-up`/`trend-down`/`minus` do Phosphor (o mesmo desenho do
2113
+ sprite), por máscara — o KPI é marcação pura e o `Icon` precisa de hook; o menu do `Header` já
2114
+ faz assim. A cor é a do texto do selo de cada estado, que já passa AA nos dois temas. */
2115
+ /* A seta fica na PRIMEIRA linha: com `center`, uma tendência que quebra em duas linhas deixava a
2116
+ seta solta entre elas (visto na bancada, 09/10/2026). `1lh` é a altura da linha do próprio texto. */
2117
+ .kpi-trend { display:inline-flex; align-items:flex-start; gap:var(--space-1); }
2118
+ .kpi-trend-icon { flex:none; inline-size:var(--icon-sm); block-size:var(--icon-sm); margin-block-start:calc((1lh - var(--icon-sm)) / 2); background:currentColor; -webkit-mask:var(--kpi-glifo) center/contain no-repeat; mask:var(--kpi-glifo) center/contain no-repeat; }
2119
+ .kpi-trend-up { --kpi-glifo:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M240,56v64a8,8,0,0,1-16,0V75.31l-82.34,82.35a8,8,0,0,1-11.32,0L96,123.31,29.66,189.66a8,8,0,0,1-11.32-11.32l72-72a8,8,0,0,1,11.32,0L136,140.69,212.69,64H168a8,8,0,0,1,0-16h64A8,8,0,0,1,240,56Z'/%3E%3C/svg%3E"); }
2120
+ .kpi-trend-down { --kpi-glifo:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M240,128v64a8,8,0,0,1-8,8H168a8,8,0,0,1,0-16h44.69L136,107.31l-34.34,34.35a8,8,0,0,1-11.32,0l-72-72A8,8,0,0,1,29.66,58.34L96,124.69l34.34-34.35a8,8,0,0,1,11.32,0L224,172.69V128a8,8,0,0,1,16,0Z'/%3E%3C/svg%3E"); }
2121
+ .kpi-trend-flat { --kpi-glifo:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128Z'/%3E%3C/svg%3E"); }
2122
+ .kpi-tone-success { color:var(--success-400); }
2123
+ .kpi-tone-danger { color:var(--danger-400); }
2124
+ .kpi-tone-neutral { color:var(--muted-foreground); }
2033
2125
  /* DataList: chave/valor em duas colunas. O termo é secundário — mesmo idioma do cabeçalho de
2034
2126
  tabela. Sem a regra (achado A13) o <dl> saía cru: dt e dd empilhados, com o recuo de 40px
2035
2127
  que o navegador dá ao <dd>. */
@@ -2137,7 +2229,7 @@ img,svg { display:block; }
2137
2229
  log e a cor primária da Aurea são duas intenções, e ficavam indistinguíveis. `text-transform`
2138
2230
  porque o React passa o valor em minúsculas (é ele que casa a regra) e o nível tem de LER como
2139
2231
  nível. */
2140
- .log-line { display:grid; grid-template-columns:86px 72px minmax(0,1fr); gap:12px; padding:3px 0; } .log-time { color:var(--subtle-foreground); } .log-level { color:var(--primary); text-transform:uppercase; } .log-level.info { color:var(--info); } .log-level.warn { color:var(--warning); } .log-level.error { color:var(--danger-400); }
2232
+ .log-line { display:grid; grid-template-columns:86px 72px minmax(0,1fr); gap:12px; padding:3px 0; } .log-time { color:var(--subtle-foreground); } .log-level { color:var(--primary); text-transform:uppercase; } .log-level.info { color:var(--info-400); } .log-level.warn { color:var(--warning-400); } .log-level.error { color:var(--danger-400); }
2141
2233
 
2142
2234
  /* ========================================================================== */
2143
2235
  /* 05. GRÁFICOS E VISUALIZAÇÃO */
@@ -2643,7 +2735,7 @@ img,svg { display:block; }
2643
2735
  /* MultiCombobox (Fase 4) — chips de multi-seleção + grupos. Espaçamento novo tokenizado. */
2644
2736
  .combobox-multi { display:flex; align-items:center; gap:var(--space-2); width:100%; min-width:0; min-height:var(--control-h-md); padding:var(--space-1) var(--space-2); background:var(--field-bg); border:1px solid var(--border-strong); border-radius:var(--radius-control); transition:border-color var(--duration-fast); }
2645
2737
  .combobox-multi:hover { border-color:var(--border); }
2646
- .combobox-multi:focus-within { outline:var(--focus-width) solid var(--focus-strong); outline-offset:var(--focus-offset); border-color:var(--focus-strong); }
2738
+ .combobox-multi:focus-within { outline:var(--focus-width) solid var(--focus-strong); outline-offset:0; border-color:var(--focus-strong); }
2647
2739
  .combobox-multi>.combobox-actions { position:static; inset-inline-end:auto; }
2648
2740
  /* o campo de chips não é `.input`, então a regra de :disabled dos campos não o alcança. Quem
2649
2741
  marca aqui é o `data-disabled` que o Base UI põe no InputGroup a partir do estado da Root. */
@@ -2669,7 +2761,7 @@ img,svg { display:block; }
2669
2761
  o arrastar-soltar é reforço. Espaçamento novo tokenizado; superfície = card. */
2670
2762
  .dropzone { display:flex; flex-direction:column; align-items:center; gap:var(--space-2); padding:var(--space-8) var(--space-6); text-align:center; color:var(--muted-foreground); background:var(--surface-inset); border:1px dashed var(--border-strong); border-radius:var(--radius-card); cursor:pointer; transition:border-color var(--duration-fast),background-color var(--duration-fast); }
2671
2763
  .dropzone:hover { border-color:var(--border); }
2672
- .dropzone:focus-within { outline:var(--focus-width) solid var(--focus-strong); outline-offset:var(--focus-offset); border-color:var(--focus-strong); }
2764
+ .dropzone:focus-within { outline:var(--focus-width) solid var(--focus-strong); outline-offset:0; border-color:var(--focus-strong); }
2673
2765
  .dropzone[data-dragging="true"] { border-style:solid; border-color:var(--primary); background:var(--surface-2); }
2674
2766
  .dropzone strong { color:var(--foreground); }
2675
2767
  .dropzone-icon { color:var(--primary); }
@@ -2737,7 +2829,11 @@ img,svg { display:block; }
2737
2829
  .combobox-multi:has([aria-invalid="true"]),
2738
2830
  .combobox-multi:has(:user-invalid),
2739
2831
  .dropzone:has([aria-invalid="true"]),
2740
- .dropzone:has(:user-invalid) { border-color:var(--danger-400); }
2832
+ .dropzone:has(:user-invalid) { border-color:var(--danger-400); --focus-strong:var(--danger-400); }
2833
+ /* ↑ `--focus-strong` (ADR-0059, 08/10/2026): o anel de foco agora COLA na borda e a pinta — com o
2834
+ amarelo, o campo inválido perdia o vermelho justo enquanto a pessoa corrige. No inválido o anel é
2835
+ da cor do perigo, como o campo inválido da referência principal. Cor por contexto se faz assim,
2836
+ redefinindo `--focus-strong` (check 44). */
2741
2837
 
2742
2838
 
2743
2839
  /* TreeView (Fase 4) — árvore headless própria (Base UI 1.6 não tem tree).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aurea-uds/core",
3
- "version": "0.24.1",
3
+ "version": "0.27.0",
4
4
  "description": "O CSS da Aurea UDS e o comportamento em JavaScript puro. Importe @aurea-uds/fonts/css antes deste.",
5
5
  "keywords": [
6
6
  "aurea",