Tokens
3d. Material — vidro e metal
seed-tokens.md v1.26 · §03dseção 7 de 1803d-material-vidro-e-metal-f10-1-v1-24-v1-25-v1-26.md · MD5 24916c9bTítulo completo no canon: Material — vidro e metal (F10.1, v1.24 · v1.25 · v1.26, 2026-09-12/13) · estável (o §93 do seed-componentes.md virou estável pelo gate F10.4 em 2026-09-13; esta linha dizia "emitido · aplicação em gate" até a v1.26 — registro de estado que envelheceu)
Para quem lê sem ter visto a conversa. Em 2026-09-12 o Rafael escreveu que as telas feitas com o DS estavam "muito básicas, botões, barras, menus etc. ta faltando alguma coisa" e pediu pesquisa sobre "liquid Glass metalizado em DS de grandes empresas" com dois exemplos para comparar. A pesquisa (13 fontes datadas) e o par de telas estão em
09-pesquisa/material-vidro-metal-2026-09-12/; o veredito dele, verbatim, no MANIFESTO §204: V-1 = B (adotar a proposta inteira), V-2 opacidade 80 % claro · 72 % escuro · desfoque 18 px · movimento ligado, V-3 fundo com luz · barra superior em vidro · rail em metal · cartões em vidro · botões primários em metal · números KPI com brilho · barras e pílulas com luz · micro-movimento (a sidebar NÃO foi marcada e fica opaca —MA-P4, exposta a veto). Esta seção é o que a F10.1 do roadmap entrega: a camada vira tokens, para o gerador de cada tela emitir o material a partir deles (F10.4) — nunca CSS copiado (regra da casa: uma fonte).Mesma marca. Cor, tipografia e logo continuam os do DS. Aqui só muda material (translucidez, desfoque, luz de borda, acabamento metálico), profundidade (sombras em camadas, fundo com luz) e movimento (dois micro-movimentos, desligáveis).
⚠ Token existir não é permissão de uso — é o que permite MEDIR. A folha do gate declarou "não medi" o contraste efetivo de texto sobre vidro (
MA-P1): o instrumento da casa lê o fundo por CSS e um fundo de vidro é composição de pixel. A F10.3 entrega a régua rasterizada (renderiza, apaga o texto, amostra os pixels atrás de cada caixa de texto, mede o pior pixel contra a tinta declarada) e bloqueia a aplicação: nenhuma tela do acervo consome--seed-mat-*até a régua medir. HV1-c doseed-componentes.md§71: "quem cria um fundo novo cria a obrigação de medir o contraste sobre ele."
Os 18 tokens (grupo semantic.mat do JSON) e os 2 derivados do gêmeo#
| token | variável CSS | claro | escuro | de onde vem o valor |
|---|---|---|---|---|
mat.glass-alpha |
--seed-mat-glass-alpha |
80% |
72% |
V-2 dele (2026-09-12); piso ≥ 70 % da pesquisa |
mat.glass-blur |
--seed-mat-glass-blur |
18px |
= claro | V-2 dele |
mat.glass-saturate |
--seed-mat-glass-saturate |
1.45 |
= claro | receita da pesquisa (Fluent) |
mat.glass-border |
--seed-mat-glass-border |
#FFFFFF9E |
#FFFFFF21 |
estudo v1.1 (material.css), branco a 62 % / 13 % |
mat.glass-specular |
--seed-mat-glass-specular |
#FFFFFFD9 |
#FFFFFF38 |
estudo v1.1; é o PN21 do §48 com nome |
mat.glass-shadow |
--seed-mat-glass-shadow |
inset 0 1px 0 #FFFFFFD9, inset 0 -1px 0 rgba(0,53,47,0.05), 0 1px 2px… |
inset 0 1px 0 #FFFFFF38, inset 0 -1px 0 rgba(0,0,0,0.25), 0 1px 2px r… |
estudo v1.1; tinta = turquesa-900 no claro, preto no escuro (como shadow-raised) |
mat.glass-shadow-hover |
--seed-mat-glass-shadow-hover |
inset 0 1px 0 #FFFFFFD9, inset 0 -1px 0 rgba(0,53,47,0.05), 0 2px 4px… |
inset 0 1px 0 #FFFFFF38, inset 0 -1px 0 rgba(0,0,0,0.25), 0 2px 6px r… |
par de glass-shadow no sobrevoo |
mat.canvas |
--seed-mat-canvas |
radial-gradient(52% 48% at 10% 0%, color-mix(in srgb, var(--seed-turq… |
radial-gradient(52% 48% at 10% 0%, color-mix(in srgb, var(--seed-turq… |
estudo v1.1, derivado: turquesa-400/300/500 por color-mix, rampa surface-subtle → surface-sunken; os hex #E9F1F4/#DDE8EE do estudo NÃO entraram (§14.1). v1.25: a luz do escuro caiu de 40 % / 26 % para 26 % / 18 % (turquesa-400 / turquesa-500) — medido pela régua RC na primeira aplicação (F10.4): com 40 % o micro-rótulo text-secondary do primeiro KPI, sob vidro a 72 %, media 4,41 no ponto mais quente da luz (piso 4,5); em quatro intensidades (40/26 → 4,41 · 34/22 → 4,47 · 30/20 → 4,52 · 26/18 → 4,58) ficou a que passa com margem. O alfa do vidro (V-2 dele) não mudou |
mat.metal |
--seed-mat-metal |
1 |
= claro | nasce em 1; o 20 % do gate não é valor (MA-P5); calibração por peça na F10.4 |
mat.metal-sheen |
--seed-mat-metal-sheen |
linear-gradient(180deg, rgba(255,255,255,calc(0.08 * var(--seed-mat-m… |
= claro | estudo v1.1; regra do metal: só do token para o escuro onde há texto. v1.26 (F10.5): a luz do topo cai de 30 % para 8 % e some a 18 % da altura — medido pela régua RC nas sete telas seguintes: o primeiro rótulo branco do rail media 3,25–4,27 sob a luz (o shell passou na F10.4 porque o item ativo, com pílula clara, ocupa a primeira posição); com 8 %, 16 de 16 medições passam, pior 4,69 |
mat.metal-specular |
--seed-mat-metal-specular |
linear-gradient(162deg, transparent 28%, rgba(255,255,255,calc(0.13 *… |
= claro | estudo v1.1 (substitui o escovado de 1 px — moiré, MA-P5) |
mat.metal-curve |
--seed-mat-metal-curve |
linear-gradient(90deg, rgba(255,255,255,calc(0.08 * var(--seed-mat-me… |
= claro | estudo v1.1 |
mat.metal-action |
--seed-mat-metal-action |
linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(0,0,0,calc(0.06 … |
= claro | estudo v1.1; CP20 (branco sobre action-primary = 4,60, o piso — clarear reprova) |
mat.metal-edge |
--seed-mat-metal-edge |
inset 0 1px 0 rgba(255,255,255,calc(0.55 * var(--seed-mat-metal))), i… |
= claro | estudo v1.1 |
mat.metal-action-edge |
--seed-mat-metal-action-edge |
inset 0 1px 0 rgba(255,255,255,calc(0.40 * var(--seed-mat-metal))), i… |
= claro | estudo v1.1 |
mat.grain |
--seed-mat-grain |
url(data:image/svg+xml…feTurbulence…) |
= claro | estudo v1.1 (feTurbulence 5 %) |
mat.sheen-duration |
--seed-mat-sheen-duration |
700ms |
= claro | estudo v1.1 (700 ms; mais lenta que dur-expressive-slow de propósito) |
mat.breath-duration |
--seed-mat-breath-duration |
18s |
= claro | estudo v1.1 (18 s) |
| — (derivado) | --seed-mat-glass |
color-mix(in srgb, var(--seed-surface-raised) var(--seed-mat-glass-alpha), transparent) |
idem | só no gêmeo CSS, como --seed-focus-ring |
| — (derivado) | --seed-mat-glass-filter |
blur(var(--seed-mat-glass-blur)) saturate(var(--seed-mat-glass-saturate)) |
idem | só no gêmeo CSS |
Como se compõe (a receita que a F10.4 emite do token, por peça):
- Vidro (barra superior, cartão, pílula):
background: var(--seed-mat-glass)·backdrop-filter: var(--seed-mat-glass-filter)·box-shadow: 0 0 0 1px var(--seed-mat-glass-border), var(--seed-mat-glass-shadow)(no sobrevoo,-hover). O grão (--seed-mat-grain) entra como camada por cima emmix-blend-mode: soft-light. - Metal do rail:
background: var(--seed-mat-grain), var(--seed-mat-metal-specular), var(--seed-mat-metal-sheen), var(--seed-mat-metal-curve), var(--seed-rail-background)·box-shadow: var(--seed-mat-metal-edge). ⚠ v1.26 (F10.5, 2026-09-13): a luz do topo dometal-sheencaiu de 30 % para 8 % (some a 18 % da altura). A F10.4 mediu o rail do shell, cujo item ATIVO ocupa a primeira posição — a pílula clara cobria a faixa mais clara da luz e o pior rótulo branco ("Compras", 4,73) estava na terceira; nas sete telas seguintes o primeiro rótulo é branco e media 3,25 a 4,27 (12 medições, piso 4,5), e o shell com a pílula removida por variante reprova igual (3,62). Foi ponto cego da primeira medição, não mudança de gosto: a regra de contraste do metal (abaixo, e MA2 do §93) já proibia luz onde há texto. - Metal da ação primária: a cor continua o token de ação;
background-image: var(--seed-mat-metal-action)·box-shadow: var(--seed-mat-metal-action-edge). - Fundo com luz:
background: var(--seed-mat-canvas)na casca da aplicação. - Calibração:
--seed-mat-metalé o único botão, com o render e a régua na mesa. ⚠ Errata v1.25 (medida na F10.4, 2026-09-12): esta linha dizia "a F10.4 pode sobrescrevê-lo no escopo de um componente" — não basta: ovar()dentro do valor de uma custom property é resolvido no elemento onde ela é declarada (o:root), não onde é consumida;--seed-mat-metal-sheenjá nasce com o multiplicador resolvido em 1, e um.rail { --seed-mat-metal: .7 }não alcança nada (a régua devolveu os mesmos números em 1, 0,7 e 0,4 até o conserto). A calibração por peça reemite no escopo os tokens que multiplicam pelo botão, com o texto lido do gêmeo — é o que06-validacao/ferramentas/material_bloco.py(calibracao_metal()) faz. A alternativa de declarar esses tokens em*em vez de:root(ovar()resolveria por elemento) foi descartada: sairia da paridade G2, que lê o:root.
Regra de contraste do metal (vai ao canon na F10.2): o gradiente metálico só vai do token para o lado escuro
onde há texto. Motivo medido: a tinta branca sobre action-primary já mede 4,60 no claro, que é o piso — clarear
qualquer extremo reprovaria (CP20: a tinta passa nos dois extremos, não na média).
Os fallbacks — regra escrita E executável#
A pesquisa manda respeitar todo estado de sistema (a Apple recuou três vezes em um ano por legibilidade; a Microsoft desliga o acrílico em economia de bateria; NN/g 2025). Aqui a regra vive no gêmeo CSS, no próprio token, então nenhum consumidor precisa lembrar de escrever a media query:
| condição | o que o token faz |
|---|---|
navegador sem backdrop-filter (@supports not) |
glass-alpha → 100 %, glass-blur → 0 — o vidro vira sólido |
prefers-reduced-transparency: reduce |
idem: vidro sólido |
prefers-contrast: more |
vidro sólido · glass-border → border-strong · glass-specular → transparente · canvas → none · grain → none · metal → 0 |
prefers-reduced-motion: reduce |
sheen-duration → 0 ms · breath-duration → 0 s (no mesmo bloco que já zera as durações produtivas) |
O seletor dos blocos de fallback é :root, :root[data-theme]: cobre os três estados de tema (sem atributo, claro
forçado, escuro forçado) com especificidade igual ou maior que a dos blocos de tema, e vence por vir depois no arquivo.
O que NÃO entrou, e por quê#
- O "escovado" de 1 px da v1 do estudo (traço repetido a cada 2 px): virava moiré quando a tela era vista em
escala e listra visível a 100 % — foi o que ele viu no gate ("cria várias linhas verticais paralelas"). Textura de
período fixo em pixel não sobrevive a escala; grão aleatório e reflexo contínuo sobrevivem (
MA-P5). - O 20 % de metal que ele deixou no controle: era reação ao defeito acima, não preferência — ele mesmo escreveu
"acredito que testes e medições vc vai achar o que é melhor para cada caso".
--seed-mat-metalnasce em 1 e a calibração por peça é da F10.4. - Os hex do fundo do estudo (#E9F1F4 → #DDE8EE no claro, #0B1419 → #08100E no escuro): não existem na paleta.
O
canvasé derivado de token em todas as paradas (§14.1: valor que não está no canônico não se cria). A diferença de tom vai à mesa no gate visual da F10.4, com o render. - Um token de "luz" (
--mat-luzdo estudo): ele deixou em 100 % e a intensidade está dentro docanvas; um multiplicador a mais seria botão sem decisão.