@weasel-js/theme 1.10.0 → 1.10.1
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/README.md +48 -1
- package/dist/chunk-32JKTYS2.js +160 -0
- package/dist/chunk-32JKTYS2.js.map +1 -0
- package/dist/chunk-354G4TUL.js +246 -0
- package/dist/chunk-354G4TUL.js.map +1 -0
- package/dist/{chunk-3NIEJ77B.js → chunk-5PFIA5JU.js} +108 -14
- package/dist/chunk-5PFIA5JU.js.map +1 -0
- package/dist/chunk-M3R5MV7Q.js +10 -0
- package/dist/chunk-M3R5MV7Q.js.map +1 -0
- package/dist/{chunk-2PY2YTDY.js → chunk-S7MJPFDP.js} +5 -158
- package/dist/chunk-S7MJPFDP.js.map +1 -0
- package/dist/engine.js +3 -2
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +28 -6
- package/dist/index.js +8 -247
- package/dist/index.js.map +1 -1
- package/dist/prefs.d.ts +62 -0
- package/dist/prefs.js +193 -0
- package/dist/prefs.js.map +1 -0
- package/dist/react.js +5 -3
- package/dist/react.js.map +1 -1
- package/package.json +8 -3
- package/dist/chunk-2PY2YTDY.js.map +0 -1
- package/dist/chunk-3NIEJ77B.js.map +0 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ definition into CSS custom properties plus a parallel TS export.
|
|
|
5
5
|
|
|
6
6
|
Part of [weasel](https://github.com/orochi235/weasel), a domain-agnostic 2D
|
|
7
7
|
scene-graph canvas kit for React. See the
|
|
8
|
-
[API reference](https://orochi235.github.io/weasel/
|
|
8
|
+
[API reference](https://orochi235.github.io/weasel/#pkg/theme).
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -76,6 +76,53 @@ beside it. The resolved record carries that CSS as is, because a canvas has no
|
|
|
76
76
|
`currentColor`; flatten it with `resolveCurrentColor(value, resolved['--wzl-fg'])`,
|
|
77
77
|
passing the color of the text it is drawn beside.
|
|
78
78
|
|
|
79
|
+
## Between two modes
|
|
80
|
+
|
|
81
|
+
`blendTheme(theme, weights, selection?)` is the theme partway between values
|
|
82
|
+
of its axes, as `resolveTheme` returns one:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
blendTheme(acme, { mode: { dark: 0.25, light: 0.75 } });
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
It resolves the theme at each weighted selection and mixes what each token
|
|
89
|
+
resolved to: a color in OKLCH, a number with one unit linearly, and anything
|
|
90
|
+
else the heaviest selection's. `applyTheme(el, theme, selection, { weights })`
|
|
91
|
+
holds that blend where it would hold the selection, so calling it with the
|
|
92
|
+
next weights is one frame of a crossfade.
|
|
93
|
+
|
|
94
|
+
## As a prefs schema
|
|
95
|
+
|
|
96
|
+
`@weasel-js/theme/prefs` turns a theme into a `@weasel-js/prefs` schema, and a
|
|
97
|
+
store over that schema back into a theme:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { openPrefsSync } from '@weasel-js/prefs';
|
|
101
|
+
import { applyTheme, weaselTheme } from '@weasel-js/theme';
|
|
102
|
+
import { themeFromPrefs, themePrefsSchema, themePrefsSelection } from '@weasel-js/theme/prefs';
|
|
103
|
+
|
|
104
|
+
const store = openPrefsSync(themePrefsSchema(weaselTheme), { storage, prefix: 'theme.' });
|
|
105
|
+
store.set('accent.accent-base', '#ff3366');
|
|
106
|
+
store.set('surface.surface', '#fffdf8', { at: { 'axis.mode': 'light' } });
|
|
107
|
+
|
|
108
|
+
applyTheme(document.documentElement, themeFromPrefs(store, weaselTheme), themePrefsSelection(store));
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The schema holds an `enum` per axis under `axis` (`axis.mode`,
|
|
112
|
+
`axis.density`) and a page per token group, each token at `<group>.<token>`
|
|
113
|
+
with no `--wzl-`: a `color`, a `number` in the token's unit, or a `string` of
|
|
114
|
+
CSS text for a value neither holds, such as a font stack or a `var()`. Override
|
|
115
|
+
hooks are leaves too. Every leaf may be split by every axis, and its default
|
|
116
|
+
is what the theme resolves to, already split along the axes the token differs
|
|
117
|
+
by, so a store nothing was written to reads the theme as it is.
|
|
118
|
+
|
|
119
|
+
`themePrefsPins(store)` is the `pins` those values amount to. Only a leaf with
|
|
120
|
+
a value of its own is a pin, so a token left alone keeps its rule: pin
|
|
121
|
+
`accent-base` and `--wzl-accent` still follows it. A store reads such an alias
|
|
122
|
+
from the base theme, where it has not moved; `themePrefsValues(store, base)`
|
|
123
|
+
gives the values and loci for a form with each unset leaf read from the pinned
|
|
124
|
+
theme.
|
|
125
|
+
|
|
79
126
|
## Desktop themes
|
|
80
127
|
|
|
81
128
|
Each is a pins-only theme over the built-in one, on its own entry so an app
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { pick, mergeAxes, fullSelection } from './chunk-P5F3GZV6.js';
|
|
2
|
+
import { parseHexBytes } from '@weasel-js/paint';
|
|
3
|
+
|
|
4
|
+
// src/dtcg/value.ts
|
|
5
|
+
function fontStack(value) {
|
|
6
|
+
return value.map((f) => typeof f === "string" && /\s/.test(f) ? `'${f}'` : String(f)).join(", ");
|
|
7
|
+
}
|
|
8
|
+
function serializeTokenValue(type, value) {
|
|
9
|
+
if (Array.isArray(value)) {
|
|
10
|
+
if (type === "cubicBezier") return `cubic-bezier(${value.join(", ")})`;
|
|
11
|
+
if (type === "fontFamily") return fontStack(value);
|
|
12
|
+
return value.join(", ");
|
|
13
|
+
}
|
|
14
|
+
return String(value);
|
|
15
|
+
}
|
|
16
|
+
var BEZIER = /^cubic-bezier\(\s*([^)]*)\)$/i;
|
|
17
|
+
function parseTokenValue(type, text) {
|
|
18
|
+
const raw = text.trim();
|
|
19
|
+
if (type === "cubicBezier") {
|
|
20
|
+
const inner = BEZIER.exec(raw)?.[1] ?? raw;
|
|
21
|
+
const parts = inner.split(",").map((p) => Number(p.trim()));
|
|
22
|
+
return parts.length === 4 && parts.every((n) => Number.isFinite(n)) ? parts : raw;
|
|
23
|
+
}
|
|
24
|
+
if (type === "fontFamily") {
|
|
25
|
+
const families = raw.split(",").map((f) => f.trim().replace(/^['"]|['"]$/g, "").trim()).filter((f) => f !== "");
|
|
26
|
+
return families.length > 0 ? families : raw;
|
|
27
|
+
}
|
|
28
|
+
return raw;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/chainTokens.ts
|
|
32
|
+
function localSelections(chain, selection) {
|
|
33
|
+
let axes = {};
|
|
34
|
+
return chain.map((link) => {
|
|
35
|
+
axes = mergeAxes(axes, link.axes);
|
|
36
|
+
return { ...selection, ...fullSelection(axes, selection) };
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function tokenAt(chain, name, selection) {
|
|
40
|
+
const local = localSelections(chain, selection);
|
|
41
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
42
|
+
const { tokens } = chain[i];
|
|
43
|
+
if (!Object.hasOwn(tokens, name)) continue;
|
|
44
|
+
const picked = pick(tokens[name], local[i]);
|
|
45
|
+
if (picked.ok) return picked.value;
|
|
46
|
+
}
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
function tokensAt(chain, selection) {
|
|
50
|
+
const local = localSelections(chain, selection);
|
|
51
|
+
const out = {};
|
|
52
|
+
chain.forEach((link, i) => {
|
|
53
|
+
for (const [name, v] of Object.entries(link.tokens)) {
|
|
54
|
+
const picked = pick(v, local[i]);
|
|
55
|
+
if (picked.ok) out[name] = picked.value;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
function withAlpha(color, alpha) {
|
|
61
|
+
const rgba = parseRgba(color.trim());
|
|
62
|
+
if (!rgba) return mixAlpha(color.trim(), alpha);
|
|
63
|
+
const [r, g, b, a] = rgba;
|
|
64
|
+
return `rgba(${r}, ${g}, ${b}, ${round(a * alpha, 3)})`;
|
|
65
|
+
}
|
|
66
|
+
function mixAlpha(color, alpha) {
|
|
67
|
+
return `color-mix(in srgb, ${color} ${round(alpha * 100, 4)}%, transparent)`;
|
|
68
|
+
}
|
|
69
|
+
function atAlpha(color, alpha) {
|
|
70
|
+
const rgba = parseRgba(color.trim());
|
|
71
|
+
if (!rgba) return `rgb(from ${color.trim()} r g b / ${alpha})`;
|
|
72
|
+
const [r, g, b] = rgba;
|
|
73
|
+
return `rgba(${r}, ${g}, ${b}, ${round(alpha, 3)})`;
|
|
74
|
+
}
|
|
75
|
+
function round(n, places) {
|
|
76
|
+
return Number(n.toFixed(places));
|
|
77
|
+
}
|
|
78
|
+
function parseRgba(s) {
|
|
79
|
+
if (s.toLowerCase() === "transparent") return [0, 0, 0, 0];
|
|
80
|
+
return parseHex(s) ?? parseRgbFn(s);
|
|
81
|
+
}
|
|
82
|
+
function parseHex(s) {
|
|
83
|
+
const bytes = parseHexBytes(s);
|
|
84
|
+
return bytes && [bytes[0], bytes[1], bytes[2], bytes[3] / 255];
|
|
85
|
+
}
|
|
86
|
+
function parseRgbFn(s) {
|
|
87
|
+
const m = /^rgba?\(([^()]*)\)$/i.exec(s);
|
|
88
|
+
if (!m) return null;
|
|
89
|
+
const [channels, alphaPart, extra] = m[1].split("/");
|
|
90
|
+
if (extra !== void 0) return null;
|
|
91
|
+
const parts = channels.trim().split(/\s*,\s*|\s+/);
|
|
92
|
+
if (alphaPart !== void 0) parts.push(alphaPart.trim());
|
|
93
|
+
if (parts.length !== 3 && parts.length !== 4) return null;
|
|
94
|
+
const channel = (p) => p.endsWith("%") ? Number.parseFloat(p) / 100 * 255 : Number(p);
|
|
95
|
+
const alpha = (p) => p.endsWith("%") ? Number.parseFloat(p) / 100 : Number(p);
|
|
96
|
+
const [r, g, b] = parts.slice(0, 3).map(channel);
|
|
97
|
+
const a = parts[3] === void 0 ? 1 : alpha(parts[3]);
|
|
98
|
+
if (![r, g, b, a].every(Number.isFinite)) return null;
|
|
99
|
+
return [Math.round(r), Math.round(g), Math.round(b), a];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// src/dtcg/resolve.ts
|
|
103
|
+
var REF = /^\{([^}]+)\}$/;
|
|
104
|
+
function refTarget(value) {
|
|
105
|
+
if (typeof value !== "string") return null;
|
|
106
|
+
const m = REF.exec(value.trim());
|
|
107
|
+
if (!m) return null;
|
|
108
|
+
const path = m[1];
|
|
109
|
+
const dot = path.indexOf(".");
|
|
110
|
+
return dot === -1 ? path : path.slice(dot + 1);
|
|
111
|
+
}
|
|
112
|
+
function resolveTokens(tokens) {
|
|
113
|
+
const out = {};
|
|
114
|
+
const inProgress = /* @__PURE__ */ new Set();
|
|
115
|
+
const resolveOne = (name) => {
|
|
116
|
+
const cached = out[name];
|
|
117
|
+
if (cached !== void 0) return cached;
|
|
118
|
+
const token = tokens[name];
|
|
119
|
+
if (!token) throw new Error(`Unknown token "${name}"`);
|
|
120
|
+
if (inProgress.has(name)) {
|
|
121
|
+
throw new Error(`Reference cycle at token "${name}" (${[...inProgress].join(" \u2192 ")})`);
|
|
122
|
+
}
|
|
123
|
+
inProgress.add(name);
|
|
124
|
+
const target = refTarget(token.value);
|
|
125
|
+
let value;
|
|
126
|
+
if (target === null) {
|
|
127
|
+
value = serializeTokenValue(token.type, token.value);
|
|
128
|
+
} else if (!tokens[target]) {
|
|
129
|
+
throw new Error(`Token "${name}" references "${target}", which is not defined`);
|
|
130
|
+
} else {
|
|
131
|
+
value = resolveOne(target);
|
|
132
|
+
}
|
|
133
|
+
if (token.alpha !== void 0) value = withAlpha(value, token.alpha);
|
|
134
|
+
inProgress.delete(name);
|
|
135
|
+
out[name] = value;
|
|
136
|
+
return value;
|
|
137
|
+
};
|
|
138
|
+
for (const name of Object.keys(tokens)) resolveOne(name);
|
|
139
|
+
return out;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/resolveTheme.ts
|
|
143
|
+
function themeChain(theme) {
|
|
144
|
+
const out = [];
|
|
145
|
+
for (let t = theme; t; t = t.extends) out.unshift(t);
|
|
146
|
+
return out;
|
|
147
|
+
}
|
|
148
|
+
function themeAxes(theme) {
|
|
149
|
+
return themeChain(theme).reduce((axes, t) => mergeAxes(axes, t.axes), {});
|
|
150
|
+
}
|
|
151
|
+
function resolveTheme(theme, selection = {}) {
|
|
152
|
+
const sel = fullSelection(themeAxes(theme), selection);
|
|
153
|
+
const out = {};
|
|
154
|
+
for (const [name, value] of Object.entries(resolveTokens(tokensAt(themeChain(theme), sel)))) out[`--wzl-${name}`] = value;
|
|
155
|
+
return out;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export { atAlpha, mixAlpha, parseTokenValue, resolveTheme, resolveTokens, serializeTokenValue, themeAxes, themeChain, tokenAt, tokensAt, withAlpha };
|
|
159
|
+
//# sourceMappingURL=chunk-32JKTYS2.js.map
|
|
160
|
+
//# sourceMappingURL=chunk-32JKTYS2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/dtcg/value.ts","../src/chainTokens.ts","../src/dtcg/color.ts","../src/dtcg/resolve.ts","../src/resolveTheme.ts"],"names":[],"mappings":";;;;AAOA,SAAS,UAAU,KAAA,EAA6C;AAC9D,EAAA,OAAO,MAAM,GAAA,CAAI,CAAC,MAAO,OAAO,CAAA,KAAM,YAAY,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,GAAI,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAA,GAAM,MAAA,CAAO,CAAC,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AACnG;AAOO,SAAS,mBAAA,CAAoB,MAAc,KAAA,EAA2B;AAC3E,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,IAAI,SAAS,aAAA,EAAe,OAAO,gBAAgB,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA;AACnE,IAAA,IAAI,IAAA,KAAS,YAAA,EAAc,OAAO,SAAA,CAAU,KAAK,CAAA;AACjD,IAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EACxB;AACA,EAAA,OAAO,OAAO,KAAK,CAAA;AACrB;AAEA,IAAM,MAAA,GAAS,+BAAA;AAOR,SAAS,eAAA,CAAgB,MAAc,IAAA,EAA0B;AACtE,EAAA,MAAM,GAAA,GAAM,KAAK,IAAA,EAAK;AACtB,EAAA,IAAI,SAAS,aAAA,EAAe;AAC1B,IAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,GAAI,CAAC,CAAA,IAAK,GAAA;AACvC,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,MAAA,CAAO,CAAA,CAAE,IAAA,EAAM,CAAC,CAAA;AAC1D,IAAA,OAAO,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,KAAM,MAAA,CAAO,QAAA,CAAS,CAAC,CAAC,CAAA,GAAI,KAAA,GAAQ,GAAA;AAAA,EAChF;AACA,EAAA,IAAI,SAAS,YAAA,EAAc;AACzB,IAAA,MAAM,QAAA,GAAW,IACd,KAAA,CAAM,GAAG,EACT,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAK,CAAE,QAAQ,cAAA,EAAgB,EAAE,EAAE,IAAA,EAAM,EACtD,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,KAAM,EAAE,CAAA;AACzB,IAAA,OAAO,QAAA,CAAS,MAAA,GAAS,CAAA,GAAI,QAAA,GAAW,GAAA;AAAA,EAC1C;AACA,EAAA,OAAO,GAAA;AACT;;;AChCA,SAAS,eAAA,CAAgB,OAA6B,SAAA,EAAmC;AACvF,EAAA,IAAI,OAAiB,EAAC;AACtB,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS;AACzB,IAAA,IAAA,GAAO,SAAA,CAAU,IAAA,EAAM,IAAA,CAAK,IAAI,CAAA;AAChC,IAAA,OAAO,EAAE,GAAG,SAAA,EAAW,GAAG,aAAA,CAAc,IAAA,EAAM,SAAS,CAAA,EAAE;AAAA,EAC3D,CAAC,CAAA;AACH;AAGO,SAAS,OAAA,CAAQ,KAAA,EAA6B,IAAA,EAAc,SAAA,EAA4C;AAC7G,EAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,KAAA,EAAO,SAAS,CAAA;AAC9C,EAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,KAAA,CAAM,CAAC,CAAA;AAC1B,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,CAAO,MAAA,EAAQ,IAAI,CAAA,EAAG;AAClC,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,CAAA;AAC1C,IAAA,IAAI,MAAA,CAAO,EAAA,EAAI,OAAO,MAAA,CAAO,KAAA;AAAA,EAC/B;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,QAAA,CAAS,OAA6B,SAAA,EAAkC;AACtF,EAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,KAAA,EAAO,SAAS,CAAA;AAC9C,EAAA,MAAM,MAAgC,EAAC;AACvC,EAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,EAAM,CAAA,KAAM;AACzB,IAAA,KAAA,MAAW,CAAC,MAAM,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,EAAG;AACnD,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,CAAA;AAC/B,MAAA,IAAI,MAAA,CAAO,EAAA,EAAI,GAAA,CAAI,IAAI,IAAI,MAAA,CAAO,KAAA;AAAA,IACpC;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,GAAA;AACT;ACnCO,SAAS,SAAA,CAAU,OAAe,KAAA,EAAuB;AAC9D,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,KAAA,CAAM,IAAA,EAAM,CAAA;AACnC,EAAA,IAAI,CAAC,IAAA,EAAM,OAAO,SAAS,KAAA,CAAM,IAAA,IAAQ,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,IAAA;AACrB,EAAA,OAAO,CAAA,KAAA,EAAQ,CAAC,CAAA,EAAA,EAAK,CAAC,CAAA,EAAA,EAAK,CAAC,CAAA,EAAA,EAAK,KAAA,CAAM,CAAA,GAAI,KAAA,EAAO,CAAC,CAAC,CAAA,CAAA,CAAA;AACtD;AAGO,SAAS,QAAA,CAAS,OAAe,KAAA,EAAuB;AAC7D,EAAA,OAAO,sBAAsB,KAAK,CAAA,CAAA,EAAI,MAAM,KAAA,GAAQ,GAAA,EAAK,CAAC,CAAC,CAAA,eAAA,CAAA;AAC7D;AAGO,SAAS,OAAA,CAAQ,OAAe,KAAA,EAAuB;AAC5D,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,KAAA,CAAM,IAAA,EAAM,CAAA;AACnC,EAAA,IAAI,CAAC,MAAM,OAAO,CAAA,SAAA,EAAY,MAAM,IAAA,EAAM,YAAY,KAAK,CAAA,CAAA,CAAA;AAC3D,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,IAAA;AAClB,EAAA,OAAO,CAAA,KAAA,EAAQ,CAAC,CAAA,EAAA,EAAK,CAAC,CAAA,EAAA,EAAK,CAAC,CAAA,EAAA,EAAK,KAAA,CAAM,KAAA,EAAO,CAAC,CAAC,CAAA,CAAA,CAAA;AAClD;AAIA,SAAS,KAAA,CAAM,GAAW,MAAA,EAAwB;AAChD,EAAA,OAAO,MAAA,CAAO,CAAA,CAAE,OAAA,CAAQ,MAAM,CAAC,CAAA;AACjC;AAEA,SAAS,UAAU,CAAA,EAAwB;AACzC,EAAA,IAAI,CAAA,CAAE,aAAY,KAAM,aAAA,SAAsB,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AACzD,EAAA,OAAO,QAAA,CAAS,CAAC,CAAA,IAAK,UAAA,CAAW,CAAC,CAAA;AACpC;AAEA,SAAS,SAAS,CAAA,EAAwB;AACxC,EAAA,MAAM,KAAA,GAAQ,cAAc,CAAC,CAAA;AAC7B,EAAA,OAAO,KAAA,IAAS,CAAC,KAAA,CAAM,CAAC,GAAG,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,IAAI,GAAG,CAAA;AAC/D;AAEA,SAAS,WAAW,CAAA,EAAwB;AAC1C,EAAA,MAAM,CAAA,GAAI,sBAAA,CAAuB,IAAA,CAAK,CAAC,CAAA;AACvC,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,MAAM,CAAC,UAAU,SAAA,EAAW,KAAK,IAAI,CAAA,CAAE,CAAC,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA;AACnD,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,IAAA;AAChC,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,EAAK,CAAE,MAAM,aAAa,CAAA;AACjD,EAAA,IAAI,cAAc,MAAA,EAAW,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AACxD,EAAA,IAAI,MAAM,MAAA,KAAW,CAAA,IAAK,KAAA,CAAM,MAAA,KAAW,GAAG,OAAO,IAAA;AAErD,EAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAe,CAAA,CAAE,SAAS,GAAG,CAAA,GAAK,MAAA,CAAO,UAAA,CAAW,CAAC,CAAA,GAAI,GAAA,GAAO,GAAA,GAAM,OAAO,CAAC,CAAA;AAC/F,EAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAAe,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,GAAI,MAAA,CAAO,UAAA,CAAW,CAAC,CAAA,GAAI,GAAA,GAAM,OAAO,CAAC,CAAA;AACrF,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,GAAA,CAAI,OAAO,CAAA;AAC/C,EAAA,MAAM,CAAA,GAAI,MAAM,CAAC,CAAA,KAAM,SAAY,CAAA,GAAI,KAAA,CAAM,KAAA,CAAM,CAAC,CAAC,CAAA;AACrD,EAAA,IAAI,CAAC,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,CAAE,KAAA,CAAM,MAAA,CAAO,QAAQ,CAAA,EAAG,OAAO,IAAA;AACjD,EAAA,OAAO,CAAC,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,CAAC,GAAG,CAAC,CAAA;AACxD;;;ACzDA,IAAM,GAAA,GAAM,eAAA;AAEZ,SAAS,UAAU,KAAA,EAAkC;AACnD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,IAAA;AACtC,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAC/B,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,MAAM,IAAA,GAAO,EAAE,CAAC,CAAA;AAChB,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC5B,EAAA,OAAO,QAAQ,EAAA,GAAK,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,MAAM,CAAC,CAAA;AAC/C;AAQO,SAAS,cAAc,MAAA,EAAsC;AAClE,EAAA,MAAM,MAAwB,EAAC;AAC/B,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AAEnC,EAAA,MAAM,UAAA,GAAa,CAAC,IAAA,KAAyB;AAC3C,IAAA,MAAM,MAAA,GAAS,IAAI,IAAI,CAAA;AACvB,IAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AAEjC,IAAA,MAAM,KAAA,GAAQ,OAAO,IAAI,CAAA;AACzB,IAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,IAAI,CAAA,CAAA,CAAG,CAAA;AAErD,IAAA,IAAI,UAAA,CAAW,GAAA,CAAI,IAAI,CAAA,EAAG;AACxB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,IAAI,CAAA,GAAA,EAAM,CAAC,GAAG,UAAU,CAAA,CAAE,IAAA,CAAK,UAAK,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,IACvF;AACA,IAAA,UAAA,CAAW,IAAI,IAAI,CAAA;AAEnB,IAAA,MAAM,MAAA,GAAS,SAAA,CAAU,KAAA,CAAM,KAAK,CAAA;AACpC,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,WAAW,IAAA,EAAM;AACnB,MAAA,KAAA,GAAQ,mBAAA,CAAoB,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,KAAK,CAAA;AAAA,IACrD,CAAA,MAAA,IAAW,CAAC,MAAA,CAAO,MAAM,CAAA,EAAG;AAC1B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,OAAA,EAAU,IAAI,CAAA,cAAA,EAAiB,MAAM,CAAA,uBAAA,CAAyB,CAAA;AAAA,IAChF,CAAA,MAAO;AACL,MAAA,KAAA,GAAQ,WAAW,MAAM,CAAA;AAAA,IAC3B;AAEA,IAAA,IAAI,MAAM,KAAA,KAAU,MAAA,UAAmB,SAAA,CAAU,KAAA,EAAO,MAAM,KAAK,CAAA;AAEnE,IAAA,UAAA,CAAW,OAAO,IAAI,CAAA;AACtB,IAAA,GAAA,CAAI,IAAI,CAAA,GAAI,KAAA;AACZ,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AAEA,EAAA,KAAA,MAAW,QAAQ,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,aAAc,IAAI,CAAA;AACvD,EAAA,OAAO,GAAA;AACT;;;AC9CO,SAAS,WAAW,KAAA,EAAuB;AAChD,EAAA,MAAM,MAAe,EAAC;AACtB,EAAA,KAAA,IAAS,CAAA,GAAkB,OAAO,CAAA,EAAG,CAAA,GAAI,EAAE,OAAA,EAAS,GAAA,CAAI,QAAQ,CAAC,CAAA;AACjE,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,UAAU,KAAA,EAAwB;AAChD,EAAA,OAAO,UAAA,CAAW,KAAK,CAAA,CAAE,MAAA,CAAiB,CAAC,IAAA,EAAM,CAAA,KAAM,SAAA,CAAU,IAAA,EAAM,CAAA,CAAE,IAAI,CAAA,EAAG,EAAE,CAAA;AACpF;AAUO,SAAS,YAAA,CAAa,KAAA,EAAc,SAAA,GAAuB,EAAC,EAAkB;AACnF,EAAA,MAAM,GAAA,GAAM,aAAA,CAAc,SAAA,CAAU,KAAK,GAAG,SAAS,CAAA;AACrD,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,cAAc,QAAA,CAAS,UAAA,CAAW,KAAK,CAAA,EAAG,GAAG,CAAC,CAAC,CAAA,MAAO,CAAA,MAAA,EAAS,IAAI,EAAE,CAAA,GAAI,KAAA;AACpH,EAAA,OAAO,GAAA;AACT","file":"chunk-32JKTYS2.js","sourcesContent":["import type { TokenValue } from './types.ts';\n\n/**\n * Quote family names containing whitespace; leave everything else bare.\n * Generic keywords (`sans-serif`) and hyphen-prefixed identifiers\n * (`-apple-system`) break if quoted, and neither contains a space.\n */\nfunction fontStack(value: readonly (string | number)[]): string {\n return value.map((f) => (typeof f === 'string' && /\\s/.test(f) ? `'${f}'` : String(f))).join(', ');\n}\n\n/**\n * A token's value as CSS renders it. A DTCG value is not always a string: a\n * `fontFamily` is a list of names and a `cubicBezier` is four numbers, and both\n * have a spelling that belongs in a stylesheet rather than in JSON.\n */\nexport function serializeTokenValue(type: string, value: TokenValue): string {\n if (Array.isArray(value)) {\n if (type === 'cubicBezier') return `cubic-bezier(${value.join(', ')})`;\n if (type === 'fontFamily') return fontStack(value);\n return value.join(', ');\n }\n return String(value);\n}\n\nconst BEZIER = /^cubic-bezier\\(\\s*([^)]*)\\)$/i;\n\n/**\n * The inverse of {@link serializeTokenValue}: text a person edited, back in the\n * shape a definition stores. Text that does not parse for its type is kept as\n * text rather than thrown away, so a half-typed value stays editable.\n */\nexport function parseTokenValue(type: string, text: string): TokenValue {\n const raw = text.trim();\n if (type === 'cubicBezier') {\n const inner = BEZIER.exec(raw)?.[1] ?? raw;\n const parts = inner.split(',').map((p) => Number(p.trim()));\n return parts.length === 4 && parts.every((n) => Number.isFinite(n)) ? parts : raw;\n }\n if (type === 'fontFamily') {\n const families = raw\n .split(',')\n .map((f) => f.trim().replace(/^['\"]|['\"]$/g, '').trim())\n .filter((f) => f !== '');\n return families.length > 0 ? families : raw;\n }\n return raw;\n}\n","import { fullSelection, mergeAxes, pick, type AxisDefs, type Selection, type Varying } from './axes.ts';\nimport type { FlatTokens, RawToken } from './dtcg/types.ts';\n\n/** One theme of an `extends` chain, as far as choosing its tokens goes. */\nexport interface ChainLink {\n readonly axes: AxisDefs;\n readonly tokens: Readonly<Record<string, Varying<RawToken>>>;\n}\n\n/**\n * The selection each theme of a root-first chain reads its own tokens at. An axis value a theme and\n * everything it extends never declared (one a descendant added) becomes that theme's default for the\n * axis, which is what the stylesheet's cascade gives it: no block of the ancestor matches the new\n * value, so its default declarations show through.\n */\nfunction localSelections(chain: readonly ChainLink[], selection: Selection): Selection[] {\n let axes: AxisDefs = {};\n return chain.map((link) => {\n axes = mergeAxes(axes, link.axes);\n return { ...selection, ...fullSelection(axes, selection) };\n });\n}\n\n/** `name` from the nearest theme of a root-first chain that has it at `selection`. */\nexport function tokenAt(chain: readonly ChainLink[], name: string, selection: Selection): RawToken | undefined {\n const local = localSelections(chain, selection);\n for (let i = chain.length - 1; i >= 0; i--) {\n const { tokens } = chain[i];\n if (!Object.hasOwn(tokens, name)) continue;\n const picked = pick(tokens[name], local[i]);\n if (picked.ok) return picked.value;\n }\n return undefined;\n}\n\n/** Every token of a root-first chain at `selection`, each from the nearest theme that has it there. */\nexport function tokensAt(chain: readonly ChainLink[], selection: Selection): FlatTokens {\n const local = localSelections(chain, selection);\n const out: Record<string, RawToken> = {};\n chain.forEach((link, i) => {\n for (const [name, v] of Object.entries(link.tokens)) {\n const picked = pick(v, local[i]);\n if (picked.ok) out[name] = picked.value;\n }\n });\n return out;\n}\n","import { parseHexBytes } from '@weasel-js/paint';\n\n/**\n * A resolved color at `alpha`, multiplied into any alpha it already carries. The\n * JS side of the alpha extension; the CSS side emits `color-mix()` instead so DOM\n * chrome keeps tracking a downstream override of the referenced token.\n *\n * Hex and `rgb()`/`rgba()` become an `rgba()` literal. Anything else — a named\n * color, `hsl()`, `oklch()`, a `var()` — becomes the same `color-mix()` the CSS\n * side writes, which the browser resolves.\n */\nexport function withAlpha(color: string, alpha: number): string {\n const rgba = parseRgba(color.trim());\n if (!rgba) return mixAlpha(color.trim(), alpha);\n const [r, g, b, a] = rgba;\n return `rgba(${r}, ${g}, ${b}, ${round(a * alpha, 3)})`;\n}\n\n/** `color` at `alpha` as a `color-mix()` with transparent, for a color only the browser can resolve. */\nexport function mixAlpha(color: string, alpha: number): string {\n return `color-mix(in srgb, ${color} ${round(alpha * 100, 4)}%, transparent)`;\n}\n\n/** A resolved color with its alpha replaced by `alpha`, as `rgb(from c r g b / alpha)` computes it. */\nexport function atAlpha(color: string, alpha: number): string {\n const rgba = parseRgba(color.trim());\n if (!rgba) return `rgb(from ${color.trim()} r g b / ${alpha})`;\n const [r, g, b] = rgba;\n return `rgba(${r}, ${g}, ${b}, ${round(alpha, 3)})`;\n}\n\ntype Rgba = [number, number, number, number];\n\nfunction round(n: number, places: number): number {\n return Number(n.toFixed(places));\n}\n\nfunction parseRgba(s: string): Rgba | null {\n if (s.toLowerCase() === 'transparent') return [0, 0, 0, 0];\n return parseHex(s) ?? parseRgbFn(s);\n}\n\nfunction parseHex(s: string): Rgba | null {\n const bytes = parseHexBytes(s);\n return bytes && [bytes[0], bytes[1], bytes[2], bytes[3] / 255];\n}\n\nfunction parseRgbFn(s: string): Rgba | null {\n const m = /^rgba?\\(([^()]*)\\)$/i.exec(s);\n if (!m) return null;\n const [channels, alphaPart, extra] = m[1].split('/');\n if (extra !== undefined) return null;\n const parts = channels.trim().split(/\\s*,\\s*|\\s+/);\n if (alphaPart !== undefined) parts.push(alphaPart.trim());\n if (parts.length !== 3 && parts.length !== 4) return null;\n\n const channel = (p: string) => (p.endsWith('%') ? (Number.parseFloat(p) / 100) * 255 : Number(p));\n const alpha = (p: string) => (p.endsWith('%') ? Number.parseFloat(p) / 100 : Number(p));\n const [r, g, b] = parts.slice(0, 3).map(channel);\n const a = parts[3] === undefined ? 1 : alpha(parts[3]);\n if (![r, g, b, a].every(Number.isFinite)) return null;\n return [Math.round(r), Math.round(g), Math.round(b), a];\n}\n","import { withAlpha } from './color.ts';\nimport type { FlatTokens, ResolvedTokenMap, TokenValue } from './types.ts';\nimport { serializeTokenValue } from './value.ts';\n\n/** `{color.gray-100}` → `gray-100`. The type group is dropped, per the naming rule. */\nconst REF = /^\\{([^}]+)\\}$/;\n\nfunction refTarget(value: TokenValue): string | null {\n if (typeof value !== 'string') return null;\n const m = REF.exec(value.trim());\n if (!m) return null;\n const path = m[1];\n const dot = path.indexOf('.');\n return dot === -1 ? path : path.slice(dot + 1);\n}\n\n/**\n * Resolve flat tokens to final CSS-ready strings.\n *\n * Merge modes before calling: this function has no notion of modes, only of a\n * complete token set.\n */\nexport function resolveTokens(tokens: FlatTokens): ResolvedTokenMap {\n const out: ResolvedTokenMap = {};\n const inProgress = new Set<string>();\n\n const resolveOne = (name: string): string => {\n const cached = out[name];\n if (cached !== undefined) return cached;\n\n const token = tokens[name];\n if (!token) throw new Error(`Unknown token \"${name}\"`);\n\n if (inProgress.has(name)) {\n throw new Error(`Reference cycle at token \"${name}\" (${[...inProgress].join(' → ')})`);\n }\n inProgress.add(name);\n\n const target = refTarget(token.value);\n let value: string;\n if (target === null) {\n value = serializeTokenValue(token.type, token.value);\n } else if (!tokens[target]) {\n throw new Error(`Token \"${name}\" references \"${target}\", which is not defined`);\n } else {\n value = resolveOne(target);\n }\n\n if (token.alpha !== undefined) value = withAlpha(value, token.alpha);\n\n inProgress.delete(name);\n out[name] = value;\n return value;\n };\n\n for (const name of Object.keys(tokens)) resolveOne(name);\n return out;\n}\n\n/** Merge a mode's tokens over the mode-invariant set. Later wins. */\nexport function mergeTokens(base: FlatTokens, mode: FlatTokens): FlatTokens {\n return { ...base, ...mode };\n}\n","import { fullSelection, mergeAxes, type AxisDefs, type Selection } from './axes.ts';\nimport { tokensAt } from './chainTokens.ts';\nimport { resolveTokens } from './dtcg/resolve.ts';\nimport type { TokenName } from './generated/themes.ts';\nimport type { Theme } from './theme.ts';\n\n/** The output of `resolveTheme`: every token of a theme, for one selection, keyed\n * by CSS custom-property name and flattened to a final CSS value. */\nexport type ResolvedTheme = Readonly<Record<TokenName, string>>;\n\n/** Root-first, so the leaf theme's tokens land last. */\nexport function themeChain(theme: Theme): Theme[] {\n const out: Theme[] = [];\n for (let t: Theme | null = theme; t; t = t.extends) out.unshift(t);\n return out;\n}\n\n/** Every axis the chain declares. An axis declared more than once keeps every value; a descendant's value entries and default win. */\nexport function themeAxes(theme: Theme): AxisDefs {\n return themeChain(theme).reduce<AxisDefs>((axes, t) => mergeAxes(axes, t.axes), {});\n}\n\n/**\n * Merge the extends chain at a selection, resolve every alias, and key the\n * result by CSS custom-property name. A missing or unknown axis value takes the\n * axis default, and a theme in the chain reads a value it never declared at its\n * own default for that axis.\n *\n * Pure — no DOM. An unresolvable reference throws rather than falling back.\n */\nexport function resolveTheme(theme: Theme, selection: Selection = {}): ResolvedTheme {\n const sel = fullSelection(themeAxes(theme), selection);\n const out: Record<string, string> = {};\n for (const [name, value] of Object.entries(resolveTokens(tokensAt(themeChain(theme), sel)))) out[`--wzl-${name}`] = value;\n return out as ResolvedTheme;\n}\n"]}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// src/generated/manifest.ts
|
|
2
|
+
var TOKEN_MANIFEST = [
|
|
3
|
+
{ name: "--wzl-gray-50", type: "color", group: "gray", defaultValue: "#f5f5f6", description: "", hook: false },
|
|
4
|
+
{ name: "--wzl-gray-100", type: "color", group: "gray", defaultValue: "#e6e7e9", description: "", hook: false },
|
|
5
|
+
{ name: "--wzl-gray-200", type: "color", group: "gray", defaultValue: "#c9cbcf", description: "", hook: false },
|
|
6
|
+
{ name: "--wzl-gray-300", type: "color", group: "gray", defaultValue: "#9ea1a8", description: "", hook: false },
|
|
7
|
+
{ name: "--wzl-gray-400", type: "color", group: "gray", defaultValue: "#6f737b", description: "", hook: false },
|
|
8
|
+
{ name: "--wzl-gray-500", type: "color", group: "gray", defaultValue: "#4d5058", description: "", hook: false },
|
|
9
|
+
{ name: "--wzl-gray-600", type: "color", group: "gray", defaultValue: "#383b42", description: "", hook: false },
|
|
10
|
+
{ name: "--wzl-gray-700", type: "color", group: "gray", defaultValue: "#25272c", description: "", hook: false },
|
|
11
|
+
{ name: "--wzl-gray-800", type: "color", group: "gray", defaultValue: "#181a1e", description: "", hook: false },
|
|
12
|
+
{ name: "--wzl-gray-900", type: "color", group: "gray", defaultValue: "#0e0f12", description: "", hook: false },
|
|
13
|
+
{ name: "--wzl-accent-soft", type: "color", group: "accent", defaultValue: "#262a66", description: "", hook: false },
|
|
14
|
+
{ name: "--wzl-accent-base", type: "color", group: "accent", defaultValue: "#5b63c9", description: "Periwinkle. Anchors primary actions on dark surfaces.", hook: false },
|
|
15
|
+
{ name: "--wzl-accent-strong", type: "color", group: "accent", defaultValue: "#8c94ee", description: "", hook: false },
|
|
16
|
+
{ name: "--wzl-secondary-soft", type: "color", group: "secondary", defaultValue: "#704e09", description: "", hook: false },
|
|
17
|
+
{ name: "--wzl-secondary-base", type: "color", group: "secondary", defaultValue: "#dc9d15", description: "", hook: false },
|
|
18
|
+
{ name: "--wzl-secondary-strong", type: "color", group: "secondary", defaultValue: "#f1cb8d", description: "", hook: false },
|
|
19
|
+
{ name: "--wzl-swatch-fuchsia", type: "color", group: "swatch", defaultValue: "#f641f7", description: "First of ten categorical spot colors for plotting, status and data viz. Take them in sequence: the order is farthest-point over hue, so the first N are as separated as N colors can be (first three 87\xB0 apart, all ten 32\xB0). Mode-invariant on purpose \u2014 a series keeps its color when the mode flips, which is why they are tuned for a dark surface and clear only 1.5:1 on a light one.", hook: false },
|
|
20
|
+
{ name: "--wzl-swatch-green", type: "color", group: "swatch", defaultValue: "#48e628", description: "", hook: false },
|
|
21
|
+
{ name: "--wzl-swatch-sky", type: "color", group: "swatch", defaultValue: "#36bff2", description: "", hook: false },
|
|
22
|
+
{ name: "--wzl-swatch-amber", type: "color", group: "swatch", defaultValue: "#e69628", description: "", hook: false },
|
|
23
|
+
{ name: "--wzl-swatch-teal", type: "color", group: "swatch", defaultValue: "#3ee1cb", description: "", hook: false },
|
|
24
|
+
{ name: "--wzl-swatch-red", type: "color", group: "swatch", defaultValue: "#f75034", description: "", hook: false },
|
|
25
|
+
{ name: "--wzl-swatch-blue", type: "color", group: "swatch", defaultValue: "#407ef7", description: "", hook: false },
|
|
26
|
+
{ name: "--wzl-swatch-citron", type: "color", group: "swatch", defaultValue: "#d5d23a", description: "", hook: false },
|
|
27
|
+
{ name: "--wzl-swatch-rose", type: "color", group: "swatch", defaultValue: "#fa4590", description: "", hook: false },
|
|
28
|
+
{ name: "--wzl-swatch-violet", type: "color", group: "swatch", defaultValue: "#955cf9", description: "", hook: false },
|
|
29
|
+
{ name: "--wzl-font-size-2xs", type: "dimension", group: "font", defaultValue: "10px", description: "Shortcut keys and index badges. The floor for chrome text.", hook: false },
|
|
30
|
+
{ name: "--wzl-font-size-xs", type: "dimension", group: "font", defaultValue: "12px", description: "Tool-button labels under an icon.", hook: false },
|
|
31
|
+
{ name: "--wzl-font-size-sm", type: "dimension", group: "font", defaultValue: "13px", description: "Chrome labels, status readouts, section headings.", hook: false },
|
|
32
|
+
{ name: "--wzl-font-size-md", type: "dimension", group: "font", defaultValue: "15px", description: "Controls and body text.", hook: false },
|
|
33
|
+
{ name: "--wzl-font-size-lg", type: "dimension", group: "font", defaultValue: "18px", description: "Panel and dialog titles.", hook: false },
|
|
34
|
+
{ name: "--wzl-font-size-xl", type: "dimension", group: "font", defaultValue: "23px", description: "The largest chrome text \u2014 a lab or app title.", hook: false },
|
|
35
|
+
{ name: "--wzl-space-1", type: "dimension", group: "space", defaultValue: "2px", description: "", hook: false },
|
|
36
|
+
{ name: "--wzl-space-2", type: "dimension", group: "space", defaultValue: "4px", description: "", hook: false },
|
|
37
|
+
{ name: "--wzl-space-3", type: "dimension", group: "space", defaultValue: "6px", description: "", hook: false },
|
|
38
|
+
{ name: "--wzl-space-4", type: "dimension", group: "space", defaultValue: "8px", description: "", hook: false },
|
|
39
|
+
{ name: "--wzl-space-5", type: "dimension", group: "space", defaultValue: "10px", description: "", hook: false },
|
|
40
|
+
{ name: "--wzl-space-6", type: "dimension", group: "space", defaultValue: "12px", description: "", hook: false },
|
|
41
|
+
{ name: "--wzl-space-7", type: "dimension", group: "space", defaultValue: "14px", description: "", hook: false },
|
|
42
|
+
{ name: "--wzl-space-8", type: "dimension", group: "space", defaultValue: "16px", description: "", hook: false },
|
|
43
|
+
{ name: "--wzl-surface", type: "color", group: "surface", defaultValue: "#181a1e", description: "", hook: false },
|
|
44
|
+
{ name: "--wzl-surface-raised", type: "color", group: "surface", defaultValue: "#25272c", description: "", hook: false },
|
|
45
|
+
{ name: "--wzl-surface-popover", type: "color", group: "surface", defaultValue: "#25272c", description: "Background of a dropdown, menu or other popover list. Follows surface-raised unless a theme needs floating lists to read differently from the panels beneath them.", hook: false },
|
|
46
|
+
{ name: "--wzl-surface-sunken", type: "color", group: "surface", defaultValue: "#0e0f12", description: "", hook: false },
|
|
47
|
+
{ name: "--wzl-fg", type: "color", group: "fg", defaultValue: "#e6e7e9", description: "", hook: false },
|
|
48
|
+
{ name: "--wzl-fg-muted", type: "color", group: "fg", defaultValue: "rgb(from currentColor r g b / 0.7)", description: "Secondary text: the text color in effect where it is used, at reduced alpha, so it steps down from whatever text it sits beside on any surface. The alpha is absolute, so muted text nested in muted text stays one step down. Under fg it clears WCAG 4.5:1 on surface, surface-raised, and surface-sunken in both modes.", hook: false },
|
|
49
|
+
{ name: "--wzl-fg-subtle", type: "color", group: "fg", defaultValue: "rgb(from currentColor r g b / 0.54)", description: "Tertiary text: a further step down from the text color in effect, by the same rule as fg-muted. Under fg it clears WCAG 4.5:1 on surface, surface-raised, and surface-sunken in both modes.", hook: false },
|
|
50
|
+
{ name: "--wzl-fg-muted-on-accent", type: "color", group: "fg", defaultValue: "rgb(from currentColor r g b / 0.98)", description: "Secondary text on an accent fill. Every rule that sets --wzl-fg-on-accent text redirects --wzl-fg-muted here (npm run check:on-accent), because the general step falls below WCAG 4.5:1 on the accent. In dark mode that leaves almost no step to show.", hook: false },
|
|
51
|
+
{ name: "--wzl-fg-subtle-on-accent", type: "color", group: "fg", defaultValue: "rgb(from currentColor r g b / 0.96)", description: "Tertiary text on an accent fill, redirected from --wzl-fg-subtle by the same rule as fg-muted-on-accent. Clears WCAG 4.5:1 on the accent in both modes.", hook: false },
|
|
52
|
+
{ name: "--wzl-border", type: "color", group: "border", defaultValue: "#25272c", description: "", hook: false },
|
|
53
|
+
{ name: "--wzl-border-strong", type: "color", group: "border", defaultValue: "#6f737b", description: "The line that has to be seen: a control's edge, a raised surface's outline. Clears WCAG 1.4.11's 3:1 against every surface in both modes.", hook: false },
|
|
54
|
+
{ name: "--wzl-accent-fg", type: "color", group: "accent", defaultValue: "#8c94ee", description: "Accent for foreground use \u2014 text, icons, selected labels drawn on a surface. accent is a fill; the midnight base is too dim to read as text on dark surfaces.", hook: false },
|
|
55
|
+
{ name: "--wzl-secondary-fg", type: "color", group: "secondary", defaultValue: "#dc9d15", description: "Secondary accent for foreground use: a second voice beside the accent, such as a value the panel derived rather than one the user set. Picked from the ramp so it clears 4.5:1 on the surface in both modes.", hook: false },
|
|
56
|
+
{ name: "--wzl-fg-inverse", type: "color", group: "fg", defaultValue: "#0e0f12", description: "Text drawn on a filled foreground-colored element (e.g. a slider thumb). Flips with the mode, so it is a semantic, not an alias to a primitive.", hook: false },
|
|
57
|
+
{ name: "--wzl-shadow", type: "color", group: "shadow", defaultValue: "rgba(0, 0, 0, 0.6)", description: "Elevation. Always darker than any surface \u2014 never derived from fg, which is near-white on dark.", hook: false },
|
|
58
|
+
{ name: "--wzl-scrim", type: "color", group: "scrim", defaultValue: "rgba(0, 0, 0, 0.4)", description: "What a modal dims the page behind it with.", hook: false },
|
|
59
|
+
{ name: "--wzl-code-keyword", type: "color", group: "code", defaultValue: "#955cf9", description: "Keywords in highlighted code.", hook: false },
|
|
60
|
+
{ name: "--wzl-code-string", type: "color", group: "code", defaultValue: "#48e628", description: "String literals in highlighted code.", hook: false },
|
|
61
|
+
{ name: "--wzl-code-number", type: "color", group: "code", defaultValue: "#e69628", description: "Numbers in highlighted code.", hook: false },
|
|
62
|
+
{ name: "--wzl-code-constant", type: "color", group: "code", defaultValue: "#3ee1cb", description: "true, false, null and undefined in highlighted code.", hook: false },
|
|
63
|
+
{ name: "--wzl-code-property", type: "color", group: "code", defaultValue: "#36bff2", description: "Property keys and attribute names in highlighted code.", hook: false },
|
|
64
|
+
{ name: "--wzl-code-name", type: "color", group: "code", defaultValue: "#fa4590", description: "Functions, classes and other names in highlighted code.", hook: false },
|
|
65
|
+
{ name: "--wzl-panel-surface", type: "color", group: "panel", defaultValue: "#25272c", description: "Fill of a PropertyPanel.", hook: false },
|
|
66
|
+
{ name: "--wzl-panel-border-color", type: "color", group: "panel", defaultValue: "#25272c", description: "", hook: false },
|
|
67
|
+
{ name: "--wzl-panel-border-style", type: "string", group: "panel", defaultValue: "solid", description: "", hook: false },
|
|
68
|
+
{ name: "--wzl-panel-border-width", type: "dimension", group: "panel", defaultValue: "1px", description: "", hook: false },
|
|
69
|
+
{ name: "--wzl-panel-radius", type: "dimension", group: "panel", defaultValue: "14px", description: "", hook: false },
|
|
70
|
+
{ name: "--wzl-panel-pad", type: "dimension", group: "panel", defaultValue: "14px 16px", description: "A panel\u2019s padding when no density sets one.", hook: false },
|
|
71
|
+
{ name: "--wzl-panel-blur", type: "dimension", group: "panel", defaultValue: "3px", description: "", hook: false },
|
|
72
|
+
{ name: "--wzl-panel-tone-mix", type: "number", group: "panel", defaultValue: "14%", description: "How much of a panel\u2019s tone mixes into its surface.", hook: false },
|
|
73
|
+
{ name: "--wzl-panel-title-font", type: "fontFamily", group: "panel", defaultValue: "Oswald, 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif", description: "", hook: false },
|
|
74
|
+
{ name: "--wzl-panel-title-weight", type: "fontWeight", group: "panel", defaultValue: "200", description: "", hook: false },
|
|
75
|
+
{ name: "--wzl-panel-title-size", type: "dimension", group: "panel", defaultValue: "18px", description: "", hook: false },
|
|
76
|
+
{ name: "--wzl-panel-title-case", type: "string", group: "panel", defaultValue: "none", description: "", hook: false },
|
|
77
|
+
{ name: "--wzl-panel-title-tracking", type: "dimension", group: "panel", defaultValue: "0.01em", description: "", hook: false },
|
|
78
|
+
{ name: "--wzl-panel-title-color", type: "color", group: "panel", defaultValue: "#e6e7e9", description: "", hook: false },
|
|
79
|
+
{ name: "--wzl-panel-title-inset", type: "dimension", group: "panel", defaultValue: "0", description: "", hook: false },
|
|
80
|
+
{ name: "--wzl-stance-scope-border-width", type: "dimension", group: "stance", defaultValue: "0", description: "", hook: false },
|
|
81
|
+
{ name: "--wzl-stance-scope-radius", type: "dimension", group: "stance", defaultValue: "8px", description: "", hook: false },
|
|
82
|
+
{ name: "--wzl-stance-scope-tone-mix", type: "number", group: "stance", defaultValue: "22%", description: "", hook: false },
|
|
83
|
+
{ name: "--wzl-stance-scope-nested-radius", type: "dimension", group: "stance", defaultValue: "6px", description: "", hook: false },
|
|
84
|
+
{ name: "--wzl-stance-scope-nested-surface", type: "color", group: "stance", defaultValue: "#181a1e", description: "A scope panel inside another sits back into it.", hook: false },
|
|
85
|
+
{ name: "--wzl-stance-aside-surface", type: "color", group: "stance", defaultValue: "transparent", description: "", hook: false },
|
|
86
|
+
{ name: "--wzl-stance-aside-border-color", type: "color", group: "stance", defaultValue: "rgba(230, 231, 233, 0.1)", description: "", hook: false },
|
|
87
|
+
{ name: "--wzl-stance-aside-blur", type: "dimension", group: "stance", defaultValue: "0px", description: "", hook: false },
|
|
88
|
+
{ name: "--wzl-stance-aside-title-color", type: "color", group: "stance", defaultValue: "rgb(from currentColor r g b / 0.54)", description: "", hook: false },
|
|
89
|
+
{ name: "--wzl-stance-advanced-title-color", type: "color", group: "stance", defaultValue: "rgb(from currentColor r g b / 0.54)", description: "", hook: false },
|
|
90
|
+
{ name: "--wzl-stance-debug-border-style", type: "string", group: "stance", defaultValue: "dashed", description: "", hook: false },
|
|
91
|
+
{ name: "--wzl-stance-debug-title-font", type: "fontFamily", group: "stance", defaultValue: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace", description: "", hook: false },
|
|
92
|
+
{ name: "--wzl-stance-debug-title-case", type: "string", group: "stance", defaultValue: "none", description: "", hook: false },
|
|
93
|
+
{ name: "--wzl-stance-danger-tone", type: "color", group: "stance", defaultValue: "#d94a3f", description: "", hook: false },
|
|
94
|
+
{ name: "--wzl-stance-danger-border-color", type: "color", group: "stance", defaultValue: "#d94a3f", description: "", hook: false },
|
|
95
|
+
{ name: "--wzl-stance-danger-title-color", type: "color", group: "stance", defaultValue: "#d94a3f", description: "", hook: false },
|
|
96
|
+
{ name: "--wzl-stance-notice-tone", type: "color", group: "stance", defaultValue: "#5b63c9", description: "", hook: false },
|
|
97
|
+
{ name: "--wzl-stance-notice-tone-mix", type: "number", group: "stance", defaultValue: "8%", description: "", hook: false },
|
|
98
|
+
{ name: "--wzl-stance-important-border-color", type: "color", group: "stance", defaultValue: "#8c94ee", description: "", hook: false },
|
|
99
|
+
{ name: "--wzl-stance-important-title-color", type: "color", group: "stance", defaultValue: "#8c94ee", description: "", hook: false },
|
|
100
|
+
{ name: "--wzl-stance-preview-pad", type: "dimension", group: "stance", defaultValue: "0", description: "", hook: false },
|
|
101
|
+
{ name: "--wzl-stance-preview-title-size", type: "dimension", group: "stance", defaultValue: "12px", description: "", hook: false },
|
|
102
|
+
{ name: "--wzl-stance-preview-title-case", type: "string", group: "stance", defaultValue: "none", description: "", hook: false },
|
|
103
|
+
{ name: "--wzl-stance-preview-title-inset", type: "dimension", group: "stance", defaultValue: "6px 10px 0", description: "", hook: false },
|
|
104
|
+
{ name: "--wzl-danger-base", type: "color", group: "status", defaultValue: "#d94a3f", description: "", hook: false },
|
|
105
|
+
{ name: "--wzl-warning-base", type: "color", group: "status", defaultValue: "#d99a3f", description: "", hook: false },
|
|
106
|
+
{ name: "--wzl-success-base", type: "color", group: "status", defaultValue: "#2ec27e", description: "", hook: false },
|
|
107
|
+
{ name: "--wzl-fg-on-accent", type: "color", group: "fg", defaultValue: "#f5f5f6", description: "", hook: false },
|
|
108
|
+
{ name: "--wzl-line-subtle", type: "color", group: "line", defaultValue: "rgba(230, 231, 233, 0.1)", description: "Barely-there separators (table rows).", hook: false },
|
|
109
|
+
{ name: "--wzl-line", type: "color", group: "line", defaultValue: "rgba(230, 231, 233, 0.2)", description: "Primary gridlines on sunken surfaces.", hook: false },
|
|
110
|
+
{ name: "--wzl-line-strong", type: "color", group: "line", defaultValue: "rgba(230, 231, 233, 0.4)", description: "Axes and emphasized dividers.", hook: false },
|
|
111
|
+
{ name: "--wzl-border-on-sunken", type: "color", group: "border", defaultValue: "rgba(230, 231, 233, 0.12)", description: "The edge of a box filled with surface-sunken. Stepped from the text color, because light mode's border is the sunken fill's own gray.", hook: false },
|
|
112
|
+
{ name: "--wzl-curve-color", type: "color", group: "curve", defaultValue: "#8c94ee", description: "Drawn data curves. Routes through the bright accent because accent-base is too dim on sunken surfaces.", hook: false },
|
|
113
|
+
{ name: "--wzl-accent", type: "color", group: "accent", defaultValue: "#5b63c9", description: "", hook: false },
|
|
114
|
+
{ name: "--wzl-accent-hover", type: "color", group: "accent", defaultValue: "#8c94ee", description: "", hook: false },
|
|
115
|
+
{ name: "--wzl-secondary", type: "color", group: "secondary", defaultValue: "#dc9d15", description: "Honey amber in dark mode and teal in light, where a darkened amber reads as brown. A fill; use secondary-fg for text.", hook: false },
|
|
116
|
+
{ name: "--wzl-danger", type: "color", group: "status", defaultValue: "#d94a3f", description: "", hook: false },
|
|
117
|
+
{ name: "--wzl-warning", type: "color", group: "status", defaultValue: "#d99a3f", description: "", hook: false },
|
|
118
|
+
{ name: "--wzl-success", type: "color", group: "status", defaultValue: "#2ec27e", description: "", hook: false },
|
|
119
|
+
{ name: "--wzl-focus-ring", type: "color", group: "focus", defaultValue: "#8c94ee", description: "", hook: false },
|
|
120
|
+
{ name: "--wzl-glass-tint", type: "color", group: "glass", defaultValue: "#5b63c9", description: "Frosted-glass tint. Components compose it as color-mix(in srgb, var(--wzl-glass-tint) 78%, transparent) with backdrop-filter: blur(3px).", hook: false },
|
|
121
|
+
{ name: "--wzl-surface-hover", type: "color", group: "surface", defaultValue: "rgba(230, 231, 233, 0.1)", description: "Hover wash over a raised surface. Same formula as line-subtle, different job \u2014 do not collapse them.", hook: false },
|
|
122
|
+
{ name: "--wzl-surface-pressed", type: "color", group: "surface", defaultValue: "rgba(230, 231, 233, 0.18)", description: "Pressed wash over a raised surface.", hook: false },
|
|
123
|
+
{ name: "--wzl-radius-sm", type: "dimension", group: "radius", defaultValue: "3px", description: "", hook: false },
|
|
124
|
+
{ name: "--wzl-radius-md", type: "dimension", group: "radius", defaultValue: "5px", description: "", hook: false },
|
|
125
|
+
{ name: "--wzl-radius-lg", type: "dimension", group: "radius", defaultValue: "14px", description: "", hook: false },
|
|
126
|
+
{ name: "--wzl-radius-pill", type: "dimension", group: "radius", defaultValue: "999px", description: "Fully rounded ends \u2014 segmented controls, progress tracks.", hook: false },
|
|
127
|
+
{ name: "--wzl-border-w", type: "dimension", group: "border", defaultValue: "1px", description: "", hook: false },
|
|
128
|
+
{ name: "--wzl-line-width", type: "dimension", group: "line", defaultValue: "2px", description: "Structural lines \u2014 gridlines, dividers, axes.", hook: false },
|
|
129
|
+
{ name: "--wzl-curve-width", type: "dimension", group: "curve", defaultValue: "3px", description: "Drawn data curves. Heavier than structural lines so data reads as primary content.", hook: false },
|
|
130
|
+
{ name: "--wzl-tb-height", type: "dimension", group: "tb", defaultValue: "32px", description: "Height of a horizontal toolbar strip (ButtonBar, OptionsBar, ToolOptionsBar). Taller than control-h so the controls inside a strip are not flush with its edges.", hook: false },
|
|
131
|
+
{ name: "--wzl-control-h-xs", type: "dimension", group: "control", defaultValue: "22px", description: "Height of the smallest interactive control -- a stepper, a keycap, a swatch button in a dense row. The rank below control-h-sm.", hook: false },
|
|
132
|
+
{ name: "--wzl-control-h-sm", type: "dimension", group: "control", defaultValue: "24px", description: "Height of a control in a dense inspector -- a Properties field, a small Button. The rank below control-h, which sizes a standalone control.", hook: false },
|
|
133
|
+
{ name: "--wzl-control-h", type: "dimension", group: "control", defaultValue: "28px", description: "Height of an interactive control \u2014 button, input, select, segmented control. Distinct from tb-height, which sizes the strip a row of them sits in.", hook: false },
|
|
134
|
+
{ name: "--wzl-icon-button-size", type: "dimension", group: "icon", defaultValue: "26px", description: "Side of a square icon button -- a dialog close, a row remove, a field clear. Smaller than control-h because it carries a glyph rather than a label, and square, so it sizes both axes.", hook: false },
|
|
135
|
+
{ name: "--wzl-slider-track-h", type: "dimension", group: "slider", defaultValue: "4px", description: "Height of a linear range track. The kit's single-thumb ranges all wear this; Slider's default 24px canvas track does not.", hook: false },
|
|
136
|
+
{ name: "--wzl-slider-thumb-size", type: "dimension", group: "slider", defaultValue: "8px", description: "Diameter of a linear range thumb.", hook: false },
|
|
137
|
+
{ name: "--wzl-slider-track-slop", type: "dimension", group: "slider", defaultValue: "6px", description: "How far past a range track's edge a press still lands on it. Invisible, and overlaps whatever sits beside the track rather than taking layout space.", hook: false },
|
|
138
|
+
{ name: "--wzl-slider-thumb-slop", type: "dimension", group: "slider", defaultValue: "6px", description: "How far past a range thumb's edge a press still grabs the thumb rather than landing on the track. Sits over the track's own slop.", hook: false },
|
|
139
|
+
{ name: "--wzl-slider-track-mix", type: "dimension", group: "slider", defaultValue: "40%", description: "Proportion of accent-fg in a range track, as a color-mix percentage \u2014 not a color. Mixed into a real property, never into another custom property. Higher in dark mode, where a light tint of the accent sinks into the surface.", hook: false },
|
|
140
|
+
{ name: "--wzl-slider-thumb-mix", type: "dimension", group: "slider", defaultValue: "100%", description: "Proportion of accent-fg in a range thumb, as a color-mix percentage \u2014 not a color. Solid in dark mode.", hook: false },
|
|
141
|
+
{ name: "--wzl-handle-size", type: "dimension", group: "handle", defaultValue: "9px", description: "Edge of a draggable handle on a plot or timeline \u2014 a keyframe diamond, a timeline key, an event mark. The default rank; -sm and -lg are the two deliberate departures from it.", hook: false },
|
|
142
|
+
{ name: "--wzl-handle-size-sm", type: "dimension", group: "handle", defaultValue: "7px", description: "A handle that is drawn but not draggable \u2014 a locked or pinned point. Smaller so it reads as inert next to a live one.", hook: false },
|
|
143
|
+
{ name: "--wzl-handle-size-lg", type: "dimension", group: "handle", defaultValue: "10px", description: "A handle that is a category of its own rather than one of a row \u2014 a curve's endpoint. Larger so it separates from the handles it sits in line with.", hook: false },
|
|
144
|
+
{ name: "--wzl-handle-dot-size", type: "dimension", group: "handle", defaultValue: "8px", description: "Diameter of a round handle \u2014 a plain anchor on a curve. Its own rank beside handle-size, because a circle and a diamond of one edge do not read as one size.", hook: false },
|
|
145
|
+
{ name: "--wzl-handle-dot-size-sm", type: "dimension", group: "handle", defaultValue: "7px", description: "A round handle that belongs to another point \u2014 a bezier control handle at the end of its stem.", hook: false },
|
|
146
|
+
{ name: "--wzl-checker-a", type: "color", group: "checker", defaultValue: "#25272c", description: "One square of the transparency checker drawn under a paint that is empty, mixed or translucent. Paint it as repeating-conic-gradient(var(--wzl-checker-a) 0% 25%, var(--wzl-checker-b) 0% 50%) 50% / var(--wzl-checker-size) var(--wzl-checker-size).", hook: false },
|
|
147
|
+
{ name: "--wzl-checker-b", type: "color", group: "checker", defaultValue: "#181a1e", description: "The other square of the transparency checker.", hook: false },
|
|
148
|
+
{ name: "--wzl-checker-size", type: "dimension", group: "checker", defaultValue: "8px", description: "Edge of one repeat of the transparency checker: two squares by two.", hook: false },
|
|
149
|
+
{ name: "--wzl-workspace-surface", type: "color", group: "workspace", defaultValue: "#0e0f12", description: "Ground of a canvas app's workspace \u2014 the area around the document page.", hook: false },
|
|
150
|
+
{ name: "--wzl-workspace-line", type: "color", group: "workspace", defaultValue: "rgba(230, 231, 233, 0.1)", description: "Marks drawn over workspace-surface, such as its diagonal stripes, so the page reads as the thing on top.", hook: false },
|
|
151
|
+
{ name: "--wzl-field-pad-x", type: "dimension", group: "field", defaultValue: "8px", description: "Horizontal padding inside a boxed field. Pairs with --wzl-field-h, which is a container override and has no :root default.", hook: false },
|
|
152
|
+
{ name: "--wzl-gloss", type: "number", group: "gloss", defaultValue: "0", description: "How much glass a boxed button and a selected segment wear, from 0 to 1: at 0 a flat fill, at 1 the full ramp, specular gloss, rim, and drop shadow.", hook: false },
|
|
153
|
+
{ name: "--wzl-glass-blur", type: "dimension", group: "glass", defaultValue: "3px", description: "Backdrop blur radius for frosted surfaces. Pairs with glass-tint.", hook: false },
|
|
154
|
+
{ name: "--wzl-font-size", type: "dimension", group: "font", defaultValue: "15px", description: "Controls and body text.", hook: false },
|
|
155
|
+
{ name: "--wzl-tracking-none", type: "dimension", group: "tracking", defaultValue: "0", description: "", hook: false },
|
|
156
|
+
{ name: "--wzl-tracking-wide", type: "dimension", group: "tracking", defaultValue: "0.06em", description: "Uppercase section headings.", hook: false },
|
|
157
|
+
{ name: "--wzl-tracking-wider", type: "dimension", group: "tracking", defaultValue: "0.08em", description: "Uppercase at 11px and below.", hook: false },
|
|
158
|
+
{ name: "--wzl-z-toolbar", type: "number", group: "z", defaultValue: "10", description: "Chrome pinned over a workspace.", hook: false },
|
|
159
|
+
{ name: "--wzl-z-overlay", type: "number", group: "z", defaultValue: "20", description: "A panel or readout floating over the chrome.", hook: false },
|
|
160
|
+
{ name: "--wzl-z-hud", type: "number", group: "z", defaultValue: "900", description: "Debug readouts, over the app and under anything modal.", hook: false },
|
|
161
|
+
{ name: "--wzl-z-modal", type: "number", group: "z", defaultValue: "1000", description: "A dialog or lightbox and its scrim.", hook: false },
|
|
162
|
+
{ name: "--wzl-z-toast", type: "number", group: "z", defaultValue: "1100", description: "Toasts, which stay readable over a dialog.", hook: false },
|
|
163
|
+
{ name: "--wzl-z-popover", type: "number", group: "z", defaultValue: "1200", description: "Tooltips and callouts, which a dialog or a toast can open.", hook: false },
|
|
164
|
+
{ name: "--wzl-z-drag", type: "number", group: "z", defaultValue: "10000", description: "A drag ghost, over everything it can be dragged across.", hook: false },
|
|
165
|
+
{ name: "--wzl-leading-tight", type: "number", group: "leading", defaultValue: "1", description: "Single-line controls; the box sets the height.", hook: false },
|
|
166
|
+
{ name: "--wzl-leading-snug", type: "number", group: "leading", defaultValue: "1.2", description: "Headings and two-line labels.", hook: false },
|
|
167
|
+
{ name: "--wzl-leading", type: "number", group: "leading", defaultValue: "1.4", description: "Body and anything that wraps.", hook: false },
|
|
168
|
+
{ name: "--wzl-backdrop", type: "gradient", group: "backdrop", defaultValue: "none", description: "Layered backdrop fill for a page or lab root. `none` here; a theme with a signature background sets it.", hook: false },
|
|
169
|
+
{ name: "--wzl-motion-fast", type: "duration", group: "motion", defaultValue: "120ms", description: "Micro-interactions \u2014 hover, focus, pressed.", hook: false },
|
|
170
|
+
{ name: "--wzl-motion-medium", type: "duration", group: "motion", defaultValue: "240ms", description: "Entrances and exits \u2014 toasts, popovers, panels.", hook: false },
|
|
171
|
+
{ name: "--wzl-ease-in-cubic", type: "cubicBezier", group: "ease", defaultValue: "cubic-bezier(0.32, 0, 0.67, 0)", description: "", hook: false },
|
|
172
|
+
{ name: "--wzl-ease-out-cubic", type: "cubicBezier", group: "ease", defaultValue: "cubic-bezier(0.33, 1, 0.68, 1)", description: "", hook: false },
|
|
173
|
+
{ name: "--wzl-ease-in-out-cubic", type: "cubicBezier", group: "ease", defaultValue: "cubic-bezier(0.65, 0, 0.35, 1)", description: "", hook: false },
|
|
174
|
+
{ name: "--wzl-ease-out-back", type: "cubicBezier", group: "ease", defaultValue: "cubic-bezier(0.34, 1.56, 0.64, 1)", description: "", hook: false },
|
|
175
|
+
{ name: "--wzl-font-ui", type: "fontFamily", group: "font", defaultValue: "Oswald, 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif", description: "Condensed UI/display face. The heavier cuts get blocky at any size, so the weight tokens stay in the 200-400 range.", hook: false },
|
|
176
|
+
{ name: "--wzl-font-numeric", type: "fontFamily", group: "font", defaultValue: "'Oswald Tabular', var(--wzl-font-ui)", description: "The UI face with equal-width digits, for numbers read down a column or updated in place. Oswald Tabular carries only 0-9 and the figure space (U+2007); every other character falls through to the UI face.", hook: false },
|
|
177
|
+
{ name: "--wzl-font-display", type: "fontFamily", group: "font", defaultValue: "Oswald, 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif", description: "", hook: false },
|
|
178
|
+
{ name: "--wzl-font-body", type: "fontFamily", group: "font", defaultValue: "Inter, system-ui, -apple-system, 'Segoe UI', sans-serif", description: "", hook: false },
|
|
179
|
+
{ name: "--wzl-font-mono", type: "fontFamily", group: "font", defaultValue: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace", description: "", hook: false },
|
|
180
|
+
{ name: "--wzl-font-weight-light", type: "fontWeight", group: "font", defaultValue: "200", description: "", hook: false },
|
|
181
|
+
{ name: "--wzl-font-weight-normal", type: "fontWeight", group: "font", defaultValue: "300", description: "", hook: false },
|
|
182
|
+
{ name: "--wzl-font-weight-medium", type: "fontWeight", group: "font", defaultValue: "350", description: "", hook: false },
|
|
183
|
+
{ name: "--wzl-font-weight-bold", type: "fontWeight", group: "font", defaultValue: "400", description: "", hook: false },
|
|
184
|
+
{ name: "--wzl-space-xs", type: "dimension", group: "space", defaultValue: "4px", description: "Alias for space-2. The t-shirt names name every other rung of the ladder.", hook: false },
|
|
185
|
+
{ name: "--wzl-space-sm", type: "dimension", group: "space", defaultValue: "8px", description: "Alias for space-4. The t-shirt names name every other rung of the ladder.", hook: false },
|
|
186
|
+
{ name: "--wzl-space-md", type: "dimension", group: "space", defaultValue: "12px", description: "Alias for space-6. The t-shirt names name every other rung of the ladder.", hook: false },
|
|
187
|
+
{ name: "--wzl-space-lg", type: "dimension", group: "space", defaultValue: "16px", description: "Alias for space-8. The t-shirt names name every other rung of the ladder.", hook: false },
|
|
188
|
+
{ name: "--wzl-bevel-pressed", type: "shadow", group: "bevel", defaultValue: "none", description: "Box shadow of a Button held down, or of a Button or a toolbar\u2019s button that stays down. Unset, a Button draws its own inset (--btn-relief-pressed) and a toolbar\u2019s button none.", hook: true },
|
|
189
|
+
{ name: "--wzl-bevel-raised", type: "shadow", group: "bevel", defaultValue: "none", description: "Box shadow of a raised face: a Button, a PropertyPanel, a menu, popover, tooltip, or Dialog, a thumb, the chosen segment of a segmented control, a toolbar\u2019s strip, and every edge of a tab but the one its panel is on. A theme that draws its edges in relief declares it; unset, each keeps the shadow it draws for itself, which for most is none.", hook: true },
|
|
190
|
+
{ name: "--wzl-bevel-sunken", type: "shadow", group: "bevel", defaultValue: "none", description: "Box shadow of a well: the frame a field draws its value in, a checkbox, a radio, the track of a switch, a slider, or a segmented control, and a cell of a flat one.", hook: true },
|
|
191
|
+
{ name: "--wzl-button-gloss", type: "number", group: "button", defaultValue: "1", description: "Opacity of the specular sheen over a Button\u2019s upper half. 0 for a flat face.", hook: true },
|
|
192
|
+
{ name: "--wzl-button-pressed-surface", type: "color", group: "button", defaultValue: "var(--btn-glass-pressed)", description: "Background of a secondary Button while it is held down.", hook: true },
|
|
193
|
+
{ name: "--wzl-button-primary-bevel", type: "shadow", group: "button", defaultValue: "var(--wzl-bevel-raised)", description: "Box shadow of a primary Button, where it differs from --wzl-bevel-raised: the heavier frame of a default button.", hook: true },
|
|
194
|
+
{ name: "--wzl-button-primary-fg", type: "color", group: "button", defaultValue: "var(--wzl-fg-on-accent)", description: "Text color of a primary Button, for a theme whose --wzl-button-primary-surface is not an accent fill.", hook: true },
|
|
195
|
+
{ name: "--wzl-button-primary-pressed-surface", type: "color", group: "button", defaultValue: "var(--btn-glass-pressed)", description: "Background of a primary Button while it is held down.", hook: true },
|
|
196
|
+
{ name: "--wzl-button-primary-surface", type: "color", group: "button", defaultValue: "var(--btn-glass)", description: "Background of a primary Button. Unset, glass tinted with --wzl-accent.", hook: true },
|
|
197
|
+
{ name: "--wzl-button-radius", type: "dimension", group: "button", defaultValue: "calc(var(--btn-height) * 0.1)", description: "Corner radius of a Button. Unset, a tenth of its height.", hook: true },
|
|
198
|
+
{ name: "--wzl-button-surface", type: "color", group: "button", defaultValue: "var(--btn-glass)", description: "Background of a secondary Button. Unset, neutral glass mixed from the surfaces.", hook: true },
|
|
199
|
+
{ name: "--wzl-button-text-shadow", type: "shadow", group: "button", defaultValue: "var(--btn-engraving)", description: "Text shadow of a primary or secondary Button\u2019s label. Unset, an engraving stamp under the glyphs in dark mode.", hook: true },
|
|
200
|
+
{ name: "--wzl-detail-figure-min-width", type: "dimension", group: "detail", defaultValue: "8ch", description: 'Least width of a value cell in a `values="figures"` DetailList.', hook: true },
|
|
201
|
+
{ name: "--wzl-dialog-max-width", type: "dimension", group: "dialog", defaultValue: "900px", description: "Widest a Dialog grows, modal or inline, before its contents wrap or scroll.", hook: true },
|
|
202
|
+
{ name: "--wzl-disclosure-fill", type: "color", group: "disclosure", defaultValue: "var(--wzl-accent-fg)", description: "Fill of a Disclosure\u2019s fold mark.", hook: true },
|
|
203
|
+
{ name: "--wzl-disclosure-gap", type: "dimension", group: "disclosure", defaultValue: "4px", description: "Gap between a Disclosure\u2019s twisty and its label.", hook: true },
|
|
204
|
+
{ name: "--wzl-disclosure-target", type: "dimension", group: "disclosure", defaultValue: "20px", description: "Hit-target square of a Disclosure twisty, and the twisty column of a LayerList row.", hook: true },
|
|
205
|
+
{ name: "--wzl-field-border", type: "border", group: "field", defaultValue: "1px solid var(--wzl-border)", description: "Border of a field\u2019s frame. A theme whose --wzl-bevel-sunken draws the edge sets it to a border of no width.", hook: true },
|
|
206
|
+
{ name: "--wzl-field-focus-shadow", type: "shadow", group: "field", defaultValue: "0 0 0 1px var(--wzl-focus-ring)", description: "Box shadow of a field\u2019s frame while it holds focus. It replaces --wzl-bevel-sunken there, so a beveled theme restates the bevel in it.", hook: true },
|
|
207
|
+
{ name: "--wzl-input-surface", type: "color", group: "input", defaultValue: "var(--wzl-surface-sunken)", description: "Surface a field\u2019s frame sits on \u2014 Input, NumberField, ComboBox, Select, MenuButton, ListEditor and the property rows. Set it on any container whose own background is the default \u2014 a sunken rail or panel \u2014 where an unset field is the same color as what is behind it.", hook: true },
|
|
208
|
+
{ name: "--wzl-number-field-width", type: "dimension", group: "number", defaultValue: "9ch", description: "Width of a NumberField\u2019s input.", hook: true },
|
|
209
|
+
{ name: "--wzl-params-label-align", type: "string", group: "params", defaultValue: "start", description: "Text alignment of row labels in PropertyPanel, Prefs and labkit\u2019s ControlPanel.", hook: true },
|
|
210
|
+
{ name: "--wzl-params-label-case", type: "string", group: "params", defaultValue: "uppercase", description: "text-transform of every label and title in PropertyPanel, Prefs and labkit\u2019s ControlPanel.", hook: true },
|
|
211
|
+
{ name: "--wzl-params-label-tracking", type: "dimension", group: "params", defaultValue: "var(--wzl-tracking-wide)", description: "Letter spacing of every label and title in PropertyPanel, Prefs and labkit\u2019s ControlPanel. Unset, rows take --wzl-tracking-wide and titles --wzl-tracking-wider.", hook: true },
|
|
212
|
+
{ name: "--wzl-params-label-width", type: "dimension", group: "params", defaultValue: "auto", description: "Inline size of row labels in PropertyPanel, Prefs and labkit\u2019s ControlPanel.", hook: true },
|
|
213
|
+
{ name: "--wzl-prefs-across-gap", type: "dimension", group: "prefs", defaultValue: "28px", description: "Gap between the two columns of rows a PrefsForm pane sets side by side.", hook: true },
|
|
214
|
+
{ name: "--wzl-prefs-column-width", type: "dimension", group: "prefs", defaultValue: "300px", description: "Width of the Prefs category column.", hook: true },
|
|
215
|
+
{ name: "--wzl-prefs-control-min", type: "dimension", group: "prefs", defaultValue: "80px", description: "Narrowest a PrefsForm row\u2019s control gets in a two-across pane before the row wraps it under its label.", hook: true },
|
|
216
|
+
{ name: "--wzl-prefs-rail-width", type: "dimension", group: "prefs", defaultValue: "216px", description: "Width of the Prefs navigation rail.", hook: true },
|
|
217
|
+
{ name: "--wzl-prop-columns", type: "string", group: "prop", defaultValue: "1fr 1fr", description: "Column tracks of a Properties list, group body, and subpanel. A container too narrow for two columns sets `minmax(0, 1fr)` to stack every row.", hook: true },
|
|
218
|
+
{ name: "--wzl-prop-number-width", type: "dimension", group: "prop", defaultValue: "9ch", description: "Width of a numeric field in the Properties panel.", hook: true },
|
|
219
|
+
{ name: "--wzl-prop-panel-actions-align", type: "string", group: "prop", defaultValue: "center", description: "How a PropertyPanel\u2019s title row lines its actions up with the title: center, or baseline for actions that are text.", hook: true },
|
|
220
|
+
{ name: "--wzl-prop-panel-actions-basis", type: "dimension", group: "prop", defaultValue: "auto", description: "Width a PropertyPanel\u2019s title row gives its actions. Set, it holds that width whatever the actions are.", hook: true },
|
|
221
|
+
{ name: "--wzl-prop-row-h", type: "dimension", group: "prop", defaultValue: "20px", description: "Floor under every Properties row, whatever control it holds. Unset, it is the panel\u2019s own field height, so it follows density \u2014 20px at the default one.", hook: true },
|
|
222
|
+
{ name: "--wzl-prop-text-width", type: "dimension", group: "prop", defaultValue: "16ch", description: "Width of a text field in the Properties panel.", hook: true },
|
|
223
|
+
{ name: "--wzl-property-readout-w", type: "dimension", group: "property", defaultValue: "calc(4.5ch + 2px)", description: "Width of a Properties row\u2019s value readout \u2014 four digits, so the controls beside a column of readouts end on one line. A range whose widest value needs more widens its own readout.", hook: true },
|
|
224
|
+
{ name: "--wzl-select-border", type: "border", group: "select", defaultValue: "1px solid var(--wzl-border)", description: "Border of a Select\u2019s trigger. Unset, a boxed trigger draws --wzl-border and a bare one a transparent border of the same width.", hook: true },
|
|
225
|
+
{ name: "--wzl-select-fg", type: "color", group: "select", defaultValue: "var(--wzl-fg)", description: "Text color of a Select\u2019s trigger.", hook: true },
|
|
226
|
+
{ name: "--wzl-swatch-size", type: "dimension", group: "swatch", defaultValue: "28px", description: "Minimum cell of a swatch grid \u2014 PatternPicker, and any panel laying swatches out the same way.", hook: true },
|
|
227
|
+
{ name: "--wzl-timeline-label-w", type: "dimension", group: "timeline", defaultValue: "120px", description: "Width of the Timeline\u2019s track-label gutter.", hook: true },
|
|
228
|
+
{ name: "--wzl-timeline-value-axis-w", type: "dimension", group: "timeline", defaultValue: "32px", description: "Width reserved for the Timeline\u2019s value axis.", hook: true },
|
|
229
|
+
{ name: "--wzl-titlebar-align", type: "string", group: "titlebar", defaultValue: "start", description: "Text alignment of a `titlebar` frame\u2019s title along its strip.", hook: true },
|
|
230
|
+
{ name: "--wzl-titlebar-border", type: "border", group: "titlebar", defaultValue: "1px solid var(--_edge)", description: "Border of a `titlebar` frame. A theme whose --wzl-bevel-raised draws the edge sets it to a border of no width.", hook: true },
|
|
231
|
+
{ name: "--wzl-titlebar-fg", type: "color", group: "titlebar", defaultValue: "var(--_edge-ink)", description: "Text color on a `titlebar` frame\u2019s strip. Unset, black or white, whichever reads on the edge color.", hook: true },
|
|
232
|
+
{ name: "--wzl-titlebar-inset", type: "dimension", group: "titlebar", defaultValue: "0", description: "Padding between a `titlebar` frame\u2019s edge and its strip and body: the width of the bevel a theme draws there.", hook: true },
|
|
233
|
+
{ name: "--wzl-titlebar-label-pad", type: "dimension", group: "titlebar", defaultValue: "0", description: "Inline padding of the patch --wzl-titlebar-label-surface paints behind a `titlebar` frame\u2019s title.", hook: true },
|
|
234
|
+
{ name: "--wzl-titlebar-label-surface", type: "color", group: "titlebar", defaultValue: "transparent", description: "Background behind a `titlebar` frame\u2019s title alone, for a strip drawn in stripes that must not run through the letters.", hook: true },
|
|
235
|
+
{ name: "--wzl-titlebar-surface", type: "color", group: "titlebar", defaultValue: "var(--_edge)", description: "Background of the strip a `titlebar` frame carries its title in: a color, a gradient, or stripes. Unset, the frame\u2019s edge color. A frame that names a tone paints the tone instead.", hook: true },
|
|
236
|
+
{ name: "--wzl-titlebar-weight", type: "fontWeight", group: "titlebar", defaultValue: "var(--wzl-font-weight-bold)", description: "Font weight of a `titlebar` frame\u2019s title.", hook: true },
|
|
237
|
+
{ name: "--wzl-tree-fold-size", type: "dimension", group: "tree", defaultValue: "16px", description: "Size of the leading glyph a Tree folds a branch by, where its branches fold by their glyphs.", hook: true },
|
|
238
|
+
{ name: "--wzl-tree-font-size", type: "dimension", group: "tree", defaultValue: "var(--wzl-font-size-sm)", description: "Size of a Tree row\u2019s text.", hook: true },
|
|
239
|
+
{ name: "--wzl-tree-guide", type: "color", group: "tree", defaultValue: "var(--wzl-fg-subtle)", description: "Color of the bracket a Tree draws down a branch.", hook: true },
|
|
240
|
+
{ name: "--wzl-tree-indent", type: "dimension", group: "tree", defaultValue: "calc(var(--wzl-control-h-xs) + var(--wzl-space-2))", description: "Indent of each Tree level. Unset, it is one twisty and one gap, so a child\u2019s twisty sits under its parent\u2019s label.", hook: true },
|
|
241
|
+
{ name: "--wzl-tree-leaf-indent", type: "dimension", group: "tree", defaultValue: "0", description: "How far in from its branches' glyphs a Tree with guides sets a row that folds nothing.", hook: true }
|
|
242
|
+
];
|
|
243
|
+
|
|
244
|
+
export { TOKEN_MANIFEST };
|
|
245
|
+
//# sourceMappingURL=chunk-354G4TUL.js.map
|
|
246
|
+
//# sourceMappingURL=chunk-354G4TUL.js.map
|