synthesisui 0.16.448 → 0.16.449

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.
@@ -30,6 +30,7 @@ import { componentsPagesReachFor, pageLaws } from "../doctor/page-laws.js";
30
30
  import { callSiteNode, placeLayers, } from "../doctor/place-layers.js";
31
31
  import { publicApi, requiredProps } from "../doctor/public-api.js";
32
32
  import { aliasesOf, describeReachability, edgesIn, reachabilityOf, } from "../doctor/reachability.js";
33
+ import { rootGroundOf } from "../doctor/root-ground.js";
33
34
  import { diagnose, scanSource } from "../doctor/scan.js";
34
35
  import { parseSchemeBlocks } from "../doctor/scheme-blocks.js";
35
36
  import { describeSignals, emptySignals, finishSignals, readSignalsInto, } from "../doctor/signals.js";
@@ -2408,6 +2409,15 @@ export async function takeCensus(root, opts) {
2408
2409
  sheets: globalSheets.map((g) => ({ file: g.file, css: g.body })),
2409
2410
  signals: signals.theme,
2410
2411
  });
2412
+ /**
2413
+ * O CHAO DA FACE PADRAO - a mesma folha, outra pergunta.
2414
+ *
2415
+ * `polarity` responde QUAL face o projeto abre; isto responde O QUE ela veste. Sao
2416
+ * fatos separados de proposito: um projeto pode ter chao sem ter polaridade declarada,
2417
+ * e e' exatamente o caso que fazia o `canvas` ser escolhido por casamento de palavra.
2418
+ * Ver `root-ground.ts` para a medicao do `codelevel` que motivou isto.
2419
+ */
2420
+ const rootGround = rootGroundOf(globalSheets.map((g) => ({ file: g.file, css: g.body })));
2411
2421
  const declaredSchemes = {
2412
2422
  base: Object.fromEntries(schemes.base),
2413
2423
  light: Object.fromEntries(schemes.light),
@@ -2415,6 +2425,9 @@ export async function takeCensus(root, opts) {
2415
2425
  defaultScheme: polarity.scheme,
2416
2426
  defaultSchemeSource: polarity.source,
2417
2427
  ...(polarity.evidence ? { defaultSchemeEvidence: polarity.evidence } : {}),
2428
+ ...(rootGround.background != null || rootGround.color != null
2429
+ ? { rootGround }
2430
+ : {}),
2418
2431
  };
2419
2432
  // Every name their CSS defines, from the same harvest the token table came
2420
2433
  // from - so a reference is judged against what actually exists, not against
@@ -0,0 +1,86 @@
1
+ /**
2
+ * O QUE A PÁGINA VESTE, lido da regra em vez de adivinhado pelo nome do token.
3
+ *
4
+ * O QUE ISTO RESOLVE PARA O CLIENTE: o `canvas` e o `foreground` da face padrão dele
5
+ * param de ser escolhidos por casamento de palavra. Medido no `codelevel` em 21/09: o
6
+ * fundo da página é `--color-paper` (`#fbfaf6`) e o texto é `--color-ink-900`
7
+ * (`#0c0c11`), escritos numa regra de raiz sem escopo nenhum:
8
+ *
9
+ * html, body { background: var(--color-paper); color: var(--color-ink-900); }
10
+ * html.dark { background: var(--color-ink-950); color: var(--color-ink-50); }
11
+ *
12
+ * O vocabulário de `canvas` em `census-import` é `["canvas","background","bg","page",…]`.
13
+ * `--color-code-bg` casa por causa do `bg` e ganhou o fundo da página; `--color-paper`
14
+ * não casa com nada e sobrou. A tela dele passou a chamar `CODE-BG` de *"Page
15
+ * background"*, e a paleta clara nasceu com o fundo de um bloco de código.
16
+ *
17
+ * A REGRA NÃO TEM ESSE PROBLEMA porque ela não descreve o token, ela descreve o uso: o
18
+ * que está depois de `background:` na raiz do documento É o fundo da página, com o nome
19
+ * que for.
20
+ *
21
+ * COMO A FACE É NOMEADA, sem encostar em luminância. A restrição do dono (28/08) proíbe
22
+ * decidir polaridade por luminância, por nome de token, por nome de repositório ou por
23
+ * presença ISOLADA de `.dark`. Aqui não é presença isolada: é um PAR. A raiz sem escopo
24
+ * veste um chão, e um bloco com escopo `dark` veste outro nas mesmas propriedades. O
25
+ * primeiro é a face padrão por ser o que não tem escopo; o segundo se chama `dark` pelo
26
+ * próprio seletor. Logo a padrão é `light` — e nenhuma cor foi medida para dizer isso.
27
+ *
28
+ * SEM O PAR, A FACE CONTINUA SEM NOME. Um projeto que só tem a raiz sem escopo tem chão,
29
+ * mas não tem como dizer de que face ele é: `counterpart` sai `null` e quem consome
30
+ * decide o que fazer com um chão anônimo. Chão sem nome ainda vale — ele diz qual é o
31
+ * fundo e qual é o texto da face que o projeto abre, que é exatamente o que faltava.
32
+ */
33
+ import { scopedBlocks } from "./scheme-scope.js";
34
+ /** As propriedades que pintam o chão. `background` abreviado inclui a cor. */
35
+ const GROUND = /^(background|background-color|color)$/i;
36
+ const VAZIO = { background: null, color: null, counterpart: null };
37
+ /**
38
+ * A PRIMEIRA DECLARAÇÃO VENCE, a mesma regra de `parseSchemeBlocks`.
39
+ *
40
+ * Cascata entre folhas é coisa que um scanner não vê, e inventar uma ordem aqui seria
41
+ * inventar um vencedor. Duas folhas discordando do chão é um fato sobre o projeto, não
42
+ * uma escolha deste módulo — e a primeira é a que a varredura encontra.
43
+ */
44
+ export function rootGroundOf(sheets) {
45
+ let background = null;
46
+ let color = null;
47
+ let evidence;
48
+ /** As faces com escopo que também vestem chão — é o que nomeia a face padrão. */
49
+ const opostas = new Set();
50
+ for (const sheet of sheets) {
51
+ for (const block of scopedBlocks(sheet.css)) {
52
+ if (block.scope === "other")
53
+ continue;
54
+ const vestidas = block.declarations.filter((d) => GROUND.test(d.name));
55
+ if (vestidas.length === 0)
56
+ continue;
57
+ if (block.scope !== "base") {
58
+ opostas.add(block.scope);
59
+ continue;
60
+ }
61
+ for (const d of vestidas) {
62
+ const nome = d.name.toLowerCase();
63
+ if (nome === "color") {
64
+ if (color == null) {
65
+ color = d.value.trim();
66
+ evidence ??= { file: sheet.file, selector: block.stack.join(" ") };
67
+ }
68
+ continue;
69
+ }
70
+ if (background == null) {
71
+ background = d.value.trim();
72
+ evidence ??= { file: sheet.file, selector: block.stack.join(" ") };
73
+ }
74
+ }
75
+ }
76
+ }
77
+ if (background == null && color == null)
78
+ return VAZIO;
79
+ /**
80
+ * UMA CONTRAPARTE SÓ NOMEIA. Se as duas faces com escopo vestem chão, o projeto tem
81
+ * claro E escuro escritos à mão e a raiz sem escopo é um terceiro estado — aí ela não
82
+ * é "a outra", e o chão fica anônimo em vez de receber um nome sorteado.
83
+ */
84
+ const counterpart = opostas.size === 1 ? (opostas.has("dark") ? "light" : "dark") : null;
85
+ return { background, color, counterpart, ...(evidence ? { evidence } : {}) };
86
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.448",
3
+ "version": "0.16.449",
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": {