synthesisui 0.16.430 → 0.16.432
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/commands/import.js +9 -0
- package/dist/report-html.js +396 -88
- package/dist/report-theme.js +610 -0
- package/package.json +1 -1
package/dist/commands/import.js
CHANGED
|
@@ -3750,10 +3750,17 @@ async function mostrarInspecao(c, root, transcrito) {
|
|
|
3750
3750
|
medidoEm: c.measured?.at ?? "",
|
|
3751
3751
|
cli: c.ledger?.cli ?? "",
|
|
3752
3752
|
},
|
|
3753
|
+
/**
|
|
3754
|
+
* OS TRÊS NÚMEROS DA ABERTURA, e os dois primeiros carregam o denominador para virarem
|
|
3755
|
+
* BARRA. O terceiro não tem fatia possível - "quantos `var()` não resolvem" não é parte de
|
|
3756
|
+
* nada -, então ele fica só número, e desenhar uma barra ali inventaria uma proporção.
|
|
3757
|
+
*/
|
|
3753
3758
|
destaques: [
|
|
3754
3759
|
{
|
|
3755
3760
|
numero: `${lidos} of ${total}`,
|
|
3756
3761
|
rotulo: "components came out with a blueprint",
|
|
3762
|
+
parte: lidos,
|
|
3763
|
+
de: total,
|
|
3757
3764
|
},
|
|
3758
3765
|
...(pct === null
|
|
3759
3766
|
? []
|
|
@@ -3761,6 +3768,8 @@ async function mostrarInspecao(c, root, transcrito) {
|
|
|
3761
3768
|
{
|
|
3762
3769
|
numero: `${pct}%`,
|
|
3763
3770
|
rotulo: `of ${decisoes} style decisions carry your vocabulary`,
|
|
3771
|
+
parte: valores?.interpreted ?? 0,
|
|
3772
|
+
de: decisoes,
|
|
3764
3773
|
},
|
|
3765
3774
|
]),
|
|
3766
3775
|
{
|
package/dist/report-html.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { FAMILY_SEAM_PREFIX } from "./fonts.js";
|
|
2
|
+
import { HALOGEN_TOKENS, HALOGEN_VERSION } from "./report-theme.js";
|
|
1
3
|
import { semCor } from "./transcript.js";
|
|
2
4
|
/**
|
|
3
5
|
* O QUE O TERMINAL DIRIA, LIDO DE VOLTA COMO DOCUMENTO.
|
|
@@ -45,62 +47,221 @@ function escapar(s) {
|
|
|
45
47
|
export function relatorioHtml(input) {
|
|
46
48
|
const { cabecalho, destaques, secoes } = input;
|
|
47
49
|
const quando = legivel(cabecalho.medidoEm);
|
|
50
|
+
/**
|
|
51
|
+
* O ÍNDICE DIZ O TAMANHO DE CADA CAPÍTULO, e é isso que o torna uma escolha em vez de uma lista.
|
|
52
|
+
* Dezesseis links iguais obrigam a entrar para descobrir o custo; com a contagem ao lado, quem
|
|
53
|
+
* está com pressa sabe onde não entrar.
|
|
54
|
+
*/
|
|
48
55
|
const indice = secoes
|
|
49
|
-
.map((s, i) => `<li><a href="#s${i}">${escapar(s.titulo)}</a></li>`)
|
|
50
|
-
.join("\n
|
|
56
|
+
.map((s, i) => `<li><a href="#s${i}">${escapar(s.titulo)}</a><span>${s.linhas.filter((l) => l.trim()).length}</span></li>`)
|
|
57
|
+
.join("\n ");
|
|
51
58
|
const corpo = secoes
|
|
52
|
-
.map((s, i) => ` <section id="s${i}">
|
|
53
|
-
<h2>${escapar(s.titulo)}</h2>
|
|
54
|
-
|
|
59
|
+
.map((s, i) => ` <section id="s${i}" class="chapter" style="--ordem:${Math.min(i, 12)}">
|
|
60
|
+
<h2><span>${escapar(s.titulo)}</span></h2>
|
|
61
|
+
${desenharCorpo(s)}
|
|
55
62
|
</section>`)
|
|
56
63
|
.join("\n");
|
|
57
|
-
const numeros = destaques
|
|
58
|
-
.map((d) => ` <div class="stat">
|
|
59
|
-
<strong>${escapar(d.numero)}</strong>
|
|
60
|
-
<span>${escapar(d.rotulo)}</span>
|
|
61
|
-
</div>`)
|
|
62
|
-
.join("\n");
|
|
64
|
+
const numeros = destaques.map(cartaoDeNumero).join("\n");
|
|
63
65
|
return `<!doctype html>
|
|
64
|
-
<html lang="en">
|
|
66
|
+
<html lang="en" data-scheme="light">
|
|
65
67
|
<head>
|
|
66
68
|
<meta charset="utf-8">
|
|
67
69
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
68
70
|
<title>${escapar(cabecalho.repo)} - read by SynthesisUI</title>
|
|
69
71
|
<style>
|
|
70
|
-
${
|
|
72
|
+
${HALOGEN_TOKENS}
|
|
73
|
+
</style>
|
|
74
|
+
<style>
|
|
75
|
+
${layout()}
|
|
71
76
|
</style>
|
|
72
77
|
</head>
|
|
73
78
|
<body>
|
|
74
|
-
<header>
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
<header class="bar">
|
|
80
|
+
<div class="bar-in">
|
|
81
|
+
<div class="bar-id">
|
|
82
|
+
<p class="kicker">Read by SynthesisUI</p>
|
|
83
|
+
<p class="bar-repo">${escapar(cabecalho.repo)}</p>
|
|
84
|
+
</div>
|
|
85
|
+
<p class="meta">${escapar(quando)} · CLI ${escapar(cabecalho.cli)} · nothing left this machine</p>
|
|
86
|
+
</div>
|
|
78
87
|
</header>
|
|
79
88
|
|
|
80
|
-
<
|
|
81
|
-
<
|
|
89
|
+
<main class="wrap">
|
|
90
|
+
<section class="hero chapter" style="--ordem:0">
|
|
91
|
+
<h1>${escapar(cabecalho.repo)}</h1>
|
|
92
|
+
<p class="lede">This is what your own code says about itself.</p>
|
|
93
|
+
<div class="stats">
|
|
82
94
|
${numeros}
|
|
83
|
-
|
|
95
|
+
</div>
|
|
96
|
+
</section>
|
|
84
97
|
|
|
85
|
-
<nav>
|
|
98
|
+
<nav class="chapter" style="--ordem:1">
|
|
86
99
|
<p class="kicker">What is in here</p>
|
|
87
100
|
<ol>
|
|
88
|
-
|
|
101
|
+
${indice}
|
|
89
102
|
</ol>
|
|
90
103
|
</nav>
|
|
91
104
|
|
|
92
|
-
<main>
|
|
93
105
|
${corpo}
|
|
94
|
-
</main>
|
|
95
106
|
|
|
96
107
|
<footer>
|
|
108
|
+
<p>Dressed by Halogen v${HALOGEN_VERSION}, a design system from the SynthesisUI gallery.</p>
|
|
97
109
|
<p>This file lives in your project and was never sent anywhere. Re-run the command to refresh it.</p>
|
|
98
110
|
</footer>
|
|
99
|
-
</
|
|
111
|
+
</main>
|
|
100
112
|
</body>
|
|
101
113
|
</html>
|
|
102
114
|
`;
|
|
103
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* O NÚMERO COM A FATIA DESENHADA - e a barra só aparece quando existe denominador medido.
|
|
118
|
+
*
|
|
119
|
+
* `aria-hidden` na barra porque ela não diz nada que o número ao lado já não diga; um leitor de
|
|
120
|
+
* tela que a anunciasse leria a mesma informação duas vezes.
|
|
121
|
+
*/
|
|
122
|
+
function cartaoDeNumero(d) {
|
|
123
|
+
const temBarra = typeof d.parte === "number" && typeof d.de === "number" && d.de > 0;
|
|
124
|
+
const pct = temBarra
|
|
125
|
+
? Math.max(0, Math.min(100, Math.round(((d.parte ?? 0) / (d.de ?? 1)) * 100)))
|
|
126
|
+
: 0;
|
|
127
|
+
return ` <div class="stat">
|
|
128
|
+
<strong>${escapar(d.numero)}</strong>
|
|
129
|
+
<span>${escapar(d.rotulo)}</span>${temBarra
|
|
130
|
+
? `
|
|
131
|
+
<div class="bar-track" aria-hidden="true"><i style="--pct:${pct}%"></i></div>`
|
|
132
|
+
: ""}
|
|
133
|
+
</div>`;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* COMO CADA CAPÍTULO É DESENHADO - e a decisão é sobre REPETIÇÃO, não sobre o assunto.
|
|
137
|
+
*
|
|
138
|
+
* Medido na página dele em 18/09: as 94 linhas com a mesma forma saíram em SEIS pedaços, porque o
|
|
139
|
+
* agrupamento só juntava linhas VIZINHAS e as frases de `mx-auto` caem no meio delas. Seis blocos
|
|
140
|
+
* de dez são a mesma parede com mais bordas.
|
|
141
|
+
*
|
|
142
|
+
* Agora a família é da SEÇÃO INTEIRA: irmãs distantes se encontram, e a ordem que sobrevive é a da
|
|
143
|
+
* primeira aparição - o texto continua sendo lido na ordem em que a esteira o escreveu.
|
|
144
|
+
*
|
|
145
|
+
* E O PRIMEIRO FATO DO CAPÍTULO SOBE: a linha de abertura, que é onde mora o número, deixa de ter
|
|
146
|
+
* o peso do detalhe monoespaçado e vira o CALLOUT que a pessoa lê antes de decidir se desce.
|
|
147
|
+
*/
|
|
148
|
+
function desenharCorpo(s) {
|
|
149
|
+
const { destaque, resto } = abertura(s.linhas);
|
|
150
|
+
const familias = agrupar(resto);
|
|
151
|
+
const corpo = familias
|
|
152
|
+
.map((f) => f.tipo === "tabela"
|
|
153
|
+
? ` <details class="familia" open>
|
|
154
|
+
<summary><span>${escapar(f.rotulo)}</span> <b>${f.itens.length}</b></summary>
|
|
155
|
+
<ul class="grade">
|
|
156
|
+
${f.itens.map((i) => ` <li>${escapar(i)}</li>`).join("\n")}
|
|
157
|
+
</ul>
|
|
158
|
+
</details>`
|
|
159
|
+
: ` <pre>${escapar(f.itens.join("\n"))}</pre>`)
|
|
160
|
+
.join("\n");
|
|
161
|
+
return destaque
|
|
162
|
+
? ` <p class="callout">${escapar(destaque)}</p>\n${corpo}`
|
|
163
|
+
: corpo;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* A ABERTURA DO CAPÍTULO - a primeira linha com conteúdo, e só quando ela CARREGA UM NÚMERO.
|
|
167
|
+
*
|
|
168
|
+
* É o número que faz a frase valer o destaque: "78 of 78 components came out with a blueprint" é
|
|
169
|
+
* um fato que decide se a pessoa lê o resto. Uma abertura sem número seria só a primeira linha
|
|
170
|
+
* promovida por ser a primeira, e aí o destaque deixaria de significar alguma coisa.
|
|
171
|
+
*/
|
|
172
|
+
function abertura(linhas) {
|
|
173
|
+
const i = linhas.findIndex((l) => l.trim());
|
|
174
|
+
if (i < 0)
|
|
175
|
+
return { destaque: null, resto: linhas };
|
|
176
|
+
const primeira = linhas[i].trim();
|
|
177
|
+
if (!/\d/.test(primeira) || primeira.length > 240)
|
|
178
|
+
return { destaque: null, resto: linhas };
|
|
179
|
+
/**
|
|
180
|
+
* E ELA NÃO PODE SER MEMBRO DE UMA FAMÍLIA. Um capítulo que abre com a primeira de noventa
|
|
181
|
+
* linhas iguais promoveria uma irmã qualquer a conclusão, e ainda tiraria uma da contagem -
|
|
182
|
+
* duas mentiras pelo preço de uma. O destaque é para o fato ÚNICO.
|
|
183
|
+
*/
|
|
184
|
+
const f = forma(primeira);
|
|
185
|
+
const irmas = linhas.filter((l) => l.trim() && forma(l) === f).length;
|
|
186
|
+
if (irmas >= MINIMO_PARA_TABELA)
|
|
187
|
+
return { destaque: null, resto: linhas };
|
|
188
|
+
return { destaque: primeira, resto: linhas.slice(i + 1) };
|
|
189
|
+
}
|
|
190
|
+
const MINIMO_PARA_TABELA = 6;
|
|
191
|
+
/**
|
|
192
|
+
* A FORMA DE UMA LINHA, sem ler o que ela diz: as palavras ficam, os nomes próprios viram `·`.
|
|
193
|
+
*
|
|
194
|
+
* É isso que faz `two parts named \`box\`` e `two parts named \`nav\`` caírem na mesma família sem
|
|
195
|
+
* ninguém escrever uma regra sobre partes - e é isso que faz a regra valer para a próxima classe de
|
|
196
|
+
* linha repetida, que ninguém ainda viu (`INV-GERAL-07`).
|
|
197
|
+
*/
|
|
198
|
+
function forma(linha) {
|
|
199
|
+
return linha
|
|
200
|
+
.trim()
|
|
201
|
+
.replace(/`[^`]*`/g, "·")
|
|
202
|
+
.replace(/\d+/g, "#")
|
|
203
|
+
.split(/\s+/)
|
|
204
|
+
.slice(0, 6)
|
|
205
|
+
.join(" ");
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* AGRUPA A SEÇÃO INTEIRA, e a ordem é a da PRIMEIRA APARIÇÃO de cada forma.
|
|
209
|
+
*
|
|
210
|
+
* Uma varredura só: cada linha entra no balde da forma dela, e os baldes saem na ordem em que
|
|
211
|
+
* nasceram. Quem tem irmãs suficientes vira família; quem não tem volta para a prosa, no lugar
|
|
212
|
+
* onde estava. O que a pessoa lê continua sendo o texto da esteira, na ordem da esteira.
|
|
213
|
+
*/
|
|
214
|
+
function agrupar(linhas) {
|
|
215
|
+
const contagem = new Map();
|
|
216
|
+
for (const l of linhas) {
|
|
217
|
+
if (!l.trim())
|
|
218
|
+
continue;
|
|
219
|
+
const f = forma(l);
|
|
220
|
+
contagem.set(f, (contagem.get(f) ?? 0) + 1);
|
|
221
|
+
}
|
|
222
|
+
const saida = [];
|
|
223
|
+
const familiaDe = new Map();
|
|
224
|
+
for (const l of linhas) {
|
|
225
|
+
const f = l.trim() ? forma(l) : "";
|
|
226
|
+
if (l.trim() && (contagem.get(f) ?? 0) >= MINIMO_PARA_TABELA) {
|
|
227
|
+
const existente = familiaDe.get(f);
|
|
228
|
+
if (existente) {
|
|
229
|
+
existente.itens.push(l.trim());
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const nova = {
|
|
233
|
+
tipo: "tabela",
|
|
234
|
+
rotulo: rotuloDe(f),
|
|
235
|
+
itens: [l.trim()],
|
|
236
|
+
};
|
|
237
|
+
familiaDe.set(f, nova);
|
|
238
|
+
saida.push(nova);
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
empilharProsa(saida, l);
|
|
242
|
+
}
|
|
243
|
+
return saida.filter((f) => f.itens.some((l) => l.trim()));
|
|
244
|
+
}
|
|
245
|
+
function empilharProsa(saida, linha) {
|
|
246
|
+
const ultimo = saida[saida.length - 1];
|
|
247
|
+
if (ultimo && ultimo.tipo === "prosa")
|
|
248
|
+
ultimo.itens.push(linha);
|
|
249
|
+
else
|
|
250
|
+
saida.push({ tipo: "prosa", rotulo: "", itens: [linha] });
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* O RÓTULO DA FAMÍLIA - uma frase que se lê, e não a forma crua.
|
|
254
|
+
*
|
|
255
|
+
* `two parts named · - the second is ·` saía como `two parts named … - the 10`: reticência solta,
|
|
256
|
+
* minúscula, e sem dizer o que aquilo é. O rótulo agora é a parte ESTÁVEL da frase - o que todas as
|
|
257
|
+
* irmãs têm em comum - cortada no primeiro buraco e começando com maiúscula.
|
|
258
|
+
*/
|
|
259
|
+
function rotuloDe(f) {
|
|
260
|
+
const estavel = f.split("·")[0].replace(/#/g, "n").trim();
|
|
261
|
+
const limpo = estavel.replace(/[\s\-–—:,]+$/, "");
|
|
262
|
+
const frase = limpo || "Repeated lines";
|
|
263
|
+
return frase.charAt(0).toUpperCase() + frase.slice(1);
|
|
264
|
+
}
|
|
104
265
|
/** A data em palavras. Data ilegível some da frase em vez de imprimir `Invalid Date`. */
|
|
105
266
|
function legivel(iso) {
|
|
106
267
|
if (!iso || Number.isNaN(Date.parse(iso)))
|
|
@@ -112,94 +273,241 @@ function legivel(iso) {
|
|
|
112
273
|
});
|
|
113
274
|
}
|
|
114
275
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
276
|
+
* O LAYOUT DESTA PÁGINA, e só ele: cor, raio e fonte vêm dos tokens do halogen logo acima.
|
|
277
|
+
*
|
|
278
|
+
* A BARRA É FIXA porque os três números são a razão de a página existir - e numa leitura de
|
|
279
|
+
* dezesseis capítulos eles somem na primeira rolagem, que é quando a pessoa mais precisa deles
|
|
280
|
+
* para saber o que está olhando.
|
|
281
|
+
*
|
|
282
|
+
* O MOVIMENTO CARREGA INFORMAÇÃO: cada capítulo entra de baixo, na ordem em que a esteira o
|
|
283
|
+
* escreveu, e o atraso é a posição dele. Ele para inteiro sob `prefers-reduced-motion` - uma
|
|
284
|
+
* página que desliza dezesseis vezes são dezesseis chances de passar mal.
|
|
118
285
|
*
|
|
119
286
|
* E ela imprime: `@media print` existe porque o navegador já exporta PDF, e um relatório que sai
|
|
120
287
|
* torto no papel obriga a construir um gerador de PDF para resolver o que uma regra resolve.
|
|
121
288
|
*/
|
|
122
|
-
function
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
--canvas: #0f0f12;
|
|
139
|
-
--accent: #e9a13b;
|
|
140
|
-
}
|
|
289
|
+
function layout() {
|
|
290
|
+
/**
|
|
291
|
+
* A COSTURA DAS FAMÍLIAS VEM DA CONST, e não do literal: renomear o prefixo em `fonts.ts` tem
|
|
292
|
+
* que alcançar esta página também. Um literal solto aqui divergiria em silêncio, que é
|
|
293
|
+
* exatamente o que o portão de `fonts.spec.ts` existe para impedir.
|
|
294
|
+
*/
|
|
295
|
+
const corpo = `var(${FAMILY_SEAM_PREFIX}body, ui-sans-serif, system-ui, sans-serif)`;
|
|
296
|
+
const mono = `var(${FAMILY_SEAM_PREFIX}mono, ui-monospace, monospace)`;
|
|
297
|
+
const display = `var(${FAMILY_SEAM_PREFIX}display, inherit)`;
|
|
298
|
+
return `body {
|
|
299
|
+
margin: 0;
|
|
300
|
+
background: var(--ds-color-semantic-canvas);
|
|
301
|
+
color: var(--ds-color-semantic-foreground);
|
|
302
|
+
font-family: ${corpo};
|
|
303
|
+
font-size: 15px;
|
|
304
|
+
line-height: 1.6;
|
|
141
305
|
}
|
|
142
306
|
* { box-sizing: border-box; }
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
307
|
+
|
|
308
|
+
.bar {
|
|
309
|
+
position: sticky;
|
|
310
|
+
top: 0;
|
|
311
|
+
z-index: 10;
|
|
312
|
+
background: var(--ds-color-semantic-raised, var(--ds-color-semantic-surface));
|
|
313
|
+
border-bottom: 1px solid var(--ds-color-semantic-border);
|
|
148
314
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
315
|
+
.bar-in {
|
|
316
|
+
max-width: 920px;
|
|
317
|
+
margin-inline: auto;
|
|
318
|
+
padding: 11px 24px;
|
|
319
|
+
display: flex;
|
|
320
|
+
flex-wrap: wrap;
|
|
321
|
+
gap: 8px 24px;
|
|
322
|
+
align-items: baseline;
|
|
323
|
+
justify-content: space-between;
|
|
153
324
|
}
|
|
154
|
-
.
|
|
155
|
-
.
|
|
325
|
+
.bar-repo { margin: 2px 0 0; font-weight: 600; }
|
|
326
|
+
.bar-id { min-width: 0; }
|
|
327
|
+
|
|
328
|
+
.wrap { max-width: 920px; margin-inline: auto; padding: 0 24px 96px; }
|
|
329
|
+
|
|
156
330
|
.kicker {
|
|
157
331
|
margin: 0;
|
|
158
|
-
font:
|
|
332
|
+
font-family: ${mono};
|
|
333
|
+
font-size: 11px;
|
|
159
334
|
letter-spacing: 0.16em;
|
|
160
335
|
text-transform: uppercase;
|
|
161
|
-
color: var(--accent);
|
|
336
|
+
color: var(--ds-color-semantic-accent);
|
|
337
|
+
}
|
|
338
|
+
.meta { margin: 0; color: var(--ds-color-semantic-muted); font-size: 13px; }
|
|
339
|
+
|
|
340
|
+
.hero { padding: 56px 0 8px; }
|
|
341
|
+
h1 {
|
|
342
|
+
margin: 10px 0 8px;
|
|
343
|
+
font-family: ${display};
|
|
344
|
+
font-size: 40px;
|
|
345
|
+
line-height: 1.1;
|
|
346
|
+
letter-spacing: -0.02em;
|
|
162
347
|
}
|
|
163
|
-
|
|
164
|
-
|
|
348
|
+
.lede { margin: 0 0 28px; color: var(--ds-color-semantic-muted); font-size: 17px; }
|
|
349
|
+
|
|
165
350
|
.stats {
|
|
166
351
|
display: grid;
|
|
167
352
|
gap: 12px;
|
|
168
|
-
grid-template-columns: repeat(auto-fit, minmax(
|
|
169
|
-
margin: -28px 0 40px;
|
|
353
|
+
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
|
|
170
354
|
}
|
|
171
355
|
.stat {
|
|
172
|
-
background: var(--
|
|
173
|
-
border: 1px solid var(--
|
|
174
|
-
border-radius: 14px;
|
|
356
|
+
background: var(--ds-color-semantic-surface);
|
|
357
|
+
border: 1px solid var(--ds-color-semantic-border);
|
|
358
|
+
border-radius: var(--ds-radius-lg, 14px);
|
|
175
359
|
padding: 18px 20px;
|
|
176
360
|
}
|
|
177
|
-
.stat strong { display: block; font-size:
|
|
178
|
-
.stat span { display: block; margin-top: 4px; color: var(--
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
361
|
+
.stat strong { display: block; font-size: 28px; letter-spacing: -0.02em; }
|
|
362
|
+
.stat span { display: block; margin-top: 4px; color: var(--ds-color-semantic-muted); font-size: 13px; }
|
|
363
|
+
.bar-track {
|
|
364
|
+
margin-top: 14px;
|
|
365
|
+
height: 6px;
|
|
366
|
+
border-radius: 999px;
|
|
367
|
+
background: var(--ds-color-semantic-overlay, var(--ds-color-semantic-border));
|
|
368
|
+
overflow: hidden;
|
|
369
|
+
}
|
|
370
|
+
.bar-track i {
|
|
371
|
+
display: block;
|
|
372
|
+
height: 100%;
|
|
373
|
+
width: var(--pct);
|
|
374
|
+
border-radius: inherit;
|
|
375
|
+
background: var(--ds-color-semantic-accent);
|
|
376
|
+
animation: crescer 900ms cubic-bezier(0.22, 1, 0.36, 1) both;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
nav { margin: 44px 0 8px; }
|
|
380
|
+
nav ol {
|
|
381
|
+
margin: 12px 0 0;
|
|
382
|
+
padding: 0;
|
|
383
|
+
list-style: none;
|
|
384
|
+
counter-reset: capitulo;
|
|
385
|
+
color: var(--ds-color-semantic-muted);
|
|
386
|
+
display: grid;
|
|
387
|
+
gap: 1px;
|
|
388
|
+
}
|
|
389
|
+
nav li {
|
|
390
|
+
counter-increment: capitulo;
|
|
391
|
+
display: flex;
|
|
392
|
+
align-items: baseline;
|
|
393
|
+
gap: 12px;
|
|
394
|
+
padding: 7px 10px;
|
|
395
|
+
border-radius: var(--ds-radius-sm, 8px);
|
|
396
|
+
}
|
|
397
|
+
nav li:hover { background: var(--ds-color-semantic-surface); }
|
|
398
|
+
nav li::before {
|
|
399
|
+
content: counter(capitulo);
|
|
400
|
+
min-width: 18px;
|
|
401
|
+
font-variant-numeric: tabular-nums;
|
|
402
|
+
font-size: 12px;
|
|
403
|
+
color: var(--ds-color-semantic-faint);
|
|
404
|
+
}
|
|
405
|
+
nav a { color: inherit; text-decoration: none; }
|
|
406
|
+
nav li:hover a { color: var(--ds-color-semantic-accent); }
|
|
407
|
+
/* A regua que sobra entre o nome e a contagem - sem ela os numeros flutuam soltos. */
|
|
408
|
+
nav a::after {
|
|
409
|
+
content: "";
|
|
410
|
+
display: inline-block;
|
|
411
|
+
width: 100%;
|
|
412
|
+
}
|
|
413
|
+
nav li > span {
|
|
414
|
+
margin-left: auto;
|
|
415
|
+
font-variant-numeric: tabular-nums;
|
|
416
|
+
font-size: 12px;
|
|
417
|
+
color: var(--ds-color-semantic-faint);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
section.chapter {
|
|
421
|
+
background: var(--ds-color-semantic-surface);
|
|
422
|
+
border: 1px solid var(--ds-color-semantic-border);
|
|
423
|
+
border-radius: var(--ds-radius-lg, 14px);
|
|
424
|
+
padding: 24px 26px;
|
|
425
|
+
margin-top: 16px;
|
|
426
|
+
scroll-margin-top: 84px;
|
|
427
|
+
}
|
|
428
|
+
.hero, nav { background: none; border: 0; padding-inline: 0; }
|
|
429
|
+
/* O TITULO DO CAPITULO SEGURA O TOPO ENQUANTO O CAPITULO PASSA - e e assim que a pessoa sempre
|
|
430
|
+
sabe o que esta lendo, sem uma linha de script. Um capitulo de cem linhas rolava ate o fim sem
|
|
431
|
+
nada na tela dizendo de qual dos dezesseis ele era. O deslocamento e a altura da barra: eles se
|
|
432
|
+
encostam em vez de se sobrepor, e o segundo empurra o primeiro so quando chega a vez dele. */
|
|
433
|
+
h2 {
|
|
434
|
+
position: sticky;
|
|
435
|
+
top: 60px;
|
|
436
|
+
z-index: 5;
|
|
437
|
+
margin: -24px -26px 14px;
|
|
438
|
+
padding: 14px 26px 12px;
|
|
439
|
+
font-size: 18px;
|
|
440
|
+
letter-spacing: -0.01em;
|
|
441
|
+
background: var(--ds-color-semantic-surface);
|
|
442
|
+
border-bottom: 1px solid var(--ds-color-semantic-border);
|
|
443
|
+
border-radius: var(--ds-radius-lg, 14px) var(--ds-radius-lg, 14px) 0 0;
|
|
444
|
+
}
|
|
445
|
+
h2 span { display: block; }
|
|
446
|
+
|
|
447
|
+
/* O PRIMEIRO FATO DO CAPITULO, no peso de quem decide se vale descer. Ele e prosa, nao codigo -
|
|
448
|
+
entao sai do monoespacado e ganha a regua da esquerda, que e a unica marca do documento que diz
|
|
449
|
+
isto aqui e a conclusao, o resto e a evidencia. */
|
|
450
|
+
.callout {
|
|
451
|
+
margin: 0 0 16px;
|
|
452
|
+
padding: 2px 0 2px 16px;
|
|
453
|
+
border-left: 2px solid var(--ds-color-semantic-accent);
|
|
454
|
+
font-size: 15.5px;
|
|
455
|
+
line-height: 1.55;
|
|
456
|
+
color: var(--ds-color-semantic-foreground);
|
|
457
|
+
}
|
|
458
|
+
|
|
192
459
|
pre {
|
|
193
|
-
margin: 0;
|
|
460
|
+
margin: 0 0 12px;
|
|
194
461
|
white-space: pre-wrap;
|
|
195
462
|
word-break: break-word;
|
|
196
|
-
font:
|
|
197
|
-
|
|
463
|
+
font-family: ${mono};
|
|
464
|
+
font-size: 12.5px;
|
|
465
|
+
line-height: 1.7;
|
|
466
|
+
color: var(--ds-color-semantic-muted);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.familia {
|
|
470
|
+
margin: 0 0 12px;
|
|
471
|
+
border: 1px solid var(--ds-color-semantic-border);
|
|
472
|
+
border-radius: var(--ds-radius-md, 10px);
|
|
473
|
+
padding: 10px 14px;
|
|
474
|
+
background: var(--ds-color-semantic-canvas);
|
|
198
475
|
}
|
|
199
|
-
|
|
476
|
+
.familia summary {
|
|
477
|
+
cursor: pointer;
|
|
478
|
+
font-size: 13px;
|
|
479
|
+
color: var(--ds-color-semantic-muted);
|
|
480
|
+
}
|
|
481
|
+
.familia summary b {
|
|
482
|
+
color: var(--ds-color-semantic-foreground);
|
|
483
|
+
font-variant-numeric: tabular-nums;
|
|
484
|
+
}
|
|
485
|
+
.grade {
|
|
486
|
+
list-style: none;
|
|
487
|
+
margin: 12px 0 4px;
|
|
488
|
+
padding: 0;
|
|
489
|
+
display: grid;
|
|
490
|
+
gap: 4px 20px;
|
|
491
|
+
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
492
|
+
font-family: ${mono};
|
|
493
|
+
font-size: 12px;
|
|
494
|
+
color: var(--ds-color-semantic-muted);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
footer { margin-top: 40px; color: var(--ds-color-semantic-muted); font-size: 13px; }
|
|
498
|
+
|
|
499
|
+
@keyframes crescer { from { width: 0; } }
|
|
500
|
+
@keyframes entrar { from { opacity: 0; transform: translateY(12px); } }
|
|
501
|
+
.chapter { animation: entrar 620ms cubic-bezier(0.22, 1, 0.36, 1) both; animation-delay: calc(var(--ordem, 0) * 55ms); }
|
|
502
|
+
|
|
503
|
+
@media (prefers-reduced-motion: reduce) {
|
|
504
|
+
.chapter, .bar-track i { animation: none; }
|
|
505
|
+
}
|
|
506
|
+
|
|
200
507
|
@media print {
|
|
201
|
-
|
|
202
|
-
.stat, section { break-inside: avoid; border-color: #ddd; }
|
|
508
|
+
.bar { position: static; }
|
|
203
509
|
nav { display: none; }
|
|
510
|
+
.stat, section.chapter { break-inside: avoid; }
|
|
511
|
+
.familia { break-inside: auto; }
|
|
204
512
|
}`;
|
|
205
513
|
}
|
|
@@ -0,0 +1,610 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* O HALOGEN, EMBUTIDO NO PACOTE - os VALORES dele, nunca o marcador dele.
|
|
3
|
+
*
|
|
4
|
+
* O QUE O CLIENTE GANHA: o relatório do `inspect` é desenhado por um design system de verdade, o
|
|
5
|
+
* mesmo que qualquer pessoa instala da galeria. A primeira coisa que ela vê do produto já é o
|
|
6
|
+
* produto funcionando, e não uma folha que alguém escreveu à mão para a ocasião.
|
|
7
|
+
*
|
|
8
|
+
* O ESCOPO FOI REESCRITO PARA A RAIZ, e isto é `INV-GERAL-13`: nada nosso é pedido, escrito ou
|
|
9
|
+
* sugerido dentro da árvore dele. O `tokens.css` publicado vive sob o escopo do sistema porque
|
|
10
|
+
* ele foi feito para ser INSTALADO num app; aqui ele veste um documento nosso, então as
|
|
11
|
+
* declarações passam a morar em `:root` e nenhum atributo nosso aparece no repositório de
|
|
12
|
+
* ninguém. O que atravessa é a cor, o raio e a tipografia - que é tudo o que uma página precisa.
|
|
13
|
+
*
|
|
14
|
+
* POR QUE DENTRO DO PACOTE: `inspect` não faz uma única chamada de rede, e isso é contrato
|
|
15
|
+
* (`INV-INSPECT-01`, com spec que conta os `fetch`). Buscar o CSS na hora de gerar quebraria o
|
|
16
|
+
* comando exatamente para quem tem menos motivo para confiar nele - alguém que acabou de apontar
|
|
17
|
+
* a ferramenta para o próprio repositório. Então ele vem junto, medido e congelado.
|
|
18
|
+
*
|
|
19
|
+
* COMO ATUALIZAR, quando o halogen publicar uma versão nova: baixe
|
|
20
|
+
* `https://www.synthesisui.com/api/registry/ds/halogen`, pegue `artifacts["tokens.css"]` e
|
|
21
|
+
* reescreva o escopo para a raiz como acima. É uma cópia deliberada, não uma dependência
|
|
22
|
+
* esquecida - e por isso a versão viaja ao lado, dita na própria página.
|
|
23
|
+
*
|
|
24
|
+
* O ESQUEMA: a raiz sozinha é ESCURA; `:root[data-scheme="light"]` é a clara. O relatório abre em
|
|
25
|
+
* claro por decisão dele (18/09), e o escuro continua ali para quem trocar o atributo.
|
|
26
|
+
*/
|
|
27
|
+
/** A versão do halogen que estas folhas descrevem - dita na página, para a divergência ser vista. */
|
|
28
|
+
export const HALOGEN_VERSION = 18;
|
|
29
|
+
/** `tokens.css` do halogen, com o escopo reescrito para a raiz e nada mais tocado. */
|
|
30
|
+
export const HALOGEN_TOKENS = String.raw `/* 39 more tokens of this system are not emitted here: nothing in it references them. They stay in the system and arrive the moment a recipe, a utility or a component asks. */
|
|
31
|
+
|
|
32
|
+
:root {
|
|
33
|
+
--ds-color-moss-400: #4f9d76;
|
|
34
|
+
--ds-color-moss-500: #3f8a66;
|
|
35
|
+
--ds-color-rose-400: #e0576a;
|
|
36
|
+
--ds-color-rose-500: #cf3f54;
|
|
37
|
+
--ds-color-veil-500: #05070ab3;
|
|
38
|
+
--ds-color-amber-400: #c9973f;
|
|
39
|
+
--ds-color-amber-500: #b3842f;
|
|
40
|
+
--ds-color-blush-400: #f79ce0;
|
|
41
|
+
--ds-color-slate-50: #ffffff;
|
|
42
|
+
--ds-color-slate-100: #f7f8f8;
|
|
43
|
+
--ds-color-slate-200: #e2e4e7;
|
|
44
|
+
--ds-color-slate-300: #d0d6e0;
|
|
45
|
+
--ds-color-slate-400: #8a8f98;
|
|
46
|
+
--ds-color-slate-500: #62666d;
|
|
47
|
+
--ds-color-slate-600: #383b3f;
|
|
48
|
+
--ds-color-slate-700: #23252a;
|
|
49
|
+
--ds-color-slate-800: #18191c;
|
|
50
|
+
--ds-color-slate-900: #0f1011;
|
|
51
|
+
--ds-color-slate-950: #08090a;
|
|
52
|
+
--ds-color-indigo-300: #a5b4ff;
|
|
53
|
+
--ds-color-indigo-400: #7c8cff;
|
|
54
|
+
--ds-color-indigo-500: #5b6cff;
|
|
55
|
+
--ds-color-semantic-info: var(--ds-color-indigo-400);
|
|
56
|
+
--ds-color-semantic-faint: var(--ds-color-slate-500);
|
|
57
|
+
--ds-color-semantic-muted: var(--ds-color-slate-400);
|
|
58
|
+
--ds-color-semantic-scrim: var(--ds-color-veil-500);
|
|
59
|
+
--ds-color-semantic-accent: var(--ds-color-blush-400);
|
|
60
|
+
--ds-color-semantic-border: var(--ds-color-slate-700);
|
|
61
|
+
--ds-color-semantic-canvas: var(--ds-color-slate-950);
|
|
62
|
+
--ds-color-semantic-danger: var(--ds-color-rose-400);
|
|
63
|
+
--ds-color-semantic-raised: var(--ds-color-slate-800);
|
|
64
|
+
--ds-color-semantic-overlay: var(--ds-color-slate-700);
|
|
65
|
+
--ds-color-semantic-primary: var(--ds-color-indigo-500);
|
|
66
|
+
--ds-color-semantic-success: var(--ds-color-moss-400);
|
|
67
|
+
--ds-color-semantic-surface: var(--ds-color-slate-900);
|
|
68
|
+
--ds-color-semantic-warning: var(--ds-color-amber-400);
|
|
69
|
+
--ds-color-semantic-foreground: var(--ds-color-slate-100);
|
|
70
|
+
--ds-color-series-1: var(--ds-color-indigo-500);
|
|
71
|
+
--ds-color-series-2: var(--ds-color-amber-500);
|
|
72
|
+
--ds-color-series-3: var(--ds-color-moss-500);
|
|
73
|
+
--ds-color-series-4: var(--ds-color-rose-500);
|
|
74
|
+
--ds-color-series-5: var(--ds-color-blush-400);
|
|
75
|
+
--ds-color-series-6: var(--ds-color-indigo-300);
|
|
76
|
+
--ds-color-series-7: var(--ds-color-moss-400);
|
|
77
|
+
--ds-color-series-8: var(--ds-color-rose-400);
|
|
78
|
+
--ds-radius-lg: 12px;
|
|
79
|
+
--ds-radius-md: 8px;
|
|
80
|
+
--ds-radius-sm: 6px;
|
|
81
|
+
--ds-radius-xs: 2px;
|
|
82
|
+
--ds-radius-full: 9999px;
|
|
83
|
+
--ds-shadow-md: 0 8px 24px #00000080;
|
|
84
|
+
--ds-shadow-sm: 0 2px 4px #00000066;
|
|
85
|
+
--ds-shadow-glow: 0 0 24px -6px #5b6cffaa;
|
|
86
|
+
--ds-shadow-ring: 0 0 0 1px #23252a inset;
|
|
87
|
+
--ds-spacing-lg: 2rem;
|
|
88
|
+
--ds-spacing-md: 1.5rem;
|
|
89
|
+
--ds-spacing-sm: 1rem;
|
|
90
|
+
--ds-spacing-xl: 3rem;
|
|
91
|
+
--ds-spacing-xs: 0.75rem;
|
|
92
|
+
--ds-spacing-2xl: 4rem;
|
|
93
|
+
--ds-spacing-2xs: 0.5rem;
|
|
94
|
+
--ds-spacing-3xl: 6rem;
|
|
95
|
+
--ds-spacing-3xs: 0.25rem;
|
|
96
|
+
--ds-typography-scale-lg-font-size: 1.25rem;
|
|
97
|
+
--ds-typography-scale-lg-line-height: 1.4;
|
|
98
|
+
--ds-typography-scale-sm-font-size: 0.875rem;
|
|
99
|
+
--ds-typography-scale-sm-line-height: 1.5;
|
|
100
|
+
--ds-typography-scale-xl-font-size: 1.5rem;
|
|
101
|
+
--ds-typography-scale-xl-line-height: 1.3;
|
|
102
|
+
--ds-typography-scale-xl-letter-spacing: -0.01em;
|
|
103
|
+
--ds-typography-scale-xs-font-size: 0.75rem;
|
|
104
|
+
--ds-typography-scale-xs-line-height: 1rem;
|
|
105
|
+
--ds-typography-scale-2xl-font-size: 2rem;
|
|
106
|
+
--ds-typography-scale-2xl-line-height: 1.2;
|
|
107
|
+
--ds-typography-scale-2xl-letter-spacing: -0.02em;
|
|
108
|
+
--ds-typography-scale-base-font-size: 1rem;
|
|
109
|
+
--ds-typography-scale-base-line-height: 1.6;
|
|
110
|
+
--ds-typography-scale-display-font-size: 4rem;
|
|
111
|
+
--ds-typography-scale-display-line-height: 1.05;
|
|
112
|
+
--ds-typography-scale-display-letter-spacing: -0.03em;
|
|
113
|
+
--ds-typography-weights-medium: 510;
|
|
114
|
+
--ds-typography-weights-regular: 400;
|
|
115
|
+
--ds-typography-weights-semibold: 590;
|
|
116
|
+
--ds-typography-families-body: "Inter Variable", sans-serif;
|
|
117
|
+
--ds-typography-families-mono: "Berkeley Mono", monospace;
|
|
118
|
+
--ds-typography-families-display: "Inter Variable", sans-serif;
|
|
119
|
+
--ds-motion-durations-base: 200ms;
|
|
120
|
+
--ds-motion-durations-fast: 120ms;
|
|
121
|
+
--ds-motion-durations-slow: 320ms;
|
|
122
|
+
--ds-motion-durations-ambient: 3.5s;
|
|
123
|
+
--ds-motion-easings-out: ease-out;
|
|
124
|
+
--ds-motion-easings-swift: cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
125
|
+
--ds-motion-easings-standard: ease;
|
|
126
|
+
--color-info: var(--ds-color-semantic-info);
|
|
127
|
+
--color-faint: var(--ds-color-semantic-faint);
|
|
128
|
+
--color-muted: var(--ds-color-semantic-muted);
|
|
129
|
+
--color-scrim: var(--ds-color-semantic-scrim);
|
|
130
|
+
--color-accent: var(--ds-color-semantic-accent);
|
|
131
|
+
--color-border: var(--ds-color-semantic-border);
|
|
132
|
+
--color-canvas: var(--ds-color-semantic-canvas);
|
|
133
|
+
--color-danger: var(--ds-color-semantic-danger);
|
|
134
|
+
--color-raised: var(--ds-color-semantic-raised);
|
|
135
|
+
--color-overlay: var(--ds-color-semantic-overlay);
|
|
136
|
+
--color-primary: var(--ds-color-semantic-primary);
|
|
137
|
+
--color-success: var(--ds-color-semantic-success);
|
|
138
|
+
--color-surface: var(--ds-color-semantic-surface);
|
|
139
|
+
--color-warning: var(--ds-color-semantic-warning);
|
|
140
|
+
--color-foreground: var(--ds-color-semantic-foreground);
|
|
141
|
+
--color-series-1: var(--ds-color-series-1);
|
|
142
|
+
--color-series-2: var(--ds-color-series-2);
|
|
143
|
+
--color-series-3: var(--ds-color-series-3);
|
|
144
|
+
--color-series-4: var(--ds-color-series-4);
|
|
145
|
+
--color-series-5: var(--ds-color-series-5);
|
|
146
|
+
--color-series-6: var(--ds-color-series-6);
|
|
147
|
+
--color-series-7: var(--ds-color-series-7);
|
|
148
|
+
--color-series-8: var(--ds-color-series-8);
|
|
149
|
+
--spacing-lg: var(--ds-spacing-lg);
|
|
150
|
+
--spacing-md: var(--ds-spacing-md);
|
|
151
|
+
--spacing-sm: var(--ds-spacing-sm);
|
|
152
|
+
--spacing-xl: var(--ds-spacing-xl);
|
|
153
|
+
--spacing-xs: var(--ds-spacing-xs);
|
|
154
|
+
--spacing-2xl: var(--ds-spacing-2xl);
|
|
155
|
+
--spacing-2xs: var(--ds-spacing-2xs);
|
|
156
|
+
--spacing-3xl: var(--ds-spacing-3xl);
|
|
157
|
+
--spacing-3xs: var(--ds-spacing-3xs);
|
|
158
|
+
--radius-lg: var(--ds-radius-lg);
|
|
159
|
+
--radius-md: var(--ds-radius-md);
|
|
160
|
+
--radius-sm: var(--ds-radius-sm);
|
|
161
|
+
--radius-xs: var(--ds-radius-xs);
|
|
162
|
+
--radius-full: var(--ds-radius-full);
|
|
163
|
+
--shadow-md: var(--ds-shadow-md);
|
|
164
|
+
--shadow-sm: var(--ds-shadow-sm);
|
|
165
|
+
--shadow-glow: var(--ds-shadow-glow);
|
|
166
|
+
--shadow-ring: var(--ds-shadow-ring);
|
|
167
|
+
--font-body: var(--ds-typography-families-body);
|
|
168
|
+
--font-mono: var(--ds-typography-families-mono);
|
|
169
|
+
--font-display: var(--ds-typography-families-display);
|
|
170
|
+
--font-weight-medium: var(--ds-typography-weights-medium);
|
|
171
|
+
--font-weight-regular: var(--ds-typography-weights-regular);
|
|
172
|
+
--font-weight-semibold: var(--ds-typography-weights-semibold);
|
|
173
|
+
--ease-out: var(--ds-motion-easings-out);
|
|
174
|
+
--ease-swift: var(--ds-motion-easings-swift);
|
|
175
|
+
--ease-standard: var(--ds-motion-easings-standard);
|
|
176
|
+
--text-lg: var(--ds-typography-scale-lg-font-size);
|
|
177
|
+
--text-lg--line-height: var(--ds-typography-scale-lg-line-height);
|
|
178
|
+
--text-sm: var(--ds-typography-scale-sm-font-size);
|
|
179
|
+
--text-sm--line-height: var(--ds-typography-scale-sm-line-height);
|
|
180
|
+
--text-xl: var(--ds-typography-scale-xl-font-size);
|
|
181
|
+
--text-xl--line-height: var(--ds-typography-scale-xl-line-height);
|
|
182
|
+
--text-xl--letter-spacing: var(--ds-typography-scale-xl-letter-spacing);
|
|
183
|
+
--text-xs: var(--ds-typography-scale-xs-font-size);
|
|
184
|
+
--text-xs--line-height: var(--ds-typography-scale-xs-line-height);
|
|
185
|
+
--text-2xl: var(--ds-typography-scale-2xl-font-size);
|
|
186
|
+
--text-2xl--line-height: var(--ds-typography-scale-2xl-line-height);
|
|
187
|
+
--text-2xl--letter-spacing: var(--ds-typography-scale-2xl-letter-spacing);
|
|
188
|
+
--text-base: var(--ds-typography-scale-base-font-size);
|
|
189
|
+
--text-base--line-height: var(--ds-typography-scale-base-line-height);
|
|
190
|
+
--text-display: var(--ds-typography-scale-display-font-size);
|
|
191
|
+
--text-display--line-height: var(--ds-typography-scale-display-line-height);
|
|
192
|
+
--text-display--letter-spacing: var(--ds-typography-scale-display-letter-spacing);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@layer base {
|
|
196
|
+
:root {
|
|
197
|
+
color: var(--ds-color-semantic-foreground);
|
|
198
|
+
font-family: var(--ds-typography-families-body);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
:root[data-scheme="light"] {
|
|
203
|
+
--ds-color-semantic-faint: var(--ds-color-slate-500);
|
|
204
|
+
--ds-color-semantic-muted: var(--ds-color-slate-600);
|
|
205
|
+
--ds-color-semantic-border: var(--ds-color-slate-300);
|
|
206
|
+
--ds-color-semantic-canvas: var(--ds-color-slate-100);
|
|
207
|
+
--ds-color-semantic-raised: var(--ds-color-slate-50);
|
|
208
|
+
--ds-color-semantic-overlay: var(--ds-color-slate-200);
|
|
209
|
+
--ds-color-semantic-surface: var(--ds-color-slate-50);
|
|
210
|
+
--ds-color-semantic-foreground: var(--ds-color-slate-900);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
:root[data-theme="light"] {
|
|
214
|
+
--ds-color-semantic-faint: var(--ds-color-slate-500);
|
|
215
|
+
--ds-color-semantic-muted: var(--ds-color-slate-600);
|
|
216
|
+
--ds-color-semantic-border: var(--ds-color-slate-300);
|
|
217
|
+
--ds-color-semantic-canvas: var(--ds-color-slate-100);
|
|
218
|
+
--ds-color-semantic-raised: var(--ds-color-slate-50);
|
|
219
|
+
--ds-color-semantic-overlay: var(--ds-color-slate-200);
|
|
220
|
+
--ds-color-semantic-surface: var(--ds-color-slate-50);
|
|
221
|
+
--ds-color-semantic-foreground: var(--ds-color-slate-900);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@layer base {
|
|
225
|
+
:root :is(a[href], button, summary, [role="button"], [role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="tab"], [role="switch"], [role="option"], [tabindex]:not([tabindex="-1"])):focus-visible {
|
|
226
|
+
outline-width: 2px;
|
|
227
|
+
outline-style: solid;
|
|
228
|
+
outline-color: var(--ds-color-semantic-primary);
|
|
229
|
+
outline-offset: 2px;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
@layer base {
|
|
234
|
+
:root .ds-avatar { flex-shrink: 0; }
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
@layer base {
|
|
238
|
+
@media (prefers-reduced-motion: reduce) {
|
|
239
|
+
:root *, :root *::before, :root *::after {
|
|
240
|
+
animation-duration: 0.01ms !important;
|
|
241
|
+
animation-iteration-count: 1 !important;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
@keyframes ds-halogen-rise {
|
|
247
|
+
to {
|
|
248
|
+
opacity: 1;
|
|
249
|
+
transform: translateY(0);
|
|
250
|
+
}
|
|
251
|
+
from {
|
|
252
|
+
opacity: 0;
|
|
253
|
+
transform: translateY(12px);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
@keyframes ds-halogen-blink {
|
|
258
|
+
0% {
|
|
259
|
+
opacity: 1;
|
|
260
|
+
}
|
|
261
|
+
50% {
|
|
262
|
+
opacity: 0;
|
|
263
|
+
}
|
|
264
|
+
100% {
|
|
265
|
+
opacity: 1;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@keyframes ds-halogen-float {
|
|
270
|
+
0% {
|
|
271
|
+
transform: translateY(0);
|
|
272
|
+
}
|
|
273
|
+
50% {
|
|
274
|
+
transform: translateY(-6px);
|
|
275
|
+
}
|
|
276
|
+
100% {
|
|
277
|
+
transform: translateY(0);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
@keyframes ds-halogen-pulse {
|
|
282
|
+
0% {
|
|
283
|
+
opacity: 0.5;
|
|
284
|
+
}
|
|
285
|
+
50% {
|
|
286
|
+
opacity: 1;
|
|
287
|
+
}
|
|
288
|
+
100% {
|
|
289
|
+
opacity: 0.5;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
@keyframes ds-halogen-sheen {
|
|
294
|
+
to {
|
|
295
|
+
transform: translateX(120%);
|
|
296
|
+
}
|
|
297
|
+
from {
|
|
298
|
+
transform: translateX(-120%);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
@keyframes ds-halogen-expand {
|
|
303
|
+
to {
|
|
304
|
+
opacity: 1;
|
|
305
|
+
transform: scaleX(1);
|
|
306
|
+
}
|
|
307
|
+
from {
|
|
308
|
+
opacity: 0;
|
|
309
|
+
transform: scaleX(0);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
@keyframes ds-halogen-slide-in {
|
|
314
|
+
to {
|
|
315
|
+
opacity: 1;
|
|
316
|
+
transform: translateX(0);
|
|
317
|
+
}
|
|
318
|
+
from {
|
|
319
|
+
opacity: 0;
|
|
320
|
+
transform: translateX(-10px);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
@layer base {
|
|
325
|
+
:root {
|
|
326
|
+
--animate-rise: ds-halogen-rise var(--ds-motion-durations-base, 200ms) var(--ds-motion-easings-standard, ease) both;
|
|
327
|
+
--animate-blink: ds-halogen-blink var(--ds-motion-durations-slow, 400ms) var(--ds-motion-easings-standard, ease);
|
|
328
|
+
--animate-float: ds-halogen-float var(--ds-motion-durations-ambient, 2s) var(--ds-motion-easings-gentle, ease-in-out) infinite;
|
|
329
|
+
--animate-pulse: ds-halogen-pulse var(--ds-motion-durations-ambient, 2s) var(--ds-motion-easings-gentle, ease-in-out) infinite;
|
|
330
|
+
--animate-sheen: ds-halogen-sheen var(--ds-motion-durations-ambient, 2s) var(--ds-motion-easings-gentle, ease-in-out) infinite;
|
|
331
|
+
--animate-expand: ds-halogen-expand var(--ds-motion-durations-base, 200ms) var(--ds-motion-easings-standard, ease) both;
|
|
332
|
+
--animate-slide-in: ds-halogen-slide-in var(--ds-motion-durations-base, 200ms) var(--ds-motion-easings-standard, ease) both;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
@layer components {
|
|
337
|
+
:root .ds-card {
|
|
338
|
+
padding: var(--ds-spacing-md);
|
|
339
|
+
box-shadow: var(--ds-shadow-ring);
|
|
340
|
+
transition: box-shadow var(--ds-motion-durations-base) var(--ds-motion-easings-swift);
|
|
341
|
+
border-radius: var(--ds-radius-lg);
|
|
342
|
+
background-color: var(--ds-color-semantic-surface);
|
|
343
|
+
color: inherit;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
:root .ds-card[data-padding="none"] {
|
|
347
|
+
padding: 0;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
:root .ds-card[data-emphasis="elevated"] {
|
|
351
|
+
box-shadow: var(--ds-shadow-md);
|
|
352
|
+
background-color: var(--ds-color-semantic-raised);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
:root .ds-card:hover {
|
|
356
|
+
box-shadow: var(--ds-shadow-ring), var(--ds-shadow-md);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
:root .ds-card[disabled] {
|
|
360
|
+
cursor: not-allowed;
|
|
361
|
+
opacity: 0.5;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
:root .ds-card[aria-disabled="true"] {
|
|
365
|
+
cursor: not-allowed;
|
|
366
|
+
opacity: 0.5;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
:root .ds-card[data-disabled] {
|
|
370
|
+
cursor: not-allowed;
|
|
371
|
+
opacity: 0.5;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
:root .ds-badge {
|
|
375
|
+
gap: var(--ds-spacing-3xs);
|
|
376
|
+
display: inline-flex;
|
|
377
|
+
padding: var(--ds-spacing-3xs) var(--ds-spacing-2xs);
|
|
378
|
+
font-size: var(--ds-typography-scale-xs-font-size);
|
|
379
|
+
align-items: center;
|
|
380
|
+
font-family: var(--ds-typography-families-mono);
|
|
381
|
+
line-height: var(--ds-typography-scale-xs-line-height);
|
|
382
|
+
border-radius: var(--ds-radius-sm);
|
|
383
|
+
letter-spacing: 0.08em;
|
|
384
|
+
text-transform: uppercase;
|
|
385
|
+
color: inherit;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
:root .ds-badge[data-intent="info"] {
|
|
389
|
+
color: var(--ds-color-semantic-info);
|
|
390
|
+
background-color: var(--ds-color-slate-800);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
:root .ds-badge[data-intent="accent"] {
|
|
394
|
+
color: var(--ds-color-semantic-accent);
|
|
395
|
+
background-color: var(--ds-color-slate-800);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
:root .ds-badge[data-intent="danger"] {
|
|
399
|
+
color: var(--ds-color-semantic-danger);
|
|
400
|
+
background-color: var(--ds-color-slate-800);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
:root .ds-badge[data-intent="neutral"] {
|
|
404
|
+
color: var(--ds-color-semantic-muted);
|
|
405
|
+
background-color: var(--ds-color-slate-800);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
:root .ds-badge[data-intent="success"] {
|
|
409
|
+
color: var(--ds-color-semantic-success);
|
|
410
|
+
background-color: var(--ds-color-slate-800);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
:root .ds-badge[data-intent="warning"] {
|
|
414
|
+
color: var(--ds-color-semantic-warning);
|
|
415
|
+
background-color: var(--ds-color-slate-800);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
:root .ds-input {
|
|
419
|
+
color: var(--ds-color-semantic-foreground);
|
|
420
|
+
width: 100%;
|
|
421
|
+
padding: var(--ds-spacing-2xs) var(--ds-spacing-xs);
|
|
422
|
+
font-size: var(--ds-typography-scale-sm-font-size);
|
|
423
|
+
box-shadow: var(--ds-shadow-ring);
|
|
424
|
+
font-family: var(--ds-typography-families-body);
|
|
425
|
+
line-height: var(--ds-typography-scale-sm-line-height);
|
|
426
|
+
transition: box-shadow var(--ds-motion-durations-fast) var(--ds-motion-easings-swift);
|
|
427
|
+
border-radius: var(--ds-radius-md);
|
|
428
|
+
background-color: var(--ds-color-semantic-canvas);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
:root .ds-input:focus-visible {
|
|
432
|
+
box-shadow: var(--ds-shadow-glow);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
:root .ds-input[disabled] {
|
|
436
|
+
cursor: not-allowed;
|
|
437
|
+
opacity: 0.5;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
:root .ds-input[aria-disabled="true"] {
|
|
441
|
+
cursor: not-allowed;
|
|
442
|
+
opacity: 0.5;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
:root .ds-input[data-disabled] {
|
|
446
|
+
cursor: not-allowed;
|
|
447
|
+
opacity: 0.5;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
:root .ds-avatar {
|
|
451
|
+
color: var(--ds-color-semantic-foreground);
|
|
452
|
+
width: 40px;
|
|
453
|
+
height: 40px;
|
|
454
|
+
display: inline-flex;
|
|
455
|
+
font-size: var(--ds-typography-scale-sm-font-size);
|
|
456
|
+
align-items: center;
|
|
457
|
+
font-family: var(--ds-typography-families-body);
|
|
458
|
+
font-weight: var(--ds-typography-weights-medium);
|
|
459
|
+
line-height: var(--ds-typography-scale-sm-line-height);
|
|
460
|
+
border-radius: var(--ds-radius-full);
|
|
461
|
+
justify-content: center;
|
|
462
|
+
background-color: var(--ds-color-semantic-overlay);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
:root .ds-avatar[data-size="lg"] {
|
|
466
|
+
width: 56px;
|
|
467
|
+
height: 56px;
|
|
468
|
+
font-size: var(--ds-typography-scale-lg-font-size);
|
|
469
|
+
line-height: var(--ds-typography-scale-lg-line-height);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
:root .ds-avatar[data-size="md"] {
|
|
473
|
+
width: 40px;
|
|
474
|
+
height: 40px;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
:root .ds-avatar[data-size="sm"] {
|
|
478
|
+
width: 28px;
|
|
479
|
+
height: 28px;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
:root .ds-button {
|
|
483
|
+
gap: var(--ds-spacing-2xs);
|
|
484
|
+
display: inline-flex;
|
|
485
|
+
padding: var(--ds-spacing-2xs) var(--ds-spacing-sm);
|
|
486
|
+
font-size: var(--ds-typography-scale-sm-font-size);
|
|
487
|
+
align-items: center;
|
|
488
|
+
font-family: var(--ds-typography-families-body);
|
|
489
|
+
font-weight: var(--ds-typography-weights-medium);
|
|
490
|
+
line-height: var(--ds-typography-scale-sm-line-height);
|
|
491
|
+
transition: all var(--ds-motion-durations-fast) var(--ds-motion-easings-swift);
|
|
492
|
+
border-radius: var(--ds-radius-md);
|
|
493
|
+
justify-content: center;
|
|
494
|
+
color: inherit;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
:root .ds-button[data-intent="ghost"] {
|
|
498
|
+
color: var(--ds-color-semantic-muted);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
:root .ds-button[data-intent="primary"] {
|
|
502
|
+
color: var(--ds-color-semantic-canvas);
|
|
503
|
+
box-shadow: var(--ds-shadow-glow);
|
|
504
|
+
background-color: var(--ds-color-semantic-primary);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
:root .ds-button[data-intent="secondary"] {
|
|
508
|
+
color: var(--ds-color-semantic-foreground);
|
|
509
|
+
box-shadow: var(--ds-shadow-ring);
|
|
510
|
+
background-color: var(--ds-color-slate-800);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
:root .ds-button:hover {
|
|
514
|
+
filter: brightness(1.12);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
:root .ds-button:active {
|
|
518
|
+
transform: translateY(1px);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
:root .ds-button[disabled] {
|
|
522
|
+
cursor: not-allowed;
|
|
523
|
+
opacity: 0.5;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
:root .ds-button[aria-disabled="true"] {
|
|
527
|
+
cursor: not-allowed;
|
|
528
|
+
opacity: 0.5;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
:root .ds-button[data-disabled] {
|
|
532
|
+
cursor: not-allowed;
|
|
533
|
+
opacity: 0.5;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
:root .ds-button:focus-visible {
|
|
537
|
+
outline: 2px solid var(--ds-color-semantic-primary);
|
|
538
|
+
outline-offset: 2px;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
:root .ds-select {
|
|
542
|
+
gap: var(--ds-spacing-2xs);
|
|
543
|
+
color: var(--ds-color-semantic-foreground);
|
|
544
|
+
border: 1px solid var(--ds-color-semantic-border);
|
|
545
|
+
display: inline-flex;
|
|
546
|
+
padding: var(--ds-spacing-2xs) var(--ds-spacing-xs);
|
|
547
|
+
font-size: var(--ds-typography-scale-sm-font-size);
|
|
548
|
+
align-items: center;
|
|
549
|
+
font-family: var(--ds-typography-families-body);
|
|
550
|
+
line-height: var(--ds-typography-scale-sm-line-height);
|
|
551
|
+
transition: border-color var(--ds-motion-durations-fast) var(--ds-motion-easings-standard);
|
|
552
|
+
border-radius: var(--ds-radius-md);
|
|
553
|
+
justify-content: space-between;
|
|
554
|
+
background-color: var(--ds-color-semantic-surface);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
:root .ds-select:focus-visible {
|
|
558
|
+
border-color: var(--ds-color-semantic-primary);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
:root .ds-select[disabled] {
|
|
562
|
+
cursor: not-allowed;
|
|
563
|
+
opacity: 0.5;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
:root .ds-select[aria-disabled="true"] {
|
|
567
|
+
cursor: not-allowed;
|
|
568
|
+
opacity: 0.5;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
:root .ds-select[data-disabled] {
|
|
572
|
+
cursor: not-allowed;
|
|
573
|
+
opacity: 0.5;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
:root .ds-command-bar {
|
|
577
|
+
gap: var(--ds-spacing-2xs);
|
|
578
|
+
color: var(--ds-color-semantic-muted);
|
|
579
|
+
width: 100%;
|
|
580
|
+
border: 1px solid var(--ds-color-semantic-border);
|
|
581
|
+
display: flex;
|
|
582
|
+
padding: var(--ds-spacing-2xs) var(--ds-spacing-sm);
|
|
583
|
+
font-size: var(--ds-typography-scale-sm-font-size);
|
|
584
|
+
box-shadow: var(--ds-shadow-ring);
|
|
585
|
+
align-items: center;
|
|
586
|
+
font-family: var(--ds-typography-families-mono);
|
|
587
|
+
line-height: var(--ds-typography-scale-sm-line-height);
|
|
588
|
+
border-radius: var(--ds-radius-md);
|
|
589
|
+
background-color: var(--ds-color-semantic-surface);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
:root .ds-command-bar:focus-visible {
|
|
593
|
+
box-shadow: var(--ds-shadow-glow);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
:root .ds-command-bar[disabled] {
|
|
597
|
+
cursor: not-allowed;
|
|
598
|
+
opacity: 0.5;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
:root .ds-command-bar[aria-disabled="true"] {
|
|
602
|
+
cursor: not-allowed;
|
|
603
|
+
opacity: 0.5;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
:root .ds-command-bar[data-disabled] {
|
|
607
|
+
cursor: not-allowed;
|
|
608
|
+
opacity: 0.5;
|
|
609
|
+
}
|
|
610
|
+
}`;
|
package/package.json
CHANGED