@aurea-uds/core 0.3.0 → 0.5.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.
- package/dist/aurea.css +512 -40
- package/package.json +1 -1
package/dist/aurea.css
CHANGED
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
--z-modal:80;
|
|
57
57
|
--z-toast:100;
|
|
58
58
|
--sidebar-width:16.5rem;
|
|
59
|
-
--sidebar-rail:
|
|
59
|
+
--sidebar-rail:4.25rem;
|
|
60
60
|
--topbar-height:4rem;
|
|
61
61
|
--content-max:102.5rem;
|
|
62
62
|
--breakpoint-sm:640px;
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
--chart-5:oklch(0.424 0.199 265.638);
|
|
207
207
|
--sidebar:var(--card);
|
|
208
208
|
--sidebar-foreground:oklch(0.145 0 0);
|
|
209
|
-
--sidebar-primary:var(--
|
|
209
|
+
--sidebar-primary:var(--primary-emphasis);
|
|
210
210
|
--sidebar-primary-foreground:var(--brand-yellow-foreground);
|
|
211
211
|
--sidebar-accent:var(--secondary);
|
|
212
212
|
--sidebar-accent-foreground:oklch(0.205 0 0);
|
|
@@ -243,6 +243,130 @@
|
|
|
243
243
|
--danger-bg:oklch(0.95 0.05 22);
|
|
244
244
|
--info-bg:oklch(0.95 0.045 260);
|
|
245
245
|
}
|
|
246
|
+
[data-brand="lory"][data-theme="dark"]{
|
|
247
|
+
--background:oklch(0.16 0.018 250);
|
|
248
|
+
--foreground:oklch(0.96 0.006 250);
|
|
249
|
+
--foreground-strong:oklch(1 0 0);
|
|
250
|
+
--card:oklch(0.21 0.02 250);
|
|
251
|
+
--card-foreground:oklch(0.96 0.006 250);
|
|
252
|
+
--popover:oklch(0.21 0.02 250);
|
|
253
|
+
--popover-foreground:oklch(0.96 0.006 250);
|
|
254
|
+
--surface-1:oklch(0.21 0.02 250);
|
|
255
|
+
--surface-2:oklch(0.245 0.02 250);
|
|
256
|
+
--surface-3:oklch(0.19 0.02 250);
|
|
257
|
+
--surface-inset:oklch(0.19 0.02 250);
|
|
258
|
+
--surface-hover:oklch(0.245 0.02 250);
|
|
259
|
+
--primary:oklch(0.72 0.19 48);
|
|
260
|
+
--primary-foreground:oklch(0.16 0.02 250);
|
|
261
|
+
--primary-hover:oklch(0.78 0.17 50);
|
|
262
|
+
--primary-active:oklch(0.66 0.19 46);
|
|
263
|
+
--primary-emphasis:oklch(0.85 0.14 60);
|
|
264
|
+
--primary-outline:oklch(0.72 0.19 48 / 0.4);
|
|
265
|
+
--secondary:oklch(0.245 0.02 250);
|
|
266
|
+
--secondary-foreground:oklch(0.96 0.006 250);
|
|
267
|
+
--secondary-hover:oklch(0.28 0.02 250);
|
|
268
|
+
--muted:oklch(0.19 0.02 250);
|
|
269
|
+
--muted-foreground:oklch(0.72 0.015 250);
|
|
270
|
+
--subtle-foreground:oklch(0.58 0.016 250);
|
|
271
|
+
--accent:oklch(0.32 0.08 50);
|
|
272
|
+
--accent-foreground:oklch(0.85 0.14 60);
|
|
273
|
+
--destructive:oklch(0.7 0.19 25);
|
|
274
|
+
--destructive-foreground:oklch(0.16 0.02 250);
|
|
275
|
+
--border:oklch(1 0 0 / 0.1);
|
|
276
|
+
--border-strong:oklch(1 0 0 / 0.18);
|
|
277
|
+
--input:oklch(1 0 0 / 0.1);
|
|
278
|
+
--field-bg:oklch(0.19 0.02 250);
|
|
279
|
+
--ring:oklch(0.72 0.19 48);
|
|
280
|
+
--focus:oklch(0.72 0.19 48);
|
|
281
|
+
--focus-strong:oklch(0.85 0.14 60);
|
|
282
|
+
--selection:oklch(0.32 0.08 50);
|
|
283
|
+
--control-selected:oklch(0.72 0.19 48);
|
|
284
|
+
--control-selected-foreground:oklch(0.16 0.02 250);
|
|
285
|
+
--overlay:oklch(0 0 0 / 0.6);
|
|
286
|
+
--chart-1:oklch(0.74 0.18 50);
|
|
287
|
+
--chart-2:oklch(0.84 0.14 88);
|
|
288
|
+
--chart-3:oklch(0.72 0.15 158);
|
|
289
|
+
--chart-4:oklch(0.7 0.13 235);
|
|
290
|
+
--chart-5:oklch(0.68 0.16 320);
|
|
291
|
+
--sidebar:oklch(0.21 0.02 250);
|
|
292
|
+
--sidebar-foreground:oklch(0.96 0.006 250);
|
|
293
|
+
--sidebar-primary:oklch(0.72 0.19 48);
|
|
294
|
+
--sidebar-primary-foreground:oklch(0.16 0.02 250);
|
|
295
|
+
--sidebar-accent:oklch(0.245 0.02 250);
|
|
296
|
+
--sidebar-accent-foreground:oklch(0.96 0.006 250);
|
|
297
|
+
--sidebar-border:oklch(1 0 0 / 0.1);
|
|
298
|
+
--sidebar-ring:oklch(0.72 0.19 48);
|
|
299
|
+
--success-400:oklch(0.72 0.15 158);
|
|
300
|
+
--warning-400:oklch(0.78 0.14 78);
|
|
301
|
+
--danger-400:oklch(0.7 0.19 25);
|
|
302
|
+
--info-400:oklch(0.7 0.13 235);
|
|
303
|
+
--success-bg:oklch(0.32 0.07 158);
|
|
304
|
+
--warning-bg:oklch(0.34 0.07 80);
|
|
305
|
+
--danger-bg:oklch(0.34 0.09 25);
|
|
306
|
+
--info-bg:oklch(0.32 0.06 235);
|
|
307
|
+
}
|
|
308
|
+
[data-brand="lory"][data-theme="light"]{
|
|
309
|
+
--background:oklch(0.984 0.004 70);
|
|
310
|
+
--foreground:oklch(0.24 0.022 250);
|
|
311
|
+
--foreground-strong:oklch(0.16 0.02 250);
|
|
312
|
+
--card:oklch(1 0 0);
|
|
313
|
+
--card-foreground:oklch(0.24 0.022 250);
|
|
314
|
+
--popover:oklch(1 0 0);
|
|
315
|
+
--popover-foreground:oklch(0.24 0.022 250);
|
|
316
|
+
--surface-1:oklch(1 0 0);
|
|
317
|
+
--surface-2:oklch(0.975 0.004 70);
|
|
318
|
+
--surface-3:oklch(0.965 0.006 70);
|
|
319
|
+
--surface-inset:oklch(0.965 0.006 70);
|
|
320
|
+
--surface-hover:oklch(0.965 0.006 70);
|
|
321
|
+
--primary:oklch(0.682 0.197 44.5);
|
|
322
|
+
--primary-foreground:oklch(1 0 0);
|
|
323
|
+
--primary-hover:oklch(0.63 0.197 44.5);
|
|
324
|
+
--primary-active:oklch(0.58 0.19 44.5);
|
|
325
|
+
--primary-emphasis:oklch(0.52 0.17 45);
|
|
326
|
+
--primary-outline:oklch(0.682 0.197 44.5 / 0.35);
|
|
327
|
+
--secondary:oklch(0.965 0.006 70);
|
|
328
|
+
--secondary-foreground:oklch(0.24 0.022 250);
|
|
329
|
+
--secondary-hover:oklch(0.94 0.006 70);
|
|
330
|
+
--muted:oklch(0.965 0.006 70);
|
|
331
|
+
--muted-foreground:oklch(0.52 0.018 255);
|
|
332
|
+
--subtle-foreground:oklch(0.65 0.014 255);
|
|
333
|
+
--accent:oklch(0.96 0.04 60);
|
|
334
|
+
--accent-foreground:oklch(0.52 0.17 45);
|
|
335
|
+
--destructive:oklch(0.62 0.21 26);
|
|
336
|
+
--destructive-foreground:oklch(1 0 0);
|
|
337
|
+
--border:oklch(0.915 0.006 255);
|
|
338
|
+
--border-strong:oklch(0.86 0.008 255);
|
|
339
|
+
--input:oklch(0.915 0.006 255);
|
|
340
|
+
--field-bg:oklch(1 0 0);
|
|
341
|
+
--ring:oklch(0.682 0.197 44.5);
|
|
342
|
+
--focus:oklch(0.682 0.197 44.5);
|
|
343
|
+
--focus-strong:oklch(0.52 0.17 45);
|
|
344
|
+
--selection:oklch(0.96 0.04 60);
|
|
345
|
+
--control-selected:oklch(0.682 0.197 44.5);
|
|
346
|
+
--control-selected-foreground:oklch(1 0 0);
|
|
347
|
+
--overlay:oklch(0.16 0.018 250 / 0.45);
|
|
348
|
+
--chart-1:oklch(0.682 0.197 44.5);
|
|
349
|
+
--chart-2:oklch(0.82 0.15 88);
|
|
350
|
+
--chart-3:oklch(0.66 0.15 155);
|
|
351
|
+
--chart-4:oklch(0.62 0.13 235);
|
|
352
|
+
--chart-5:oklch(0.6 0.16 320);
|
|
353
|
+
--sidebar:oklch(1 0 0);
|
|
354
|
+
--sidebar-foreground:oklch(0.24 0.022 250);
|
|
355
|
+
--sidebar-primary:oklch(0.52 0.17 45);
|
|
356
|
+
--sidebar-primary-foreground:oklch(1 0 0);
|
|
357
|
+
--sidebar-accent:oklch(0.975 0.004 70);
|
|
358
|
+
--sidebar-accent-foreground:oklch(0.24 0.022 250);
|
|
359
|
+
--sidebar-border:oklch(0.915 0.006 255);
|
|
360
|
+
--sidebar-ring:oklch(0.682 0.197 44.5);
|
|
361
|
+
--success-400:oklch(0.66 0.15 155);
|
|
362
|
+
--warning-400:oklch(0.78 0.15 75);
|
|
363
|
+
--danger-400:oklch(0.62 0.21 26);
|
|
364
|
+
--info-400:oklch(0.62 0.13 235);
|
|
365
|
+
--success-bg:oklch(0.95 0.05 155);
|
|
366
|
+
--warning-bg:oklch(0.95 0.06 80);
|
|
367
|
+
--danger-bg:oklch(0.95 0.05 25);
|
|
368
|
+
--info-bg:oklch(0.95 0.04 235);
|
|
369
|
+
}
|
|
246
370
|
[data-density="compact"]{
|
|
247
371
|
--control-h-xs:1.5rem;
|
|
248
372
|
--control-h-sm:1.75rem;
|
|
@@ -313,6 +437,13 @@ img,svg { display:block; }
|
|
|
313
437
|
.muted { color:var(--muted-foreground); }
|
|
314
438
|
.stack { display:flex; flex-direction:column; gap:var(--space-4); }
|
|
315
439
|
.cluster { display:flex; align-items:center; flex-wrap:wrap; gap:var(--space-3); }
|
|
440
|
+
/* SEPARATOR. `background` num box de 1px e NÃO `border`: assim a espessura não depende de qual
|
|
441
|
+
lado do border está escrito, e a mesma classe serve nas duas orientações. `<hr>` chega com
|
|
442
|
+
margem e borda do navegador — as duas são zeradas aqui, senão a régua vem com folga que ninguém
|
|
443
|
+
pediu. O vertical precisa de `align-self:stretch` para acompanhar a altura do irmão mais alto, e
|
|
444
|
+
de um piso: sem `min-height` ele mede ZERO num pai que não define altura, e desaparece. */
|
|
445
|
+
.separator { flex:none; width:100%; height:1px; margin:0; border:0; background:var(--border); }
|
|
446
|
+
.separator-vertical { align-self:stretch; width:1px; height:auto; min-height:var(--space-2); }
|
|
316
447
|
/* Grid: o terceiro primitivo de layout, com o mesmo gap do .stack. A pele nasceu na Fase 11
|
|
317
448
|
(achado A13): o componente existia desde sempre e saía `display:block` — empilhava. Ninguém
|
|
318
449
|
via porque o chrome do catálogo REDEFINIA .grid, então ele parecia pronto na nossa
|
|
@@ -336,7 +467,11 @@ img,svg { display:block; }
|
|
|
336
467
|
26 telas de referência inteiras (aconteceu; o portão visual pegou). Por isso a folga
|
|
337
468
|
entre as caixas sai da MARGEM de cada filho, não de gap/padding no shell. As linhas
|
|
338
469
|
extras do grid nascem sozinhas por auto-placement. */
|
|
339
|
-
.app-shell { min-height:100vh; display:grid; grid-template-columns:var(--sidebar-
|
|
470
|
+
.app-shell { --sidebar-track:calc(var(--sidebar-width) + var(--space-4)*2); min-height:100vh; display:grid; grid-template-columns:var(--sidebar-track) minmax(0,1fr); background:var(--background); }
|
|
471
|
+
/* `--sidebar-width` nomeia o PAINEL, não a trilha inteira. A variante flutuante ainda gasta
|
|
472
|
+
`--space-4` dos dois lados; reservar só o token fazia 264px virarem 232px. A rente não tem
|
|
473
|
+
margem, então a trilha dela continua sendo o token cru. */
|
|
474
|
+
.app-shell:has(> .sidebar-flush) { --sidebar-track:var(--sidebar-width); }
|
|
340
475
|
/* A base do topo carrega só o ARRANJO; cada variante traz a própria superfície.
|
|
341
476
|
floating = caixa solta (a que já estava) · flush = faixa encostada nas bordas com fio
|
|
342
477
|
embaixo, para o topo virar moldura da janela · pill = cápsula centrada, de cabeçalho
|
|
@@ -354,7 +489,41 @@ img,svg { display:block; }
|
|
|
354
489
|
.topbar .brand { min-height:auto; margin:0; padding:0; border:0; }
|
|
355
490
|
/* altura fixa = janela menos topo e as 3 folgas; assim a caixa parece cheia mesmo com
|
|
356
491
|
poucos itens (é o que as referências mostram) e sobra o que rolar por dentro. */
|
|
357
|
-
|
|
492
|
+
/* E O TETO É O CONTAINER, NÃO A JANELA. A altura acima é da JANELA, e sozinha ela faz a lateral
|
|
493
|
+
presumir que é dona da tela: dentro de qualquer caixa menor ela calcula 818px, transborda e é
|
|
494
|
+
CORTADA — medido em 18/08/2026 na prévia do catálogo, 818px dentro de 272px, sem nem rolar.
|
|
495
|
+
`max-height:100%` contra um pai de altura INDEFINIDA é ignorado, então no `AppShell` (onde a
|
|
496
|
+
lateral realmente é dona da tela) nada muda — conferido: 818px antes e depois, idêntico. Contra
|
|
497
|
+
um pai de altura definida ele manda, e a caixa passa a caber. Os `--space-4`*2 descontam a
|
|
498
|
+
própria margem, senão ela transborda pelo dobro da folga.
|
|
499
|
+
O intento da altura continua o mesmo: caixa cheia mesmo com poucos itens, e o que sobra rola
|
|
500
|
+
por dentro (`overflow:auto`, logo abaixo). O que muda é de onde vem o teto. */
|
|
501
|
+
/* O PAINEL DÁ QUASE NADA E A LINHA DÁ O RESTO — o mesmo padrão do `.card:has(> .nav-list)`.
|
|
502
|
+
Era `--space-4` (16px): o item começava a 17px da borda e ocupava 88% da largura, com o
|
|
503
|
+
realce flutuando no meio do painel. */
|
|
504
|
+
/* A LATERAL FLUTUA POR PADRÃO — é a identidade desta casa, e o `CLAUDE.md` manda.
|
|
505
|
+
EM 18/08/2026 O PADRÃO FOI INVERTIDO AQUI, E ESTAVA ERRADO. O Victor abriu exceção para a
|
|
506
|
+
lateral PODER ser rente; uma sessão leu "abriu exceção" como "troque o padrão". São coisas
|
|
507
|
+
diferentes, e ele separou as duas em 20/08/2026:
|
|
508
|
+
"uma coisa é a gente ter o componente outra coisa é usar no nosso próprio projeto,
|
|
509
|
+
o nosso vai ser tudo flutuante mas isso não impede da gente ter outras variações para
|
|
510
|
+
as pessoas que nos acharem no npm usarem"
|
|
511
|
+
E o estrago não foi de gosto: as 106 páginas do catálogo montam por `AppShell`, que chama a
|
|
512
|
+
`Sidebar` SEM variante — inverter o padrão reescreveu o catálogo inteiro, e quatro baselines
|
|
513
|
+
de pixel foram regravadas para aceitar. Ver ADR-0034.
|
|
514
|
+
Esta regra é a de `b0599be`, íntegra: estado conhecido bom, provado pelo portão de pixel em vez
|
|
515
|
+
de reafinado à mão. */
|
|
516
|
+
.sidebar { --shell-top:calc(var(--topbar-height) + var(--space-4)*2); position:sticky; top:var(--shell-top); align-self:start; height:calc(100vh - var(--shell-top) - var(--space-4)); max-height:calc(100% - var(--space-4)*2); margin:var(--space-4); display:flex; flex-direction:column; gap:var(--space-1); padding:var(--space-1); overflow:auto; scrollbar-width:none; border:1px solid var(--sidebar-border); border-radius:var(--radius-card); background:var(--sidebar); color:var(--sidebar-foreground); }
|
|
517
|
+
/* RENTE É A VARIANTE, e ela existe porque o Victor mediu quatro aplicativos que rodam na mão:
|
|
518
|
+
Cloudflare, Sophos, o app do Claude e o painel do próprio HeroUI. Nenhum flutua a lateral — ela
|
|
519
|
+
encosta nas bordas, ocupa a altura toda e se separa do conteúdo por UM TRAÇO, não por um vão.
|
|
520
|
+
É a ÚNICA exceção à caixa flutuante nesta casa, e não generaliza: card, diálogo e painel seguem
|
|
521
|
+
flutuando.
|
|
522
|
+
Ela desfaz exatamente o que a flutuante põe — as duas contas de altura, a margem, o raio e de
|
|
523
|
+
que lados vem a borda —, e é por isso que a trava de pele exige que as duas MEÇAM diferente:
|
|
524
|
+
variante que desenha igual é enfeite. `--shell-top` volta a ser só a altura do topo, porque sem
|
|
525
|
+
margem não há as duas folgas a descontar. */
|
|
526
|
+
.sidebar-flush { --shell-top:var(--topbar-height); height:calc(100vh - var(--shell-top)); max-height:100%; margin:0; border:0; border-inline-end:1px solid var(--sidebar-border); border-radius:0; }
|
|
358
527
|
/* a lateral ROLA mas nunca mostra a barra (pedido do Victor): a barra nativa risca a
|
|
359
528
|
superfície flutuante e não segue o raio de 22px. `scrollbar-width` cobre Firefox e
|
|
360
529
|
Chrome 121+; o pseudo cobre Safari e Chrome antigo. */
|
|
@@ -363,7 +532,10 @@ img,svg { display:block; }
|
|
|
363
532
|
e do conteúdo é --space-1 (4px), e o --shell-top acompanha. */
|
|
364
533
|
/* flush cola no conteúdo com --space-05 (2px) — o degrau mais apertado da escala, criado
|
|
365
534
|
pra este caso (o Victor aprovou os 2px; tokenizado, não cru). */
|
|
366
|
-
|
|
535
|
+
/* E ela NÃO vale para a lateral rente: `.app-shell-flush .sidebar` é mais específico que
|
|
536
|
+
`.sidebar-flush` e roubaria dela a margem e o `--shell-top`. Esta regra é sobre o TOPO
|
|
537
|
+
encostado, não sobre a lateral — a rente já encosta sozinha. */
|
|
538
|
+
.app-shell-flush .sidebar:not(.sidebar-flush) { --shell-top:calc(var(--topbar-height) + var(--space-05)); margin-block-start:var(--space-05); }
|
|
367
539
|
.app-shell-flush .content { margin-block-start:var(--space-05); }
|
|
368
540
|
.content { min-width:0; margin:var(--space-4) var(--space-4) var(--space-4) 0; padding:var(--space-6); border:1px solid var(--border); border-radius:var(--radius-card); background:var(--card); color:var(--card-foreground); }
|
|
369
541
|
/* O topo é presentational — não conhece o conteúdo — então garante o mínimo universal:
|
|
@@ -375,13 +547,14 @@ img,svg { display:block; }
|
|
|
375
547
|
mexer no viewport: o @media não disparava e a nav passava 27px da borda direita, em todas
|
|
376
548
|
as páginas. Quebrar por conteúdo cobre os dois casos e não muda nada quando cabe. */
|
|
377
549
|
.topbar,.topbar > nav { flex-wrap:wrap; }
|
|
378
|
-
/* Colapso do shell abaixo de
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
550
|
+
/* Colapso do shell abaixo de lg (1023 = lg-1, escala): a lateral do AppShell deixa o fluxo e
|
|
551
|
+
vira a gaveta definida abaixo. A regra mira o filho `[popover]` de propósito: uma `Sidebar`
|
|
552
|
+
standalone dentro de um preview estreito continua sendo o componente inteiro, não herda
|
|
553
|
+
comportamento do shell que não existe ao redor dela. */
|
|
554
|
+
/* Abaixo de lg o topo QUEBRA em duas linhas em vez de esconder a navegação: perder o acesso
|
|
555
|
+
a uma área inteira não é colapso responsivo, é bug. A nav vai pra segunda linha, centrada
|
|
556
|
+
e na largura toda; badge e selo (secundários) seguem escondidos pelos utilitários. */
|
|
557
|
+
@media (max-width:1023px) { .app-shell { grid-template-columns:minmax(0,1fr); } .app-shell > .sidebar[popover] { position:static; height:auto; } .content { margin-inline-start:var(--space-4); }
|
|
385
558
|
.topbar { flex-wrap:wrap; row-gap:var(--space-2); }
|
|
386
559
|
.topbar > nav { order:3; flex-basis:100%; justify-content:center; }
|
|
387
560
|
/* e a nav quebra entre os PRÓPRIOS itens: mandar a barra pra segunda linha não bastava,
|
|
@@ -389,12 +562,13 @@ img,svg { display:block; }
|
|
|
389
562
|
.topbar > nav { flex-wrap:wrap; row-gap:var(--space-1); } }
|
|
390
563
|
|
|
391
564
|
/* ── GAVETA DE NAVEGAÇÃO (achado A8) ───────────────────────────────────────────────
|
|
392
|
-
Empilhar a lateral acima do conteúdo passava, no gate de rolagem lateral, e era
|
|
565
|
+
Empilhar a lateral acima do conteúdo passava, no gate de rolagem lateral, e era
|
|
393
566
|
inutilizável: medido em 375px, o `h1` da página começava 4,6 telas abaixo, atrás dos 65
|
|
394
|
-
itens da navegação. Abaixo de
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
567
|
+
itens da navegação. Abaixo de lg ela sai do fluxo e vira gaveta — o mesmo corte da
|
|
568
|
+
referência e o breakpoint `--breakpoint-lg` já publicado pela Aurea.
|
|
569
|
+
A MECÂNICA é nativa: o <aside> é popover e o botão do topo é o invoker. O navegador entrega
|
|
570
|
+
Escape, clique fora, `aria-expanded` e ::backdrop; o AppShell normaliza entrada e retorno de
|
|
571
|
+
foco nos três motores, porque o WebKit não os entregou sozinho (ADR-0019).
|
|
398
572
|
Não-modal de propósito (o foco não fica preso), como o CommandPaletteShell: declarar
|
|
399
573
|
modalidade sem entregá-la é pior que não declarar. */
|
|
400
574
|
.btn.nav-toggle { display:none; }
|
|
@@ -408,14 +582,16 @@ img,svg { display:block; }
|
|
|
408
582
|
Medido: sem esta linha a lateral seguia empilhada em 375px, com o botão já visível.
|
|
409
583
|
O @supports é a rede: em navegador sem popover a regra inteira não aplica, a lateral volta a
|
|
410
584
|
empilhar (o comportamento de antes, feio e usável) em vez de sumir sem botão que a abra. */
|
|
411
|
-
@supports selector(:popover-open) {
|
|
412
|
-
@media (max-width:
|
|
585
|
+
@supports selector(:popover-open) {
|
|
586
|
+
@media (max-width:1023px) {
|
|
413
587
|
.sidebar[popover]:not(:popover-open) { display:none; }
|
|
414
588
|
.btn.nav-toggle { display:inline-flex; }
|
|
415
589
|
/* altura EXPLÍCITA, não `auto`: medido em 30/07/2026, com `top` e `bottom` postos e
|
|
416
590
|
`height:auto` o Chromium resolveu pela altura do CONTEÚDO (3.498px de lateral rolando a
|
|
417
591
|
página inteira), não pelas âncoras. `dvh` porque a barra do navegador móvel some e volta. */
|
|
418
|
-
|
|
592
|
+
/* 296px no teto: `--sidebar-width` (264) + as duas folgas externas (32), a mesma medida
|
|
593
|
+
do drawer da referência. Em viewport menor, a segunda conta sempre preserva as bordas. */
|
|
594
|
+
.sidebar[popover]:popover-open { position:fixed; inset-block:var(--space-4); inset-inline-start:var(--space-4); width:min(calc(var(--sidebar-width) + var(--space-4)*2),calc(100vw - var(--space-8))); height:calc(100dvh - var(--space-4) * 2); margin:0; }
|
|
419
595
|
.sidebar[popover]::backdrop { background:var(--overlay); }
|
|
420
596
|
}
|
|
421
597
|
}
|
|
@@ -432,30 +608,236 @@ img,svg { display:block; }
|
|
|
432
608
|
.sidebar-list { display:flex; flex-direction:column; gap:var(--space-1); margin:0; padding:0; list-style:none; }
|
|
433
609
|
/* `width:100%` + `font:inherit` + `border:0`: o item também é <button> quando não navega, e
|
|
434
610
|
sem isto o botão vem com a caixa do navegador e quebra a fila. */
|
|
435
|
-
.sidebar-item { display:flex; align-items:center; gap:var(--space-2); width:100%; min-height:var(--control-h-md); padding:var(--space-1) var(--space-3); border:0; border-radius:var(--radius-
|
|
611
|
+
.sidebar-item { display:flex; align-items:center; gap:var(--space-2); width:100%; min-height:var(--control-h-md); padding:var(--space-1) var(--space-3); border:0; border-radius:calc(var(--radius-card) - var(--space-1)); background:transparent; color:var(--sidebar-foreground); font:inherit; font-size:var(--text-sm); text-align:start; text-decoration:none; cursor:pointer; }
|
|
436
612
|
.sidebar-item .icon { flex:none; opacity:.8; }
|
|
437
613
|
/* min-width:0 é o que deixa o ellipsis funcionar dentro do flex; sem ele o nome longo empurra
|
|
438
614
|
o acessório para fora da caixa em vez de cortar. */
|
|
439
615
|
.sidebar-label { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
440
|
-
|
|
441
|
-
|
|
616
|
+
/* A LATERAL SE PINTA COM OS TOKENS DELA, e isto é conserto de 20/08/2026 — o Victor viu.
|
|
617
|
+
Estas duas regras usavam `--secondary` e `--foreground`, que são tokens da PÁGINA. Na Aurea
|
|
618
|
+
isso nunca apareceu porque o painel e a página têm a mesma claridade nos dois temas; sob a
|
|
619
|
+
marca `lory`, onde a lateral é escura mesmo no tema claro (decisão de produto da Mallory), o
|
|
620
|
+
item atual virava uma pílula QUASE BRANCA com texto escuro em cima de um painel escuro. Ele
|
|
621
|
+
chamou de "cores invertidas", e é exatamente o que era.
|
|
622
|
+
`--sidebar-accent` e `--sidebar-accent-foreground` já eram PUBLICADOS e não tinham um único
|
|
623
|
+
uso no core — token publicado que ninguém usa é promessa sem entrega, e era o par certo o
|
|
624
|
+
tempo todo. O defeito não é da marca: a marca só o tornou visível. */
|
|
625
|
+
@media (hover:hover) and (pointer:fine) { .sidebar-item:hover { background:var(--sidebar-accent); } }
|
|
626
|
+
.sidebar-item[aria-current] { background:var(--sidebar-accent); color:var(--sidebar-accent-foreground); font-weight:var(--weight-medium); }
|
|
442
627
|
.sidebar-item[aria-current] .icon { opacity:1; }
|
|
443
|
-
|
|
628
|
+
/* Alinha com o TEXTO do item: padding do painel (4) + padding do item (12) = 16px. Com o
|
|
629
|
+
painel apertado, os 8px de antes deixavam a rubrica fora do prumo da lista. */
|
|
630
|
+
/* O rótulo de grupo também sai da escala da LATERAL, pelo mesmo motivo: `--subtle-foreground` é
|
|
631
|
+
apagado contra a página, e contra um painel escuro num tema claro ele some. Derivado do próprio
|
|
632
|
+
`--sidebar-foreground` em vez de token novo — a lateral não publica um "muted" dela. */
|
|
633
|
+
.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; }
|
|
444
634
|
.sidebar-sub { padding-inline-start:var(--space-5); }
|
|
445
635
|
/* RECOLHIDA — a lateral vira trilho de ícones. O rótulo NÃO some do DOM: o React troca a
|
|
446
636
|
classe dele por `.sr-only`, então quem usa leitor de tela continua ouvindo o nome. Ícone
|
|
447
637
|
sozinho não nomeia nada, e essa é a falha clássica do padrão de trilho. */
|
|
448
638
|
.sidebar-collapsed { padding-inline:var(--space-2); }
|
|
449
|
-
|
|
639
|
+
/* NO TRILHO O ITEM É QUADRADO E CENTRADO, não uma linha esticada. Medido no fonte da referência
|
|
640
|
+
em 18/08/2026: `NavButton` com `iconOnly` é `size-9` — 36×36, exatamente o nosso `--control-h-md`.
|
|
641
|
+
Antes o item herdava `width:100%` e virava 71×36 dentro de um trilho de 88: um retângulo largo
|
|
642
|
+
que, com o raio de linha, fechava nas pontas e lia como CÁPSULA. Quadrado é o que a referência
|
|
643
|
+
desenha, e é o que o olho reconhece como botão de ícone. */
|
|
644
|
+
.sidebar-collapsed .sidebar-item { justify-content:center; width:var(--control-h-md); padding-inline:0; margin-inline:auto; }
|
|
450
645
|
.sidebar-collapsed .sidebar-sub { padding-inline-start:0; }
|
|
451
|
-
/*
|
|
452
|
-
lateral não consegue encolher a própria
|
|
646
|
+
/* Estas regras tocam `.app-shell` porque a coluna do grid é do shell: a
|
|
647
|
+
lateral não consegue encolher a própria trilha. `--sidebar-rail` continua sendo a largura
|
|
648
|
+
do PAINEL; a flutuante soma as margens na trilha, a rente usa o token cru.
|
|
453
649
|
O `>` NÃO É ENFEITE, e quem achou isso foi o navegador em 06/08/2026. Escrita como
|
|
454
650
|
`:has(.sidebar-collapsed)`, a regra casa com QUALQUER descendente — e a página do catálogo
|
|
455
651
|
que mostra uma lateral recolhida como EXEMPLO, dentro do <main>, recolhia a lateral de
|
|
456
652
|
verdade do documento inteiro. Medido: a coluna do shell saía 88px numa página que não pediu
|
|
457
653
|
nada. Gate nenhum via, porque `sidebar.html` não tem baseline de pixel. */
|
|
458
|
-
.app-shell:has(> .sidebar-collapsed) {
|
|
654
|
+
.app-shell:has(> .sidebar-collapsed) { --sidebar-track:calc(var(--sidebar-rail) + var(--space-4)*2); }
|
|
655
|
+
.app-shell:has(> .sidebar-collapsed.sidebar-flush) { --sidebar-track:var(--sidebar-rail); }
|
|
656
|
+
|
|
657
|
+
/* ── Navegação inferior — o vocabulário de APLICATIVO ───────────────────────────────
|
|
658
|
+
Lacuna estrutural medida no `CONSUMIDOR-GARAGEM.md` §4.1: `.topbar` e `.sidebar` são
|
|
659
|
+
vocabulário de DESKTOP, e aplicativo não navega assim.
|
|
660
|
+
`sticky` e NÃO `fixed`, e a razão é o catálogo: fixo escapa do contêiner e a prévia
|
|
661
|
+
cobriria a página inteira — o mesmo defeito que o `:has(> …)` da linha acima pagou.
|
|
662
|
+
Grudado no fim do fluxo dá o mesmo efeito e degrada para estático sem rolagem.
|
|
663
|
+
O `max()` do recuo inferior é o que impede a barra de ficar SOB o indicador de tela
|
|
664
|
+
cheia do iPhone. Ele só tem efeito se o consumidor declarar `viewport-fit=cover` na
|
|
665
|
+
meta viewport (está na ficha); sem isso `env()` devolve 0 e o `max()` entrega o
|
|
666
|
+
espaço normal — degrada, não quebra. Nenhuma das nove referências usa isto: medido,
|
|
667
|
+
`grep -ri safe-area-inset Referencia/` = 0. Veio de pesquisa, pelo BUILDING.md §2
|
|
668
|
+
passo 4. */
|
|
669
|
+
.bottom-nav { --bottomnav-ring:2rem; --bottomnav-surface:var(--card); position:sticky; bottom:0; z-index:var(--z-sticky); display:flex; gap:var(--space-1); margin:var(--space-4); padding:var(--space-1); padding-bottom:max(var(--space-1),env(safe-area-inset-bottom)); border:1px solid var(--border); border-radius:var(--radius-control); background:var(--card); color:var(--card-foreground); box-shadow:var(--shadow-md); }
|
|
670
|
+
/* `--control-h-lg` e não `--control-h-md`: alvo de toque. O md dá 36px em comfortable e
|
|
671
|
+
o alvo confortável de dedo é maior — com o recuo, o item renderiza acima de 44px. */
|
|
672
|
+
.bottom-nav-item { flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:var(--space-1); min-height:var(--control-h-lg); padding:var(--space-1); border:0; border-radius:var(--radius-control); background:transparent; color:var(--muted-foreground); font:inherit; font-size:var(--text-xs); text-align:center; text-decoration:none; cursor:pointer; }
|
|
673
|
+
.bottom-nav-item .icon { flex:none; opacity:.8; }
|
|
674
|
+
.bottom-nav-label { max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
675
|
+
/* O CONTADOR PENDURA NO ÍCONE — canto superior da ponta, encostando na borda dele.
|
|
676
|
+
A primeira versão pendurava no ITEM, com `inset-inline-start:50%`: em barra de coluna passa
|
|
677
|
+
despercebido, e na variante de LINHA os 50% do item caem no meio do RÓTULO. O Victor achou
|
|
678
|
+
assim, com o número cobrindo o nome inteiro (17/08/2026).
|
|
679
|
+
A pesquisa que corrigiu: Material 3 põe o distintivo "sobre o ícone, no canto superior
|
|
680
|
+
direito", e os guias de barra de abas do iOS dizem o mesmo com a razão junto — encostar na
|
|
681
|
+
borda é para ser visto, sobrepor conteúdo é hesitação num controle que se usa o tempo todo.
|
|
682
|
+
`inset-inline-end` e não `right`: o eixo espelha sozinho em RTL, e transform não espelharia.
|
|
683
|
+
O `min-` da caixa é para o contador ter onde se ancorar quando o item não tem ícone.
|
|
684
|
+
A CAIXA É `--icon-lg` (24px) e o contador `--space-4` (16px) porque a PROPORÇÃO foi medida
|
|
685
|
+
em aplicativo que roda: WhatsApp, YouTube, Mercado Livre e Shopee, nos prints do Victor de
|
|
686
|
+
17/08/2026 — ícone ~24, contador ~16, razão **0,67**. A primeira versão tinha ícone de 16 e
|
|
687
|
+
contador de 18: razão 1,12, o contador MAIOR que o ícone. Foi o que ele viu e mandou refazer. */
|
|
688
|
+
/* A MOLDURA É FIXA E VALE PARA OS SETE INDICADORES. Medido em 20/08/2026, e quem viu foi o
|
|
689
|
+
Victor: os três indicadores redondos saíam com a BARRA MAIS LARGA que os outros quatro, porque
|
|
690
|
+
só eles davam largura à moldura e a largura do item vinha do conteúdo. Trocar de indicador
|
|
691
|
+
mudava a medida da barra — que é o defeito estrutural que esta reescrita existe para acabar.
|
|
692
|
+
O achado 8 da auditoria pede a mesma coisa por outro caminho: o contador tem de se ancorar na
|
|
693
|
+
caixa do ícone e ficar PREVISÍVEL, e caixa que muda de tamanho conforme a variante não é
|
|
694
|
+
ancoragem previsível. Agora quem pinta é o indicador; quem MEDE é sempre esta regra.
|
|
695
|
+
|
|
696
|
+
O NÚMERO É PESQUISADO, e a exigência é do Victor em 20/08/2026: *"vá pesquisar e descubra qual
|
|
697
|
+
padrão é usado, pesquise não invente medidas"*. Ele pegou 2.25rem saído da minha cabeça.
|
|
698
|
+
`2rem` = 32px é a ALTURA DO INDICADOR ATIVO do Material 3 (`m3.material.io/components/
|
|
699
|
+
navigation-bar/specs` e a doc do `material-components-android`: indicador 64×32dp, canto
|
|
700
|
+
totalmente arredondado, sobre um ícone de 24dp). 24 de ícone dentro de 32 deixa 4 de folga de
|
|
701
|
+
cada lado, que é a mesma folga de 4dp que o M3 usa entre o indicador e o rótulo.
|
|
702
|
+
O ALVO DE TOQUE não é este número e continua sendo o `min-height` do item: `--control-h-lg`
|
|
703
|
+
entrega 42px em comfortable e 48 em spacious, contra os 44pt mínimos da HIG da Apple e os
|
|
704
|
+
48dp do Material. A moldura é a caixa do DESENHO; o alvo é o item inteiro. */
|
|
705
|
+
.bottom-nav-mark { position:relative; flex:none; display:inline-flex; align-items:center; justify-content:center; width:var(--bottomnav-ring); height:var(--bottomnav-ring); border-radius:var(--radius-control); }
|
|
706
|
+
/* `inline-flex` no envoltório: como `<span>` solto ele é caixa de LINHA, e mede a entrelinha do
|
|
707
|
+
item (18px) em vez do contador que carrega (16px). A diferença não aparece na tela — aparece
|
|
708
|
+
na medição, e medição errada é o que faz a razão parecer 0,75 quando é 0,67. */
|
|
709
|
+
.bottom-nav-badge { position:absolute; display:inline-flex; inset-block-start:calc(var(--space-05)*-1); inset-inline-end:calc(var(--space-05)*-1); }
|
|
710
|
+
/* O contador da barra usa `<Badge size="xs">`, e NÃO uma sobrescrita local de `.badge` aqui.
|
|
711
|
+
A primeira versão sobrescrevia, e o `geometry.spec` reprovou com razão: `.badge` tem altura
|
|
712
|
+
ÚNICA por contrato, e uma regra contextual fazia o mesmo nome medir 16px numa página e 24px
|
|
713
|
+
noutra. Tamanho é do componente, não do lugar onde ele cai. */
|
|
714
|
+
/* SEM NÚMERO, É PONTO. Três dos quatro aplicativos medidos usam o ponto puro para "tem coisa
|
|
715
|
+
nova" — YouTube (Inscrições), WhatsApp (Atualizações e Você). O consumidor pede pelo vazio:
|
|
716
|
+
`badge: ""`. A cor é a de AVISO e não a da marca, também como nos quatro: o contador não é
|
|
717
|
+
decoração do item atual, é alerta.
|
|
718
|
+
⚠ Ponto não tem nome acessível — não há o que ler. Quem usa ponto põe o sentido no RÓTULO do
|
|
719
|
+
item (`label: <>Updates <span className="sr-only">(new)</span></>`). Está na ficha. */
|
|
720
|
+
.bottom-nav-badge:empty { width:var(--space-2); height:var(--space-2); border-radius:var(--radius-full); background:var(--primary); }
|
|
721
|
+
/* SEM REALCE DE PASSAR O MOUSE, e isso é decisão do Victor em 20/08/2026: *"essa bola cinza
|
|
722
|
+
que aparece quando mouse passar em cima pode retirar, é um recurso irrelevante no celular"*.
|
|
723
|
+
Ele tem razão pelo escopo do componente: esta barra é o chrome de aplicativo de TELEFONE, e o
|
|
724
|
+
dedo não tem estado de passar por cima. Pior: o realce cinza desenhava a MESMA forma que o
|
|
725
|
+
indicador `subtle` usa para dizer "você está aqui", então passar o mouse por um item inativo
|
|
726
|
+
fingia seleção — dois significados no mesmo desenho.
|
|
727
|
+
O FOCO CONTINUA, e a diferença não é de gosto: `:focus-visible` é o que o teclado enxerga, vem
|
|
728
|
+
do contrato de foco global e o `geometry.spec` cobra. Tirar hover é tirar enfeite; tirar foco
|
|
729
|
+
seria tirar acesso. */
|
|
730
|
+
.bottom-nav-item[aria-current] { color:var(--foreground); font-weight:var(--weight-medium); }
|
|
731
|
+
.bottom-nav-item[aria-current] .icon { opacity:1; }
|
|
732
|
+
/* ── A GRAMÁTICA: DOIS EIXOS, E ELES NÃO SE MISTURAM ────────────────────────────────
|
|
733
|
+
Reescrito em 20/08/2026 pela auditoria de UI/UX do BottomNav que o Victor encomendou.
|
|
734
|
+
O achado dela não é estético, é ESTRUTURAL: `flat`, `surface`, `pill` e `dock` eram quatro
|
|
735
|
+
implementações conceitualmente separadas — cada uma dizia "esta é a página atual" com uma
|
|
736
|
+
linguagem diferente (uma pela cor, outra por cápsula cinza, outra por bloco amarelo), e duas
|
|
737
|
+
delas escondiam o rótulo. Trocar de variante trocava o MODELO MENTAL do componente, não a
|
|
738
|
+
forma dele.
|
|
739
|
+
|
|
740
|
+
Agora são dois eixos independentes, e é isso que faz variante ser variante:
|
|
741
|
+
|
|
742
|
+
• LAYOUT (a barra) — `floating` (padrão, pílula solta) e `edge` (encostada, fio em cima).
|
|
743
|
+
• INDICADOR (o item) — a FORMA que marca o atual. A SEMÂNTICA é sempre a mesma: ouro.
|
|
744
|
+
|
|
745
|
+
O que TODO indicador compartilha, e por isso vive aqui em cima e não dentro de cada um:
|
|
746
|
+
altura de alvo, moldura do ícone, tipografia, ancoragem do contador, rótulo sempre visível.
|
|
747
|
+
A auditoria pedia exatamente isso — "a variante altera a forma, não toda a lógica visual".
|
|
748
|
+
|
|
749
|
+
O RÓTULO NUNCA SOME em nenhum indicador. Era o defeito 6/7 da auditoria: a `dock` escondia
|
|
750
|
+
todos e a `pill` escondia os inativos, e as sete telas que o Victor desenhou mostram o rótulo
|
|
751
|
+
em todos os itens, nas sete. Ícone sozinho só funciona quando o símbolo é inequívoco, e
|
|
752
|
+
`Garage`/`Fuel`/`Service` não são.
|
|
753
|
+
|
|
754
|
+
`--bottomnav-ring` é a moldura do ícone quando o indicador é redondo. Válvula no idioma do
|
|
755
|
+
`--chart-h` e do `--datagrid-max-h`: quem hospeda decide, o componente não vira prop nova. */
|
|
756
|
+
.bottom-nav-edge { --bottomnav-surface:var(--background); margin:0; padding-inline:0; border-width:1px 0 0; border-radius:0; background:var(--background); box-shadow:none; }
|
|
757
|
+
/* `--primary-emphasis` e não `--primary`: sem fundo, a marca vira TEXTO, e o amarelo puro
|
|
758
|
+
sobre o claro não se lê. É o mesmo token que o `.badge-primary` já usa por essa razão. */
|
|
759
|
+
.bottom-nav-ind-none .bottom-nav-item[aria-current] { color:var(--primary-emphasis); }
|
|
760
|
+
.bottom-nav-ind-none .bottom-nav-item[aria-current] .icon { opacity:1; }
|
|
761
|
+
/* SUAVE e PÍLULA envolvem ícone E rótulo — muda só o raio. O fundo é o amarelo a 12%, a mesma
|
|
762
|
+
receita do `.badge-primary`, e não um cinza: a auditoria mediu que a cápsula cinza da antiga
|
|
763
|
+
`surface` tirava a cor da marca justo do estado mais importante da barra. */
|
|
764
|
+
.bottom-nav-ind-subtle .bottom-nav-item[aria-current],.bottom-nav-ind-pill .bottom-nav-item[aria-current] { background:color-mix(in srgb,var(--primary) 12%,transparent); color:var(--primary-emphasis); }
|
|
765
|
+
.bottom-nav-ind-subtle .bottom-nav-item[aria-current] .icon,.bottom-nav-ind-pill .bottom-nav-item[aria-current] .icon { opacity:1; }
|
|
766
|
+
.bottom-nav-ind-subtle .bottom-nav-item { border-radius:calc(var(--radius-card) - var(--space-1)); }
|
|
767
|
+
.bottom-nav-ind-pill .bottom-nav-item { border-radius:var(--radius-control); }
|
|
768
|
+
/* OS QUATRO REDONDOS envolvem SÓ O ÍCONE, e o rótulo fica embaixo, fora da forma. É o que as
|
|
769
|
+
quatro telas do Victor mostram e o que o WhatsApp faz no aplicativo que roda; pintar o item
|
|
770
|
+
inteiro não aparece em nenhum dos dois lugares. A moldura vira quadrado de lado fixo para ser
|
|
771
|
+
CÍRCULO e não elipse — o rótulo é que é largo, e ele está fora daqui. */
|
|
772
|
+
.bottom-nav-ind-circle .bottom-nav-mark,.bottom-nav-ind-circle-raised .bottom-nav-mark,.bottom-nav-ind-circle-outline .bottom-nav-mark { border-radius:var(--radius-full); }
|
|
773
|
+
.bottom-nav-ind-circle .bottom-nav-item[aria-current],.bottom-nav-ind-circle-raised .bottom-nav-item[aria-current],.bottom-nav-ind-circle-outline .bottom-nav-item[aria-current] { color:var(--primary-emphasis); }
|
|
774
|
+
.bottom-nav-ind-circle .bottom-nav-item[aria-current] .icon,.bottom-nav-ind-circle-raised .bottom-nav-item[aria-current] .icon,.bottom-nav-ind-circle-outline .bottom-nav-item[aria-current] .icon { opacity:1; }
|
|
775
|
+
.bottom-nav-ind-circle .bottom-nav-item[aria-current] .bottom-nav-mark { background:color-mix(in srgb,var(--primary) 14%,transparent); }
|
|
776
|
+
/* ELEVADO: a moldura é uma superfície PRÓPRIA sobre a barra — por isso `--popover` e sombra, e
|
|
777
|
+
não uma cor de fundo. É o único indicador que usa profundidade em vez de cor para separar. */
|
|
778
|
+
.bottom-nav-ind-circle-raised .bottom-nav-item[aria-current] .bottom-nav-mark { background:var(--popover); box-shadow:var(--shadow-md); }
|
|
779
|
+
.bottom-nav-ind-circle-outline .bottom-nav-item[aria-current] .bottom-nav-mark { border:1px solid var(--primary-emphasis); }
|
|
780
|
+
/* CHEIO é o único que preenche com o amarelo sólido, e por isso é o único que troca o primeiro
|
|
781
|
+
plano inteiro para `--primary-foreground` — ícone, rótulo e contador juntos dentro da forma.
|
|
782
|
+
A auditoria recusou a antiga `pill` sólida (achado 5: "o ativo assume presença de CTA"), e a
|
|
783
|
+
diferença aqui é a FORMA: círculo do tamanho do alvo de toque lê como destino marcado; cápsula
|
|
784
|
+
larga, esticada pelo rótulo, lê como botão de ação primária dentro da navegação. */
|
|
785
|
+
/* 3.5rem = 56px, e também é número de fora: é a largura do indicador ativo do Material 3
|
|
786
|
+
Expressive (56dp) e a altura do indicador expandido na mesma doc. É a única forma aqui que
|
|
787
|
+
envolve ícone E rótulo, então usa a medida expandida e não a de 32. */
|
|
788
|
+
.bottom-nav-ind-circle-bold .bottom-nav-item[aria-current] { flex:none; width:var(--bottomnav-bold,3.5rem); border-radius:var(--radius-full); background:var(--primary); color:var(--primary-foreground); }
|
|
789
|
+
.bottom-nav-ind-circle-bold .bottom-nav-item[aria-current] .icon { opacity:1; }
|
|
790
|
+
/* O contador do `circle-bold` INVERTE, como o do `.btn-primary`, e a volta atrás está medida.
|
|
791
|
+
Tentei em 20/08/2026 deixá-lo dourado com um anel da cor da barra em volta — é o que as telas
|
|
792
|
+
do Victor mostram. O gate de contraste reprovou no tema CLARO: sobre o amarelo sólido, nem o
|
|
793
|
+
fundo do contador nem o anel branco chegam a 3:1. No escuro passava, e é assim que este defeito
|
|
794
|
+
se esconde. Fio fino não substitui contraste quando as duas cores são claras. */
|
|
795
|
+
.bottom-nav-ind-circle-bold .bottom-nav-item[aria-current] .badge { background:var(--primary-foreground); color:var(--primary); border-color:transparent; }
|
|
796
|
+
.bottom-nav-ind-circle-bold .bottom-nav-item[aria-current] .bottom-nav-badge { color:var(--primary-foreground); }
|
|
797
|
+
|
|
798
|
+
/* ── A LINHA DE LISTA TOCÁVEL (§4.3 do CONSUMIDOR-GARAGEM) ──────────────────────────
|
|
799
|
+
A LISTA NÃO PINTA SUPERFÍCIE. Quem dá o card é o `Card`, e repintar aqui seria um segundo
|
|
800
|
+
lugar para a mesma coisa — a `DIRECTION.md` §3.9 diz que composto REUSA o menor.
|
|
801
|
+
E SEM DIVISOR entre as linhas, que é decisão e não esquecimento: o realce de linha desta casa
|
|
802
|
+
é a PÍLULA (é o que `.sidebar-item` faz), e pílula com traço embaixo se contradizem — o traço
|
|
803
|
+
promete grade, a pílula promete alvo. Quem agrupa é a superfície de fora. */
|
|
804
|
+
.nav-list { display:flex; flex-direction:column; gap:var(--space-05); margin:0; padding:0; list-style:none; }
|
|
805
|
+
/* ── O RAIO DA LINHA SAI DE UMA CONTA, NÃO DE UM NÚMERO ─────────────────────────────
|
|
806
|
+
`raio do filho = raio do pai − padding do pai`. É o que faz o vão ser CONSTANTE na curva; sem
|
|
807
|
+
isso a curva da linha e a curva do painel divergem e o olho vê o desalinhamento antes de
|
|
808
|
+
qualquer medição — foi o Victor que achou, riscando o canto num print (18/08/2026).
|
|
809
|
+
POR QUE A PÍLULA NÃO SERVE AQUI, medido: `999px` não desenha 999 — o navegador limita à METADE
|
|
810
|
+
DA ALTURA. Então o raio efetivo da pílula MUDA com a altura da linha: 21px numa linha de um
|
|
811
|
+
texto, 26,8px numa de dois. Com o card em 22px e padding 4px o erro era de **8,8px**, e nenhum
|
|
812
|
+
raio de card conserta os dois casos ao mesmo tempo. A conta conserta sempre.
|
|
813
|
+
Escrito como `calc()` de propósito: se alguém mudar o raio do card ou o padding, a linha segue
|
|
814
|
+
sozinha. Número cravado divergiria em silêncio. */
|
|
815
|
+
.nav-list-row { display:flex; align-items:center; gap:var(--space-3); width:100%; min-height:var(--control-h-lg); padding:var(--space-2) var(--space-3); border:0; border-radius:calc(var(--radius-card) - var(--space-1)); background:transparent; color:var(--foreground); font:inherit; font-size:var(--text-sm); text-align:start; text-decoration:none; cursor:pointer; }
|
|
816
|
+
.nav-list-row .icon { flex:none; opacity:.8; }
|
|
817
|
+
/* O TEXTO É A ÚNICA TRILHA QUE ENCOLHE, e o par `flex:1` + `min-width:0` é o que faz isso: sem o
|
|
818
|
+
`min-width:0` o conteúdo mínimo do flex é o texto inteiro, e o rótulo longo empurra o valor e a
|
|
819
|
+
seta para fora da linha em vez de reticenciar. É a mesma família do defeito que a `pill` da
|
|
820
|
+
barra inferior pagou em 18/08/2026 — lá o rótulo virava zero, aqui ele expulsaria os vizinhos. */
|
|
821
|
+
.nav-list-text { flex:1; min-width:0; display:flex; flex-direction:column; }
|
|
822
|
+
.nav-list-label { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
823
|
+
.nav-list-description { overflow:hidden; color:var(--muted-foreground); font-size:var(--text-xs); text-overflow:ellipsis; white-space:nowrap; }
|
|
824
|
+
/* O VALOR E A SETA NÃO ENCOLHEM: valor cortado MENTE (um "R$ 1.2" no lugar de "R$ 1.234"), e seta
|
|
825
|
+
cortada deixa de dizer que a linha abre. Quem cede espaço é o texto, que reticencia dizendo. */
|
|
826
|
+
.nav-list-value { flex:none; color:var(--muted-foreground); font-size:var(--text-sm); }
|
|
827
|
+
.nav-list-row .nav-list-chevron { flex:none; opacity:.6; }
|
|
828
|
+
@media (hover:hover) and (pointer:fine) { .nav-list-row:hover { background:var(--secondary); } }
|
|
829
|
+
/* `aria-disabled` e NÃO `:disabled` — a razão está escrita ao lado de `.btn:disabled`, medida em
|
|
830
|
+
13/08/2026: `:disabled` tira da ordem de foco e quem usa teclado nunca acha a linha. */
|
|
831
|
+
.nav-list-row[aria-disabled="true"] { opacity:.45; cursor:not-allowed; }
|
|
832
|
+
/* O PAINEL DÁ QUASE NADA, A LINHA DÁ O RESTO. Medido em 18/08/2026, depois de o Victor circular a
|
|
833
|
+
folga no print: com o `--card-pad` de 20px o realce da linha começava a 21px da borda e o texto
|
|
834
|
+
a 65px, e a linha ocupava só 88% da largura — realce flutuando no meio de uma caixa grande em
|
|
835
|
+
vez de preencher o painel. `--card-pad` é padding de CONTEÚDO; lista de linhas tocáveis quer
|
|
836
|
+
outra escala. É a anatomia dos dois exemplos de `NavigationMenu` que ele mandou: o item leva
|
|
837
|
+
`p-3` (que a nossa linha já tem) e o contêiner quase não leva nada.
|
|
838
|
+
Filho DIRETO de propósito: um card com layout grande e uma lista pequena dentro não pode perder
|
|
839
|
+
o padding dele. E `:has()` já é idioma desta folha (quatro usos antes deste). */
|
|
840
|
+
.card:has(> .nav-list) { padding:var(--space-1); }
|
|
459
841
|
|
|
460
842
|
/* ── Visibilidade responsiva — o mecanismo PADRÃO de colapsar uma barra ─────────────
|
|
461
843
|
Regra do projeto (enraizada): todo layout horizontal que aperta esconde o secundário
|
|
@@ -471,9 +853,9 @@ img,svg { display:block; }
|
|
|
471
853
|
/* .nav-group-label é o rótulo de categoria SEM ser título de documento: mesma aparência do
|
|
472
854
|
h4 histórico, mas o grupo se nomeia por aria-labelledby e não entra na lista de títulos
|
|
473
855
|
do leitor de tela (senão a lateral vem antes do h1 da página). É o jeito preferido. */
|
|
474
|
-
.doc-nav h4,.doc-nav .nav-group-label { margin:16px 8px 8px; color:var(--
|
|
856
|
+
.doc-nav h4,.doc-nav .nav-group-label { margin:16px 8px 8px; color:color-mix(in oklab, var(--sidebar-foreground) 70%, transparent); font-size:11px; letter-spacing:var(--tracking-widest); text-transform:uppercase; }
|
|
475
857
|
.doc-nav .nav-group { display:grid; gap:var(--space-1); }
|
|
476
|
-
.doc-nav a { display:flex; align-items:center; gap:10px; min-height:40px; margin:0; padding:9px 12px; border:1px solid transparent; border-radius:var(--radius-lg); background:transparent; color:var(--
|
|
858
|
+
.doc-nav a { display:flex; align-items:center; gap:10px; min-height:40px; margin:0; padding:9px 12px; border:1px solid transparent; border-radius:var(--radius-lg); background:transparent; color:color-mix(in oklab, var(--sidebar-foreground) 72%, transparent); text-decoration:none; box-shadow:none; }
|
|
477
859
|
.doc-nav a:hover { color:var(--sidebar-accent-foreground); background:var(--sidebar-accent); border-color:var(--sidebar-border); }
|
|
478
860
|
.doc-nav a.active { border-color:var(--sidebar-border); }
|
|
479
861
|
/* o glifo da família fica na frente do rótulo e nunca encolhe o texto */
|
|
@@ -649,29 +1031,119 @@ img,svg { display:block; }
|
|
|
649
1031
|
grita mais que o próprio rótulo. No tema CLARO o amarelo puro como texto dá 1.6:1, longe
|
|
650
1032
|
dos 4.5:1 do AA, então o rótulo aprofunda com --foreground e segue âmbar. */
|
|
651
1033
|
.is-selected,.btn-nav[aria-current]:not([aria-current="false"]),.btn[aria-pressed="true"],
|
|
652
|
-
.segmented button.active
|
|
1034
|
+
.segmented button.active { --btn-bg:var(--secondary); --btn-fg:var(--primary); position:relative; background:var(--secondary); color:var(--primary); }
|
|
1035
|
+
/* O ATIVO DA NAV DA LATERAL sai da escala DELA, e não da página (20/08/2026, o Victor viu sob a
|
|
1036
|
+
marca `lory`). Ele dividia esta regra com o `.segmented`, que vive no conteúdo — e `--secondary`
|
|
1037
|
+
é quase branco no tema claro. Numa lateral escura isso desenhava uma pílula branca com texto
|
|
1038
|
+
escuro: as cores invertidas que ele apontou.
|
|
1039
|
+
`--sidebar-accent` e `--sidebar-primary` já eram publicados e não tinham uso no core. O segundo
|
|
1040
|
+
é o que mantém a MARCA no item atual: fundo da lateral, texto da marca. */
|
|
1041
|
+
.doc-nav a.active { position:relative; background:var(--sidebar-accent); color:var(--sidebar-primary); }
|
|
1042
|
+
/* E O ITEM EM REPOUSO PRECISA DA MESMA PROTEÇÃO, por um motivo de ESPECIFICIDADE que só apareceu
|
|
1043
|
+
medindo a tela do Victor em 20/08/2026 — eu tinha medido o ATIVO e dado o conserto por pronto.
|
|
1044
|
+
Os links da lateral do catálogo não têm atributo `class`, então `[data-theme="light"]
|
|
1045
|
+
a:not([class])` — a regra que existe para LINK DE PROSA — casa com eles. Ela pesa (0,2,1) e a
|
|
1046
|
+
`.doc-nav a` pesa (0,1,1): a regra de prosa ganhava e pintava o item com
|
|
1047
|
+
`color-mix(--primary, --foreground)`. Sob a marca `lory` isso deu MARROM ESCURO
|
|
1048
|
+
(`oklab(0.44 0.059 0.051)`) sobre um painel escuro — ilegível, e foi o que ele viu.
|
|
1049
|
+
Mesmo peso, e depois na folha: quem manda no que está DENTRO da lateral é a lateral.
|
|
1050
|
+
`:not(.active)` NÃO é enfeite — a primeira versão desta linha não tinha, pesava igual à regra do
|
|
1051
|
+
item atual e, vindo depois, APAGAVA o laranja dele. Medido no mesmo minuto: ativo e inativo
|
|
1052
|
+
saíram com a mesma cor. Com o `:not` ela pesa (0,3,1) e só alcança quem está em repouso. */
|
|
1053
|
+
[data-theme="light"] .doc-nav a:not(.active) { color:color-mix(in oklab, var(--sidebar-foreground) 72%, transparent); }
|
|
653
1054
|
.is-selected::after,.btn-nav[aria-current]:not([aria-current="false"])::after,
|
|
654
1055
|
.btn[aria-pressed="true"]:not(.btn-icon)::after,.segmented button.active::after,
|
|
655
1056
|
.doc-nav a.active::after { content:""; position:absolute; inset-inline:15px; bottom:0; height:2px; border-radius:var(--radius-full); background:color-mix(in oklab, var(--primary) 75%, transparent); }
|
|
1057
|
+
/* e o fio do ativo da lateral segue a marca DELA, pelo mesmo motivo da regra de cor acima. */
|
|
1058
|
+
.doc-nav a.active::after { background:color-mix(in oklab, var(--sidebar-primary) 75%, transparent); }
|
|
656
1059
|
[data-theme="light"] .is-selected,[data-theme="light"] .btn-nav[aria-current]:not([aria-current="false"]),
|
|
657
|
-
[data-theme="light"] .btn[aria-pressed="true"],[data-theme="light"] .segmented button.active
|
|
658
|
-
|
|
1060
|
+
[data-theme="light"] .btn[aria-pressed="true"],[data-theme="light"] .segmented button.active
|
|
1061
|
+
{ --btn-fg:color-mix(in oklab, var(--primary) 45%, var(--foreground)); color:color-mix(in oklab, var(--primary) 45%, var(--foreground)); }
|
|
1062
|
+
/* A NAV DA LATERAL SAIU DESTA LISTA em 20/08/2026. O ajuste existe porque o amarelo puro não se lê
|
|
1063
|
+
sobre o claro — mas ele mistura o `--foreground` da PÁGINA, e o item da lateral não está sobre a
|
|
1064
|
+
página: está sobre `--sidebar-accent`. Sob a marca `lory`, onde esse fundo é escuro no tema
|
|
1065
|
+
claro, a mistura escurecia o texto contra um fundo escuro. Quem manda ali é `--sidebar-primary`,
|
|
1066
|
+
que cada marca já publica com a claridade certa para o painel dela. */
|
|
659
1067
|
|
|
660
1068
|
/* `line-height:1` não é enfeite: sem ele o .badge herdava a entrelinha do pai e a MESMA
|
|
661
1069
|
classe media 26px dentro do .brand (lh 18px) e 22px dentro de um .btn-nav (lh 12px) — na
|
|
662
1070
|
mesma barra (achado A2, 26/07/2026). Geometria de componente não se decide pelo contexto.
|
|
663
1071
|
O .chip do catálogo já tinha aprendido isso; o .badge não. */
|
|
664
|
-
.badge { display:inline-flex; align-items:center; gap:6px; min-height:var(--space-6); padding:3px 9px; border:1px solid var(--border); border-radius:var(--radius-control); background:var(--secondary); color:var(--secondary-foreground); font-size:var(--text-xs); font-weight:var(--weight-medium); line-height:var(--leading-none); white-space:nowrap; }
|
|
1072
|
+
.badge { --badge-accent:var(--secondary-foreground); display:inline-flex; align-items:center; justify-content:center; gap:6px; min-height:var(--space-6); padding:3px 9px; border:1px solid var(--border); border-radius:var(--radius-control); background:var(--secondary); color:var(--secondary-foreground); font-size:var(--text-xs); font-weight:var(--weight-medium); line-height:var(--leading-none); white-space:nowrap; }
|
|
665
1073
|
/* O glifo do badge tem tamanho PRÓPRIO, senão o `.icon` padrão (20px) estoura os 24px e o
|
|
666
1074
|
badge com ícone fica mais alto que o badge de texto na mesma fila. 16px + 3+3 de padding
|
|
667
1075
|
+ 1+1 de borda = 24px exatos: com ícone ou sem, mede o mesmo. */
|
|
668
1076
|
.badge .icon { width:var(--icon-sm); height:var(--icon-sm); }
|
|
669
|
-
.badge-primary { color:var(--primary-emphasis); border-color:var(--primary-outline); background:color-mix(in srgb,var(--primary) 10%,transparent); }
|
|
1077
|
+
.badge-primary { --badge-accent:var(--primary-emphasis); color:var(--primary-emphasis); border-color:var(--primary-outline); background:color-mix(in srgb,var(--primary) 10%,transparent); }
|
|
1078
|
+
/* TAMANHOS. O md é a base (24px), que não muda — é o que as 103 fichas já usam. */
|
|
1079
|
+
.badge-xs { min-height:var(--space-4); padding:0 var(--space-1); border-width:0; }
|
|
1080
|
+
.badge-sm { min-height:var(--space-5); padding:0 var(--space-2); }
|
|
1081
|
+
.badge-lg { min-height:var(--space-7); padding:0 var(--space-3); font-size:var(--text-sm); }
|
|
1082
|
+
/* ACESSÓRIOS de dentro do chip. O ponto herda a cor do texto por `currentColor`, então ele
|
|
1083
|
+
acompanha variante e ênfase sem uma regra por combinação. */
|
|
1084
|
+
.badge-dot { flex:none; width:var(--space-2); height:var(--space-2); border-radius:var(--radius-full); background:currentColor; }
|
|
1085
|
+
.badge-image { flex:none; width:var(--space-4); height:var(--space-4); border-radius:var(--radius-full); object-fit:cover; }
|
|
1086
|
+
.badge-dismiss { display:inline-flex; align-items:center; justify-content:center; flex:none; width:var(--space-4); height:var(--space-4); margin-inline-end:calc(var(--space-1)*-1); padding:0; border:0; border-radius:var(--radius-full); background:transparent; color:inherit; cursor:pointer; }
|
|
1087
|
+
.badge-dismiss:hover { background:color-mix(in srgb,currentColor 16%,transparent); }
|
|
1088
|
+
.badge-dismiss .icon { width:var(--space-3); height:var(--space-3); }
|
|
1089
|
+
|
|
1090
|
+
/* ── O BADGE SOBREPOSTO — contador no canto de outra coisa ──────────────────────────
|
|
1091
|
+
Anatomia da `Badge.js` da MUI, medida no fonte: raiz `relative/inline-flex/flex-shrink:0`,
|
|
1092
|
+
o contador `absolute` com `z-index:1`, e o deslocamento do canto valendo **0 para caixa
|
|
1093
|
+
quadrada e 14% para redonda** — é `overlap`, e sem ele o contador de um avatar fica solto
|
|
1094
|
+
fora do círculo.
|
|
1095
|
+
O ANEL DE RECORTE é o que faltava e o que fazia parecer sujo: um fio da cor da superfície
|
|
1096
|
+
entre o contador e o que está atrás. Três fontes independentes: `ring-[1.5px] ring-bg-primary`
|
|
1097
|
+
da Untitled UI, `border-background border-2` do ReUI e `box-shadow: 0 0 0 2px background.paper`
|
|
1098
|
+
do exemplo de contato da MUI.
|
|
1099
|
+
A superfície de trás NÃO é adivinhável em CSS — dentro de um card ela é `--card`, não
|
|
1100
|
+
`--background`. Por isso ela é uma propriedade: sobrescreva `--badge-ring` no contêiner. */
|
|
1101
|
+
.badge-anchor { position:relative; display:inline-flex; vertical-align:middle; flex-shrink:0; }
|
|
1102
|
+
.badge-overlay { --badge-ring:var(--background); --badge-inset:0%; position:absolute; z-index:1; min-height:var(--space-4); padding:0 var(--space-1); box-shadow:0 0 0 var(--space-05) var(--badge-ring); }
|
|
1103
|
+
.badge-on-circle { --badge-inset:14%; }
|
|
1104
|
+
/* O ponto sozinho não tem conteúdo, então ele precisa de medida própria. */
|
|
1105
|
+
.badge-overlay.badge-is-dot { width:var(--space-2); min-width:var(--space-2); height:var(--space-2); min-height:var(--space-2); padding:0; }
|
|
1106
|
+
.badge-at-top-end { inset-block-start:var(--badge-inset); inset-inline-end:var(--badge-inset); transform:translate(50%,-50%); }
|
|
1107
|
+
.badge-at-top-start { inset-block-start:var(--badge-inset); inset-inline-start:var(--badge-inset); transform:translate(-50%,-50%); }
|
|
1108
|
+
.badge-at-bottom-end { inset-block-end:var(--badge-inset); inset-inline-end:var(--badge-inset); transform:translate(50%,50%); }
|
|
1109
|
+
.badge-at-bottom-start { inset-block-end:var(--badge-inset); inset-inline-start:var(--badge-inset); transform:translate(-50%,50%); }
|
|
1110
|
+
/* `transform` não espelha sozinho, e `inset-inline-*` sim: em RTL o par sai trocado e o
|
|
1111
|
+
contador vai para dentro da caixa. As quatro regras abaixo são o preço disso. */
|
|
1112
|
+
.badge-at-top-end:dir(rtl) { transform:translate(-50%,-50%); }
|
|
1113
|
+
.badge-at-top-start:dir(rtl) { transform:translate(50%,-50%); }
|
|
1114
|
+
.badge-at-bottom-end:dir(rtl) { transform:translate(-50%,50%); }
|
|
1115
|
+
.badge-at-bottom-start:dir(rtl) { transform:translate(50%,50%); }
|
|
1116
|
+
/* ACESSÓRIO SOBRE A MARCA — o badge INVERTE quando o que está debaixo dele é o amarelo.
|
|
1117
|
+
Achado pelo Victor em 17/08/2026 na barra inferior, e a pergunta obrigatória do CLAUDE.md
|
|
1118
|
+
("quem mais tem esse problema?") devolveu um defeito ANTIGO e publicado: `.badge-primary`
|
|
1119
|
+
dentro de `.btn-primary` é amarelo translúcido com texto `--primary-emphasis` — medido no
|
|
1120
|
+
navegador, texto `oklch(0.795 0.184 86.047)` sobre fundo `oklch(0.795 0.184 86.047)`.
|
|
1121
|
+
Contraste 1:1, literalmente invisível, e nenhum gate via: check nenhum compara a cor de um
|
|
1122
|
+
filho com a do pai.
|
|
1123
|
+
A inversão é a saída óbvia e a única que não inventa cor nova — o par da marca já existe
|
|
1124
|
+
(`--primary`/`--primary-foreground`) e é o mesmo que o botão usa.
|
|
1125
|
+
O ENVOLTÓRIO leva só a cor de texto, nunca fundo: ele é a caixa de posição do acessório, e
|
|
1126
|
+
pintá-lo desenharia um retângulo atrás de um badge que é pílula. */
|
|
1127
|
+
.btn-primary .badge { background:var(--primary-foreground); color:var(--primary); border-color:transparent; }
|
|
1128
|
+
/* O `circle-bold` é o único indicador que preenche com o amarelo sólido, então é o único onde
|
|
1129
|
+
o contador cai sobre a cor da marca e precisa da mesma inversão do botão primário. Os outros
|
|
1130
|
+
seis deixam o contador sobre a superfície da barra, onde ele já se lê. */
|
|
670
1131
|
|
|
671
|
-
.badge-success { color:var(--success-400); background:var(--success-bg); border-color:color-mix(in srgb,var(--success-400) 35%,var(--border)); }
|
|
672
|
-
.badge-warning { color:var(--warning-400); background:var(--warning-bg); border-color:color-mix(in srgb,var(--warning-400) 35%,var(--border)); }
|
|
673
|
-
.badge-danger { color:var(--danger-400); background:var(--danger-bg); border-color:color-mix(in srgb,var(--danger-400) 35%,var(--border)); }
|
|
674
|
-
.badge-info,.badge-running { color:var(--info-400); background:var(--info-bg); border-color:color-mix(in srgb,var(--info-400) 35%,var(--border)); }
|
|
1132
|
+
.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)); }
|
|
1133
|
+
.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)); }
|
|
1134
|
+
.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)); }
|
|
1135
|
+
.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)); }
|
|
1136
|
+
/* ── AS TRÊS ÊNFASES — e elas vêm DEPOIS das variantes de propósito ─────────────────
|
|
1137
|
+
Cada variante declara só o ACENTO; as ênfases saem dele. Antes cada variante escrevia
|
|
1138
|
+
cor + fundo + borda na mão, e uma ênfase nova custaria seis regras novas.
|
|
1139
|
+
A POSIÇÃO NO ARQUIVO É A REGRA, não estilo: `.badge-solid` e `.badge-success` têm a MESMA
|
|
1140
|
+
especificidade (0,1,0), então quem vem depois vence. Escritas antes, as três não faziam
|
|
1141
|
+
nada em quatro das seis variantes — medido no navegador, `solid` e `outline` devolviam o
|
|
1142
|
+
número do `soft`. É a mesma armadilha que o `.banner` e o `.data-list` já pagaram aqui.
|
|
1143
|
+
`--background` como texto do sólido serve aos DOIS temas porque o acento já vira com o
|
|
1144
|
+
tema: `--success-400` é verde CLARO no escuro e verde ESCURO no claro. */
|
|
1145
|
+
.badge-solid { background:var(--badge-accent); color:var(--background); border-color:transparent; }
|
|
1146
|
+
.badge-outline { background:transparent; color:var(--badge-accent); border-color:var(--badge-accent); }
|
|
675
1147
|
.status-dot { width:8px; height:8px; border-radius:50%; background:currentColor; box-shadow:0 0 0 3px color-mix(in srgb,currentColor 14%,transparent); }
|
|
676
1148
|
/* Status: condição operacional (DIRECTION §3.6) — NÃO é o pill do Badge; é ponto + rótulo
|
|
677
1149
|
solto na linha. A variante pinta o .status (o ponto herda por currentColor) e o rótulo
|
|
@@ -1605,7 +2077,7 @@ button.graph-node-body { cursor:pointer; }
|
|
|
1605
2077
|
/* Padrões compostos Aurea 1.7: blocos de operação, não widgets de domínio. */
|
|
1606
2078
|
/* Alvo de toque. `.tabs`/`.segmented` no lugar de `.tab`/`.segmented button`: agora a altura
|
|
1607
2079
|
mora na cápsula, então é ela que precisa crescer — o filho estica atrás. */
|
|
1608
|
-
@media (pointer:coarse) { .btn:not(.btn-link),.tabs,.segmented,.pagination button,.schedule-grid button,.media-control { min-height:var(--target-min); } .btn-icon,.media-control { min-width:var(--target-min); } }
|
|
2080
|
+
@media (pointer:coarse) { .btn:not(.btn-link),.tabs,.segmented,.pagination button,.schedule-grid button,.media-control,.nav-list-row { min-height:var(--target-min); } .btn-icon,.media-control { min-width:var(--target-min); } }
|
|
1609
2081
|
@media (forced-colors:active) {
|
|
1610
2082
|
:focus-visible { outline:2px solid CanvasText; outline-offset:2px; box-shadow:none; }
|
|
1611
2083
|
.badge,.pattern-gallery button[aria-pressed="true"],.device-grid button[aria-pressed="true"] { border:1px solid CanvasText; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aurea-uds/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "The Aurea UDS stylesheet and its vanilla behaviour. Import @aurea-uds/fonts/css before this.",
|
|
5
5
|
"keywords": ["aurea", "design-system", "css", "design-tokens"],
|
|
6
6
|
"license": "Apache-2.0",
|