synthesisui 0.16.430 → 0.16.431

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.
@@ -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
  {
@@ -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.
@@ -47,60 +49,163 @@ export function relatorioHtml(input) {
47
49
  const quando = legivel(cabecalho.medidoEm);
48
50
  const indice = secoes
49
51
  .map((s, i) => `<li><a href="#s${i}">${escapar(s.titulo)}</a></li>`)
50
- .join("\n ");
52
+ .join("\n ");
51
53
  const corpo = secoes
52
- .map((s, i) => ` <section id="s${i}">
54
+ .map((s, i) => ` <section id="s${i}" class="chapter" style="--ordem:${Math.min(i, 12)}">
53
55
  <h2>${escapar(s.titulo)}</h2>
54
- <pre>${escapar(s.linhas.join("\n"))}</pre>
56
+ ${desenharCorpo(s)}
55
57
  </section>`)
56
58
  .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");
59
+ const numeros = destaques.map(cartaoDeNumero).join("\n");
63
60
  return `<!doctype html>
64
- <html lang="en">
61
+ <html lang="en" data-scheme="light">
65
62
  <head>
66
63
  <meta charset="utf-8">
67
64
  <meta name="viewport" content="width=device-width, initial-scale=1">
68
65
  <title>${escapar(cabecalho.repo)} - read by SynthesisUI</title>
69
66
  <style>
70
- ${estilo()}
67
+ ${HALOGEN_TOKENS}
68
+ </style>
69
+ <style>
70
+ ${layout()}
71
71
  </style>
72
72
  </head>
73
73
  <body>
74
- <header>
75
- <p class="kicker">Read by SynthesisUI</p>
76
- <h1>${escapar(cabecalho.repo)}</h1>
77
- <p class="meta">Read ${escapar(quando)} by CLI ${escapar(cabecalho.cli)} &middot; nothing left this machine</p>
74
+ <header class="bar">
75
+ <div class="bar-in">
76
+ <div class="bar-id">
77
+ <p class="kicker">Read by SynthesisUI</p>
78
+ <p class="bar-repo">${escapar(cabecalho.repo)}</p>
79
+ </div>
80
+ <p class="meta">${escapar(quando)} &middot; CLI ${escapar(cabecalho.cli)} &middot; nothing left this machine</p>
81
+ </div>
78
82
  </header>
79
83
 
80
- <div class="wrap">
81
- <div class="stats">
84
+ <main class="wrap">
85
+ <section class="hero chapter" style="--ordem:0">
86
+ <h1>${escapar(cabecalho.repo)}</h1>
87
+ <p class="lede">This is what your own code says about itself.</p>
88
+ <div class="stats">
82
89
  ${numeros}
83
- </div>
90
+ </div>
91
+ </section>
84
92
 
85
- <nav>
93
+ <nav class="chapter" style="--ordem:1">
86
94
  <p class="kicker">What is in here</p>
87
95
  <ol>
88
- ${indice}
96
+ ${indice}
89
97
  </ol>
90
98
  </nav>
91
99
 
92
- <main>
93
100
  ${corpo}
94
- </main>
95
101
 
96
102
  <footer>
103
+ <p>Dressed by Halogen v${HALOGEN_VERSION}, a design system from the SynthesisUI gallery.</p>
97
104
  <p>This file lives in your project and was never sent anywhere. Re-run the command to refresh it.</p>
98
105
  </footer>
99
- </div>
106
+ </main>
100
107
  </body>
101
108
  </html>
102
109
  `;
103
110
  }
111
+ /**
112
+ * O NÚMERO COM A FATIA DESENHADA - e a barra só aparece quando existe denominador medido.
113
+ *
114
+ * `aria-hidden` na barra porque ela não diz nada que o número ao lado já não diga; um leitor de
115
+ * tela que a anunciasse leria a mesma informação duas vezes.
116
+ */
117
+ function cartaoDeNumero(d) {
118
+ const temBarra = typeof d.parte === "number" && typeof d.de === "number" && d.de > 0;
119
+ const pct = temBarra
120
+ ? Math.max(0, Math.min(100, Math.round(((d.parte ?? 0) / (d.de ?? 1)) * 100)))
121
+ : 0;
122
+ return ` <div class="stat">
123
+ <strong>${escapar(d.numero)}</strong>
124
+ <span>${escapar(d.rotulo)}</span>${temBarra
125
+ ? `
126
+ <div class="bar-track" aria-hidden="true"><i style="--pct:${pct}%"></i></div>`
127
+ : ""}
128
+ </div>`;
129
+ }
130
+ /**
131
+ * COMO CADA CAPÍTULO É DESENHADO - e a decisão é sobre REPETIÇÃO, não sobre o assunto.
132
+ *
133
+ * Medido no `codelevel-monorepo` em 18/09: uma única seção trazia 94 linhas com a mesma forma
134
+ * (`two parts named X - the second is Y`), num bloco monoespaçado onde nada se acha. Uma lista de
135
+ * itens repetidos é uma TABELA, e uma tabela é varrida com o olho; o bloco de texto é lido linha a
136
+ * linha ou não é lido.
137
+ *
138
+ * O corte é mecânico e não conhece assunto nenhum: uma família só vira tabela a partir de seis
139
+ * linhas irmãs, porque abaixo disso a tabela custa mais atenção do que economiza.
140
+ */
141
+ function desenharCorpo(s) {
142
+ const familias = agrupar(s.linhas);
143
+ return familias
144
+ .map((f) => f.tipo === "tabela"
145
+ ? ` <details class="familia" open>
146
+ <summary>${escapar(f.rotulo)} <b>${f.itens.length}</b></summary>
147
+ <ul class="grade">
148
+ ${f.itens.map((i) => ` <li>${escapar(i)}</li>`).join("\n")}
149
+ </ul>
150
+ </details>`
151
+ : ` <pre>${escapar(f.itens.join("\n"))}</pre>`)
152
+ .join("\n");
153
+ }
154
+ const MINIMO_PARA_TABELA = 6;
155
+ /**
156
+ * A FORMA DE UMA LINHA, sem ler o que ela diz: as palavras ficam, os nomes próprios viram `·`.
157
+ *
158
+ * É isso que faz `two parts named \`box\`` e `two parts named \`nav\`` caírem na mesma família sem
159
+ * ninguém escrever uma regra sobre partes - e é isso que faz a regra valer para a próxima classe de
160
+ * linha repetida, que ninguém ainda viu (`INV-GERAL-07`).
161
+ */
162
+ function forma(linha) {
163
+ return linha
164
+ .trim()
165
+ .replace(/`[^`]*`/g, "·")
166
+ .replace(/\d+/g, "#")
167
+ .split(/\s+/)
168
+ .slice(0, 6)
169
+ .join(" ");
170
+ }
171
+ function agrupar(linhas) {
172
+ const saida = [];
173
+ let i = 0;
174
+ while (i < linhas.length) {
175
+ const atual = linhas[i];
176
+ if (!atual.trim()) {
177
+ empilharProsa(saida, atual);
178
+ i += 1;
179
+ continue;
180
+ }
181
+ const f = forma(atual);
182
+ let j = i;
183
+ const irmas = [];
184
+ while (j < linhas.length && linhas[j].trim() && forma(linhas[j]) === f) {
185
+ irmas.push(linhas[j].trim());
186
+ j += 1;
187
+ }
188
+ if (irmas.length >= MINIMO_PARA_TABELA) {
189
+ saida.push({ tipo: "tabela", rotulo: rotuloDe(f), itens: irmas });
190
+ i = j;
191
+ continue;
192
+ }
193
+ empilharProsa(saida, atual);
194
+ i += 1;
195
+ }
196
+ return saida.filter((f) => f.itens.some((l) => l.trim()));
197
+ }
198
+ function empilharProsa(saida, linha) {
199
+ const ultimo = saida[saida.length - 1];
200
+ if (ultimo && ultimo.tipo === "prosa")
201
+ ultimo.itens.push(linha);
202
+ else
203
+ saida.push({ tipo: "prosa", rotulo: "", itens: [linha] });
204
+ }
205
+ /** O rótulo da família é a própria forma, com os buracos ditos em vez de mostrados. */
206
+ function rotuloDe(f) {
207
+ return f.replace(/·/g, "…").replace(/#/g, "n").trim() || "repeated lines";
208
+ }
104
209
  /** A data em palavras. Data ilegível some da frase em vez de imprimir `Invalid Date`. */
105
210
  function legivel(iso) {
106
211
  if (!iso || Number.isNaN(Date.parse(iso)))
@@ -112,94 +217,178 @@ function legivel(iso) {
112
217
  });
113
218
  }
114
219
  /**
115
- * A FOLHA, E ELA É INTEIRA DAQUI: nenhuma família remota, nenhum reset de terceiro. As famílias são
116
- * as genéricas do sistema de quem abrir, porque baixar uma fonte para desenhar um relatório sobre o
117
- * repositório de alguém contradiz o comando que não manda nada para lugar nenhum.
220
+ * O LAYOUT DESTA PÁGINA, e só ele: cor, raio e fonte vêm dos tokens do halogen logo acima.
221
+ *
222
+ * A BARRA É FIXA porque os três números são a razão de a página existir - e numa leitura de
223
+ * dezesseis capítulos eles somem na primeira rolagem, que é quando a pessoa mais precisa deles
224
+ * para saber o que está olhando.
225
+ *
226
+ * O MOVIMENTO CARREGA INFORMAÇÃO: cada capítulo entra de baixo, na ordem em que a esteira o
227
+ * escreveu, e o atraso é a posição dele. Ele para inteiro sob `prefers-reduced-motion` - uma
228
+ * página que desliza dezesseis vezes são dezesseis chances de passar mal.
118
229
  *
119
230
  * E ela imprime: `@media print` existe porque o navegador já exporta PDF, e um relatório que sai
120
231
  * torto no papel obriga a construir um gerador de PDF para resolver o que uma regra resolve.
121
232
  */
122
- function estilo() {
123
- return `:root {
124
- color-scheme: light dark;
125
- --ink: #16161a;
126
- --ink-soft: #55555f;
127
- --line: #e4e4e9;
128
- --paper: #ffffff;
129
- --canvas: #f6f6f8;
130
- --accent: #b4530a;
131
- }
132
- @media (prefers-color-scheme: dark) {
133
- :root {
134
- --ink: #edecea;
135
- --ink-soft: #a0a0aa;
136
- --line: #2a2a31;
137
- --paper: #17171b;
138
- --canvas: #0f0f12;
139
- --accent: #e9a13b;
140
- }
233
+ function layout() {
234
+ /**
235
+ * A COSTURA DAS FAMÍLIAS VEM DA CONST, e não do literal: renomear o prefixo em `fonts.ts` tem
236
+ * que alcançar esta página também. Um literal solto aqui divergiria em silêncio, que é
237
+ * exatamente o que o portão de `fonts.spec.ts` existe para impedir.
238
+ */
239
+ const corpo = `var(${FAMILY_SEAM_PREFIX}body, ui-sans-serif, system-ui, sans-serif)`;
240
+ const mono = `var(${FAMILY_SEAM_PREFIX}mono, ui-monospace, monospace)`;
241
+ const display = `var(${FAMILY_SEAM_PREFIX}display, inherit)`;
242
+ return `body {
243
+ margin: 0;
244
+ background: var(--ds-color-semantic-canvas);
245
+ color: var(--ds-color-semantic-foreground);
246
+ font-family: ${corpo};
247
+ font-size: 15px;
248
+ line-height: 1.6;
141
249
  }
142
250
  * { box-sizing: border-box; }
143
- body {
144
- margin: 0;
145
- background: var(--canvas);
146
- color: var(--ink);
147
- font: 15px/1.6 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
251
+
252
+ .bar {
253
+ position: sticky;
254
+ top: 0;
255
+ z-index: 10;
256
+ background: var(--ds-color-semantic-raised, var(--ds-color-semantic-surface));
257
+ border-bottom: 1px solid var(--ds-color-semantic-border);
148
258
  }
149
- header {
150
- padding: 56px 24px 40px;
151
- border-bottom: 1px solid var(--line);
152
- background: var(--paper);
259
+ .bar-in {
260
+ max-width: 920px;
261
+ margin-inline: auto;
262
+ padding: 12px 24px;
263
+ display: flex;
264
+ flex-wrap: wrap;
265
+ gap: 8px 24px;
266
+ align-items: baseline;
267
+ justify-content: space-between;
153
268
  }
154
- .wrap, header > * { max-width: 900px; margin-inline: auto; }
155
- .wrap { padding: 0 24px 72px; }
269
+ .bar-repo { margin: 2px 0 0; font-weight: 600; }
270
+ .bar-id { min-width: 0; }
271
+
272
+ .wrap { max-width: 920px; margin-inline: auto; padding: 0 24px 96px; }
273
+
156
274
  .kicker {
157
275
  margin: 0;
158
- font: 600 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
276
+ font-family: ${mono};
277
+ font-size: 11px;
159
278
  letter-spacing: 0.16em;
160
279
  text-transform: uppercase;
161
- color: var(--accent);
280
+ color: var(--ds-color-semantic-accent);
162
281
  }
163
- h1 { margin: 12px 0 8px; font-size: 34px; line-height: 1.15; letter-spacing: -0.02em; }
164
- .meta { margin: 0; color: var(--ink-soft); font-size: 14px; }
282
+ .meta { margin: 0; color: var(--ds-color-semantic-muted); font-size: 13px; }
283
+
284
+ .hero { padding: 56px 0 8px; }
285
+ h1 {
286
+ margin: 10px 0 8px;
287
+ font-family: ${display};
288
+ font-size: 40px;
289
+ line-height: 1.1;
290
+ letter-spacing: -0.02em;
291
+ }
292
+ .lede { margin: 0 0 28px; color: var(--ds-color-semantic-muted); font-size: 17px; }
293
+
165
294
  .stats {
166
295
  display: grid;
167
296
  gap: 12px;
168
- grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
169
- margin: -28px 0 40px;
297
+ grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
170
298
  }
171
299
  .stat {
172
- background: var(--paper);
173
- border: 1px solid var(--line);
174
- border-radius: 14px;
300
+ background: var(--ds-color-semantic-surface);
301
+ border: 1px solid var(--ds-color-semantic-border);
302
+ border-radius: var(--ds-radius-lg, 14px);
175
303
  padding: 18px 20px;
176
304
  }
177
- .stat strong { display: block; font-size: 26px; letter-spacing: -0.02em; }
178
- .stat span { display: block; margin-top: 4px; color: var(--ink-soft); font-size: 13px; }
179
- nav { margin-bottom: 40px; }
180
- nav ol { margin: 10px 0 0; padding-left: 20px; color: var(--ink-soft); }
305
+ .stat strong { display: block; font-size: 28px; letter-spacing: -0.02em; }
306
+ .stat span { display: block; margin-top: 4px; color: var(--ds-color-semantic-muted); font-size: 13px; }
307
+ .bar-track {
308
+ margin-top: 14px;
309
+ height: 6px;
310
+ border-radius: 999px;
311
+ background: var(--ds-color-semantic-overlay, var(--ds-color-semantic-border));
312
+ overflow: hidden;
313
+ }
314
+ .bar-track i {
315
+ display: block;
316
+ height: 100%;
317
+ width: var(--pct);
318
+ border-radius: inherit;
319
+ background: var(--ds-color-semantic-accent);
320
+ animation: crescer 900ms cubic-bezier(0.22, 1, 0.36, 1) both;
321
+ }
322
+
323
+ nav { margin: 44px 0 8px; }
324
+ nav ol { margin: 10px 0 0; padding-left: 20px; color: var(--ds-color-semantic-muted); }
181
325
  nav li { margin: 3px 0; }
182
- nav a { color: inherit; }
183
- nav a:hover { color: var(--accent); }
184
- section {
185
- background: var(--paper);
186
- border: 1px solid var(--line);
187
- border-radius: 14px;
188
- padding: 22px 24px;
189
- margin-bottom: 16px;
190
- }
191
- h2 { margin: 0 0 12px; font-size: 17px; letter-spacing: -0.01em; }
326
+ nav a { color: inherit; text-underline-offset: 3px; }
327
+ nav a:hover { color: var(--ds-color-semantic-accent); }
328
+
329
+ section.chapter {
330
+ background: var(--ds-color-semantic-surface);
331
+ border: 1px solid var(--ds-color-semantic-border);
332
+ border-radius: var(--ds-radius-lg, 14px);
333
+ padding: 24px 26px;
334
+ margin-top: 16px;
335
+ scroll-margin-top: 84px;
336
+ }
337
+ .hero, nav { background: none; border: 0; padding-inline: 0; }
338
+ h2 { margin: 0 0 14px; font-size: 18px; letter-spacing: -0.01em; }
339
+
192
340
  pre {
193
- margin: 0;
341
+ margin: 0 0 12px;
194
342
  white-space: pre-wrap;
195
343
  word-break: break-word;
196
- font: 12.5px/1.65 ui-monospace, SFMono-Regular, Menlo, monospace;
197
- color: var(--ink-soft);
344
+ font-family: ${mono};
345
+ font-size: 12.5px;
346
+ line-height: 1.7;
347
+ color: var(--ds-color-semantic-muted);
348
+ }
349
+
350
+ .familia {
351
+ margin: 0 0 12px;
352
+ border: 1px solid var(--ds-color-semantic-border);
353
+ border-radius: var(--ds-radius-md, 10px);
354
+ padding: 10px 14px;
355
+ background: var(--ds-color-semantic-canvas);
356
+ }
357
+ .familia summary {
358
+ cursor: pointer;
359
+ font-size: 13px;
360
+ color: var(--ds-color-semantic-muted);
361
+ }
362
+ .familia summary b {
363
+ color: var(--ds-color-semantic-foreground);
364
+ font-variant-numeric: tabular-nums;
198
365
  }
199
- footer { margin-top: 40px; color: var(--ink-soft); font-size: 13px; }
366
+ .grade {
367
+ list-style: none;
368
+ margin: 12px 0 4px;
369
+ padding: 0;
370
+ display: grid;
371
+ gap: 4px 20px;
372
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
373
+ font-family: ${mono};
374
+ font-size: 12px;
375
+ color: var(--ds-color-semantic-muted);
376
+ }
377
+
378
+ footer { margin-top: 40px; color: var(--ds-color-semantic-muted); font-size: 13px; }
379
+
380
+ @keyframes crescer { from { width: 0; } }
381
+ @keyframes entrar { from { opacity: 0; transform: translateY(12px); } }
382
+ .chapter { animation: entrar 620ms cubic-bezier(0.22, 1, 0.36, 1) both; animation-delay: calc(var(--ordem, 0) * 55ms); }
383
+
384
+ @media (prefers-reduced-motion: reduce) {
385
+ .chapter, .bar-track i { animation: none; }
386
+ }
387
+
200
388
  @media print {
201
- body { background: #fff; }
202
- .stat, section { break-inside: avoid; border-color: #ddd; }
389
+ .bar { position: static; }
203
390
  nav { display: none; }
391
+ .stat, section.chapter { break-inside: avoid; }
392
+ .familia { break-inside: auto; }
204
393
  }`;
205
394
  }
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.430",
3
+ "version": "0.16.431",
4
4
  "description": "Bring SynthesisUI design systems into any project - tokens, typed components, whole pages and an agent-ready CLAUDE.md manifest.",
5
5
  "type": "module",
6
6
  "bin": {