@kitlangton/knobs 0.4.0-next.0 → 0.4.0-next.2

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.
Files changed (47) hide show
  1. package/README.md +351 -43
  2. package/dist/dev/{chunk-stbcgz1y.js → chunk-1qzffbpa.js} +443 -451
  3. package/dist/dev/{chunk-7xgkerd2.js → chunk-3ygqgy1x.js} +23 -1
  4. package/dist/dev/{chunk-pmkvb9ep.js → chunk-8mabjeyk.js} +1920 -507
  5. package/dist/dev/{chunk-t68smqkc.js → chunk-ayb292zj.js} +13 -11
  6. package/dist/dev/index.js +10 -5
  7. package/dist/index.js +25 -1
  8. package/dist/panel.js +2900 -1320
  9. package/dist/react.js +294 -6
  10. package/dist/solid.js +292 -4
  11. package/dist/themes.js +1509 -7
  12. package/dist/types/core/adapter.d.ts +6 -2
  13. package/dist/types/core/appearance.d.ts +44 -0
  14. package/dist/types/core/glide.d.ts +7 -0
  15. package/dist/types/core/motion.d.ts +66 -0
  16. package/dist/types/core/root.d.ts +13 -0
  17. package/dist/types/core/store.d.ts +18 -5
  18. package/dist/types/core/theme.d.ts +10 -3
  19. package/dist/types/index.d.ts +2 -1
  20. package/dist/types/panel/gpu/color.d.ts +6 -0
  21. package/dist/types/panel/motion.d.ts +1 -1
  22. package/dist/types/panel/styles.d.ts +2 -3
  23. package/dist/types/themes/define.d.ts +104 -0
  24. package/dist/types/themes/index.d.ts +11 -0
  25. package/dist/types/themes/knobs.d.ts +5 -0
  26. package/dist/types/themes/void.d.ts +8 -0
  27. package/dist/types/tokens/color.d.ts +42 -0
  28. package/dist/types/tokens/css.d.ts +13 -0
  29. package/dist/types/tokens/evaluate.d.ts +8 -0
  30. package/dist/types/tokens/index.d.ts +4 -0
  31. package/dist/types/tokens/schema.d.ts +1100 -0
  32. package/dist/types/ui/bento-css.d.ts +1 -1
  33. package/dist/types/ui/compare-css.d.ts +1 -1
  34. package/dist/types/ui/index.d.ts +3 -3
  35. package/dist/types/ui/look.d.ts +18 -13
  36. package/dist/types/ui/overlay-css.d.ts +1 -1
  37. package/dist/types/ui/readout-css.d.ts +1 -1
  38. package/dist/types/ui/readout-model.d.ts +5 -1
  39. package/dist/types/ui/rgba.d.ts +11 -0
  40. package/dist/types/ui/walkthrough-blocks.d.ts +43 -0
  41. package/dist/types/ui/walkthrough-media.d.ts +4 -0
  42. package/dist/types/ui/walkthrough-model.d.ts +237 -3
  43. package/dist/types/ui/walkthrough.d.ts +3 -1
  44. package/dist/ui-react.js +3193 -791
  45. package/dist/ui-solid.js +3193 -791
  46. package/dist/ui.js +3340 -935
  47. package/package.json +1 -1
@@ -2,10 +2,203 @@ import {
2
2
  isTypingTarget,
3
3
  GRADIENT_SAMPLES,
4
4
  Spring,
5
+ springMotion2,
5
6
  springEasing,
6
7
  springCss2,
8
+ SPRINGS2,
9
+ springLinear,
10
+ DEFAULT_LINEAR,
11
+ motionCss,
7
12
  storageKey
8
- } from "./chunk-7xgkerd2.js";
13
+ } from "./chunk-3ygqgy1x.js";
14
+
15
+ // src/core/theme.ts
16
+ var property = (k) => k.startsWith("--") ? k : `--k-${k}`;
17
+ function presetCss(preset) {
18
+ if (!/^[\w-]+$/.test(preset.name))
19
+ throw Error(`Invalid preset name: ${preset.name}`);
20
+ let at = `.knobs-root[data-preset="${preset.name}"]`, light = preset.light ?? {}, decls = Object.entries(preset.dark).map(([k, dark]) => {
21
+ let l = light[k];
22
+ return l === void 0 || String(l) === String(dark) ? `${property(k)}:${dark}` : `${property(k)}:light-dark(${l},${dark})`;
23
+ });
24
+ for (let [k, l] of Object.entries(light))
25
+ if (!(k in preset.dark) && k !== "color-scheme")
26
+ decls.push(`${property(k)}:${l}`);
27
+ return `${at}{${decls.join(";")}}${(preset.css ?? "").replaceAll("&", at)}`;
28
+ }
29
+ var glide = /* @__PURE__ */ springCss2({ duration: 0.185, bounce: 0.14 });
30
+ var problemsPreset = {
31
+ name: "problems",
32
+ dark: {
33
+ bg: "#161618",
34
+ surface: "rgba(255,255,255,.055)",
35
+ "surface-hi": "rgba(255,255,255,.11)",
36
+ line: "rgba(255,255,255,.075)",
37
+ "line-hi": "rgba(255,255,255,.12)",
38
+ text: "#f5f5f7",
39
+ label: "rgba(235,235,245,.62)",
40
+ dim: "rgba(235,235,245,.36)",
41
+ accent: "#0091ff",
42
+ modified: "#0091ff",
43
+ "seg-bg": "rgba(120,120,128,.16)",
44
+ "seg-active": "rgba(120,120,128,.24)",
45
+ "toggle-track": "rgba(120,120,128,.32)",
46
+ "toggle-thumb": "#fff",
47
+ rim: "transparent",
48
+ font: 'system-ui,-apple-system,BlinkMacSystemFont,"Helvetica Neue",sans-serif',
49
+ mono: '"Kit SF Mono",ui-monospace,Menlo,monospace',
50
+ "font-size": "13px",
51
+ "label-weight": 500,
52
+ row: "34px",
53
+ radius: "8px",
54
+ "panel-radius": "12px",
55
+ pad: "0px",
56
+ inset: "10px",
57
+ gap: "4px",
58
+ "row-gap": "4px",
59
+ glass: 0,
60
+ glow: 0,
61
+ blur: 0.6,
62
+ "hover-in": 0,
63
+ "hover-out": 100,
64
+ "handle-rest": 0.55,
65
+ handle: "var(--k-text)",
66
+ "handle-inset": "7.5px",
67
+ "fill-base": "transparent",
68
+ "fill-rest-mix": "24%",
69
+ "fill-hover-mix": "36%",
70
+ "fill-active-mix": "36%",
71
+ chrome: 0,
72
+ "group-transform": "none",
73
+ "value-font": "var(--k-mono)",
74
+ "unit-gap": "0px",
75
+ "unit-color": "currentColor",
76
+ "readout-mark": 1,
77
+ "group-size": "12px",
78
+ "group-color": "rgba(235,235,245,.62)",
79
+ "group-inset": "0px",
80
+ "group-tracking": "-.01em",
81
+ "group-divider": "rgba(255,255,255,.075)",
82
+ "group-divider-gap": "8px",
83
+ "curve-inset": "0px",
84
+ "curve-guide": "dashed",
85
+ "curve-dot": 0,
86
+ spring: "0.185 0.14",
87
+ "fill-ease": glide.easing,
88
+ "fill-ms": glide.duration
89
+ },
90
+ light: {
91
+ bg: "#fff",
92
+ surface: "rgba(0,0,0,.045)",
93
+ "surface-hi": "rgba(0,0,0,.09)",
94
+ line: "rgba(0,0,0,.07)",
95
+ "line-hi": "rgba(0,0,0,.11)",
96
+ text: "#000",
97
+ label: "rgba(60,60,67,.66)",
98
+ dim: "rgba(60,60,67,.38)",
99
+ accent: "#0088ff",
100
+ modified: "#0088ff",
101
+ "seg-bg": "rgba(120,120,128,.11)",
102
+ "seg-active": "#fff",
103
+ "toggle-track": "rgba(120,120,128,.2)",
104
+ "toggle-thumb": "#fff",
105
+ rim: "transparent",
106
+ "group-color": "rgba(60,60,67,.66)",
107
+ "group-divider": "rgba(0,0,0,.07)"
108
+ }
109
+ };
110
+
111
+ // src/core/appearance.ts
112
+ var MODES = {
113
+ dark: "dark",
114
+ light: "light",
115
+ auto: "system"
116
+ };
117
+ function resolveLook(options = {}, base) {
118
+ let t = options.theme, mode = typeof t === "string" ? MODES[t] : void 0, theme = typeof t === "object" ? t : base?.theme, preset = options.preset ?? base?.preset;
119
+ return {
120
+ ...theme ? { theme } : {},
121
+ appearance: options.appearance ?? mode ?? base?.appearance ?? "inherit",
122
+ ...preset ? { preset } : {}
123
+ };
124
+ }
125
+ var themes = /* @__PURE__ */ new Map;
126
+ function themeOf(el) {
127
+ let name = el.closest("[data-knobs-theme]")?.dataset.knobsTheme;
128
+ return name ? themes.get(name) : void 0;
129
+ }
130
+ var themeSelector = (name) => `:where(.knobs-root)[data-knobs-theme="${name}"]`;
131
+ function upsertStyle(doc, key, value, content) {
132
+ let existing = doc.querySelector(`style[${key}="${value}"]`);
133
+ if (existing) {
134
+ if (existing.textContent !== content)
135
+ existing.textContent = content;
136
+ return;
137
+ }
138
+ let style = doc.createElement("style");
139
+ style.setAttribute(key, value), style.textContent = content, doc.head.append(style);
140
+ }
141
+ function injectTheme(doc, theme) {
142
+ themes.set(theme.name, theme), upsertStyle(doc, "data-knobs-theme-css", theme.name, theme.css({ selector: themeSelector(theme.name) }));
143
+ }
144
+ var presets = /* @__PURE__ */ new Map;
145
+ function injectPreset(doc, preset) {
146
+ presets.set(preset.name, preset), upsertStyle(doc, "data-knobs-preset", preset.name, presetCss(preset));
147
+ }
148
+ var setAttr = (el, name, value) => {
149
+ if (value === void 0)
150
+ el.removeAttribute(name);
151
+ else if (el.getAttribute(name) !== value)
152
+ el.setAttribute(name, value);
153
+ };
154
+ function applyLook(el, look) {
155
+ let doc = el.ownerDocument;
156
+ if (look.theme)
157
+ injectTheme(doc, look.theme);
158
+ if (look.preset)
159
+ injectPreset(doc, look.preset);
160
+ if (setAttr(el, "data-knobs-theme", look.theme?.name), setAttr(el, "data-preset", look.preset?.name), setAttr(el, "data-appearance", look.appearance === "inherit" ? void 0 : look.appearance), look.appearance === "inherit")
161
+ followPage(el);
162
+ else
163
+ clearInherited(el);
164
+ }
165
+ var clearInherited = (el) => {
166
+ el.style.removeProperty("color-scheme"), el.style.removeProperty("--_k-light");
167
+ };
168
+ function resolveInherited(el) {
169
+ let parent = el.parentElement, win = el.ownerDocument.defaultView;
170
+ if (!parent || !win || el.hasAttribute("data-appearance"))
171
+ return;
172
+ if (parent.closest(".knobs-root"))
173
+ return clearInherited(el);
174
+ let scheme = win.getComputedStyle(parent).colorScheme.trim(), dark = /\bdark\b/.test(scheme), light = /\blight\b/.test(scheme);
175
+ if (!dark && !light)
176
+ return clearInherited(el);
177
+ let isLight = dark && light ? win.matchMedia?.("(prefers-color-scheme: light)").matches ?? !1 : light;
178
+ el.style.setProperty("color-scheme", "inherit"), el.style.setProperty("--_k-light", isLight ? "1" : "0");
179
+ }
180
+ var watched = /* @__PURE__ */ new WeakSet;
181
+ function followPage(el) {
182
+ let doc = el.ownerDocument, win = doc.defaultView;
183
+ if (!win)
184
+ return;
185
+ let run = () => resolveInherited(el);
186
+ if (el.isConnected)
187
+ run();
188
+ if (queueMicrotask(run), win.requestAnimationFrame?.(run), watched.has(doc))
189
+ return;
190
+ watched.add(doc);
191
+ let all = () => {
192
+ for (let root of doc.querySelectorAll(".knobs-root:not([data-appearance])"))
193
+ resolveInherited(root);
194
+ }, observer = new MutationObserver(all), attributeFilter = ["class", "data-theme", "data-appearance"];
195
+ if (observer.observe(doc.documentElement, { attributes: !0, attributeFilter }), doc.body)
196
+ observer.observe(doc.body, { attributes: !0, attributeFilter });
197
+ win.matchMedia?.("(prefers-color-scheme: light)").addEventListener?.("change", all);
198
+ }
199
+
200
+ // src/core/adapter.ts
201
+ var panelLook = (controls, look = {}) => resolveLook(look, resolveLook({ theme: controls.theme, appearance: controls.appearance }));
9
202
 
10
203
  // src/panel/icons.ts
11
204
  var ICONS = {
@@ -162,99 +355,8 @@ var rolling_css_default = `.rn-root {
162
355
  .rn-solid:not([data-rn-hydrated]) > .rn-mount { display: none; }
163
356
  `;
164
357
 
165
- // src/core/theme.ts
166
- var block = (tokens) => Object.entries(tokens).map(([k, v]) => `${k.startsWith("--") || k === "color-scheme" ? k : `--k-${k}`}:${v}`).join(";");
167
- function presetCss(preset) {
168
- if (!/^[\w-]+$/.test(preset.name))
169
- throw Error(`Invalid preset name: ${preset.name}`);
170
- let at = `.knobs-panel[data-preset="${preset.name}"]`, light = preset.light ? `:where(.knobs-panel)[data-preset="${preset.name}"][data-theme="light"],:where([data-knobs-theme="light"]) ${at}:not([data-theme="dark"]),:where(:root[data-theme="light"]) ${at}[data-theme="auto"]{${block(preset.light)}}@media(prefers-color-scheme:light){:where(:root:not([data-theme="dark"])) ${at}[data-theme="auto"]{${block(preset.light)}}}` : "";
171
- return `${at}{${block(preset.dark)}}${light}${(preset.css ?? "").replaceAll("&", at)}`;
172
- }
173
- var glide = /* @__PURE__ */ springCss2({ duration: 0.185, bounce: 0.14 });
174
- var problemsPreset = {
175
- name: "problems",
176
- dark: {
177
- bg: "#161618",
178
- surface: "rgba(255,255,255,.055)",
179
- "surface-hi": "rgba(255,255,255,.11)",
180
- line: "rgba(255,255,255,.075)",
181
- "line-hi": "rgba(255,255,255,.12)",
182
- text: "#f5f5f7",
183
- label: "rgba(235,235,245,.62)",
184
- dim: "rgba(235,235,245,.36)",
185
- accent: "#0091ff",
186
- modified: "#0091ff",
187
- "seg-bg": "rgba(120,120,128,.16)",
188
- "seg-active": "rgba(120,120,128,.24)",
189
- "toggle-track": "rgba(120,120,128,.32)",
190
- "toggle-thumb": "#fff",
191
- rim: "transparent",
192
- font: 'system-ui,-apple-system,BlinkMacSystemFont,"Helvetica Neue",sans-serif',
193
- mono: '"Kit SF Mono",ui-monospace,Menlo,monospace',
194
- "font-size": "13px",
195
- "label-weight": 500,
196
- row: "34px",
197
- radius: "8px",
198
- "panel-radius": "12px",
199
- pad: "0px",
200
- inset: "10px",
201
- gap: "4px",
202
- "row-gap": "4px",
203
- glass: 0,
204
- glow: 0,
205
- blur: 0.6,
206
- "hover-in": 0,
207
- "hover-out": 100,
208
- "handle-rest": 0.55,
209
- handle: "var(--k-text)",
210
- "handle-inset": "7.5px",
211
- "fill-base": "transparent",
212
- "fill-rest-mix": "24%",
213
- "fill-hover-mix": "36%",
214
- "fill-active-mix": "36%",
215
- chrome: 0,
216
- "group-transform": "none",
217
- "value-font": "var(--k-mono)",
218
- "unit-gap": "0px",
219
- "unit-color": "currentColor",
220
- "readout-mark": 1,
221
- "group-size": "12px",
222
- "group-color": "rgba(235,235,245,.62)",
223
- "group-inset": "0px",
224
- "group-tracking": "-.01em",
225
- "group-divider": "rgba(255,255,255,.075)",
226
- "group-divider-gap": "8px",
227
- "curve-inset": "0px",
228
- "curve-guide": "dashed",
229
- "curve-dot": 0,
230
- spring: "0.185 0.14",
231
- "fill-ease": glide.easing,
232
- "fill-ms": glide.duration
233
- },
234
- light: {
235
- bg: "#fff",
236
- surface: "rgba(0,0,0,.045)",
237
- "surface-hi": "rgba(0,0,0,.09)",
238
- line: "rgba(0,0,0,.07)",
239
- "line-hi": "rgba(0,0,0,.11)",
240
- text: "#000",
241
- label: "rgba(60,60,67,.66)",
242
- dim: "rgba(60,60,67,.38)",
243
- accent: "#0088ff",
244
- modified: "#0088ff",
245
- "seg-bg": "rgba(120,120,128,.11)",
246
- "seg-active": "#fff",
247
- "toggle-track": "rgba(120,120,128,.2)",
248
- "toggle-thumb": "#fff",
249
- rim: "transparent",
250
- "group-color": "rgba(60,60,67,.66)",
251
- "group-divider": "rgba(0,0,0,.07)",
252
- "color-scheme": "light"
253
- }
254
- };
255
-
256
358
  // src/panel/motion.ts
257
- var FILL = { omega: 30, zeta: 0.88 };
359
+ var FILL = springMotion2(SPRINGS2.default);
258
360
  var LEAD = { omega: 34, zeta: 0.86 }, TRAIL = { omega: 25, zeta: 1 }, trailScale = (blur) => 0.6 + 0.4 * clamp(blur, 0, 2);
259
361
 
260
362
  class Edges {
@@ -560,7 +662,7 @@ function digitHints(count, showing) {
560
662
  }
561
663
 
562
664
  // src/panel/crumbs.ts
563
- var glide2 = springEasing(2 * Math.PI / 0.3, 1), CRUMB_GLIDE = `${glide2.ms}ms ${glide2.easing}`, SLIDE = 5, GAP = 6, HINT_GAP = 10, SEP = "›";
665
+ var glide2 = springLinear(SPRINGS2.default), CRUMB_GLIDE = `${glide2.ms}ms ${glide2.easing}`, SLIDE = 5, GAP = 6, HINT_GAP = 10, SEP = "›";
564
666
  function createCrumbs(o) {
565
667
  let doc = o.header.ownerDocument, element = doc.createElement("div");
566
668
  element.className = "knobs-crumbs", element.setAttribute("aria-hidden", "true"), o.header.append(element);
@@ -673,38 +775,1388 @@ function createCrumbs(o) {
673
775
  };
674
776
  }
675
777
 
676
- // src/panel/styles.ts
677
- var lead = springEasing(LEAD.omega, LEAD.zeta), trail = springEasing(TRAIL.omega, TRAIL.zeta), fill = springEasing(FILL.omega, FILL.zeta), LEAD_T = `${lead.ms}ms var(--k-lead)`, TRAIL_T = `calc(${trail.ms}ms * (.6 + .4 * clamp(0, var(--k-blur), 2))) var(--k-trail)`, FILL_T = "calc(var(--k-fill-ms) * 1ms * clamp(var(--k-blur),.1,2)) var(--k-fill-ease)", SLIDE_T = "calc(var(--k-fill-ms) * 1ms) var(--k-fill-ease)", snappy = springEasing(2 * Math.PI / 0.25, 1), snappyOut = springEasing(2 * Math.PI / 0.2, 1), BLOOM_IN = `${snappy.ms}ms ${snappy.easing}`, BLOOM_OUT = `${snappyOut.ms}ms ${snappyOut.easing}`, DELAY = "var(--k-delay,0ms)", armed = springEasing(2 * Math.PI / 0.3, 1), ARMED_T = `${armed.ms}ms ${armed.easing}`, POINTER_ROW = ".knobs-panel[data-k-row-hover]:not([data-keyboard])", DELAYED = ".knobs-fill,.knobs-handle,.knobs-seg-pill,.knobs-toggle,.knobs-toggle i,.knobs-arm,.knobs-curve,.knobs-swatch,.knobs-strip-thumb,.knobs-pad>i,.knobs-ease-handle,.knobs-range-track,.knobs-range-fill,.knobs-range-thumb,.knobs-dial-hand,.knobs-grad,.knobs-grad-mini,.knobs-grad-mini>i,.knobs-grad-stop,.knobs-graph-pt", GRAD_N = GRADIENT_SAMPLES, gradStops = (at) => Array.from({ length: GRAD_N }, (_, i) => `var(--kgrad-${i}) ${at(i)}`).join(","), GRAD_STRIP = `linear-gradient(to right,${gradStops((i) => `calc(var(--kg-r) + (100% - var(--kg-r) * 2) * ${Number((i / (GRAD_N - 1)).toFixed(5))})`)})`, GRAD_MINI = `linear-gradient(to right,${gradStops((i) => `${Number((i / (GRAD_N - 1) * 100).toFixed(3))}%`)})`, GRAD_PROPS = Array.from({ length: GRAD_N }, (_, i) => `@property --kgrad-${i}{syntax:"<color>";inherits:false;initial-value:transparent}`).join(`
678
- `), COLOR_TOKENS = [
778
+ // src/tokens/color.ts
779
+ var clamp01 = (x) => Math.min(1, Math.max(0, x)), toLinear = (c) => c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4, toGamma = (c) => c <= 0.0031308 ? 12.92 * c : 1.055 * c ** 0.4166666666666667 - 0.055;
780
+ function linearToOklch([r, g, b, a]) {
781
+ let l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b), m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b), s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b), L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s, A = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s, B = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s, c = Math.hypot(A, B), h = c < 0.0000001 ? 0 : (Math.atan2(B, A) * 180 / Math.PI + 360) % 360;
782
+ return { l: L, c, h, alpha: a };
783
+ }
784
+ function oklchToLinear({ l: L, c, h, alpha = 1 }) {
785
+ let hr = h * Math.PI / 180, A = c * Math.cos(hr), B = c * Math.sin(hr), l = (L + 0.3963377774 * A + 0.2158037573 * B) ** 3, m = (L - 0.1055613458 * A - 0.0638541728 * B) ** 3, s = (L - 0.0894841775 * A - 1.291485548 * B) ** 3;
786
+ return [
787
+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
788
+ -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
789
+ -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,
790
+ alpha
791
+ ];
792
+ }
793
+ var inGamut = ([r, g, b]) => [r, g, b].every((x) => x >= -0.00001 && x <= 1.00001);
794
+ function oklchToLinearInGamut(color) {
795
+ let rgb = oklchToLinear(color);
796
+ if (inGamut(rgb))
797
+ return clampRgba(rgb);
798
+ let lo = 0, hi = color.c;
799
+ for (let i = 0;i < 24; i++) {
800
+ let mid = (lo + hi) / 2;
801
+ if (rgb = oklchToLinear({ ...color, c: mid }), inGamut(rgb))
802
+ lo = mid;
803
+ else
804
+ hi = mid;
805
+ }
806
+ return clampRgba(oklchToLinear({ ...color, c: lo }));
807
+ }
808
+ var clampRgba = ([r, g, b, a]) => [clamp01(r), clamp01(g), clamp01(b), clamp01(a)];
809
+ function parseColor(input) {
810
+ let s = input.trim().toLowerCase();
811
+ if (s === "transparent")
812
+ return [0, 0, 0, 0];
813
+ if (s.startsWith("#")) {
814
+ let hex = s.slice(1);
815
+ if (hex.length === 3 || hex.length === 4)
816
+ hex = [...hex].map((ch) => ch + ch).join("");
817
+ if (!/^[0-9a-f]{6}([0-9a-f]{2})?$/.test(hex))
818
+ throw Error(`Invalid colour: ${input}`);
819
+ let n = (i) => Number.parseInt(hex.slice(i, i + 2), 16) / 255;
820
+ return [toLinear(n(0)), toLinear(n(2)), toLinear(n(4)), hex.length === 8 ? n(6) : 1];
821
+ }
822
+ let fn = /^(oklch|rgba?)\(([^)]*)\)$/.exec(s);
823
+ if (!fn)
824
+ throw Error(`Unsupported colour: ${input}`);
825
+ let parts = fn[2].split(/[\s,/]+/).filter(Boolean), num = (p, scale) => p === void 0 ? 1 : p.endsWith("%") ? Number.parseFloat(p) / 100 : Number.parseFloat(p) / scale;
826
+ if (fn[1] === "oklch") {
827
+ let l = num(parts[0], 1);
828
+ return oklchToLinearInGamut({
829
+ l,
830
+ c: Number.parseFloat(parts[1]),
831
+ h: Number.parseFloat(parts[2]),
832
+ alpha: num(parts[3], 1)
833
+ });
834
+ }
835
+ return [
836
+ toLinear(num(parts[0], 255)),
837
+ toLinear(num(parts[1], 255)),
838
+ toLinear(num(parts[2], 255)),
839
+ num(parts[3], 1)
840
+ ];
841
+ }
842
+ var toOklch = (input) => linearToOklch(parseColor(input)), byte = (c) => Math.round(clamp01(c) * 255).toString(16).padStart(2, "0");
843
+ function formatHex([r, g, b, a]) {
844
+ let rgb = `#${byte(toGamma(r))}${byte(toGamma(g))}${byte(toGamma(b))}`;
845
+ return a >= 0.9995 ? rgb : rgb + byte(a);
846
+ }
847
+ var oklchToHex = (color) => formatHex(oklchToLinearInGamut(color)), normalize = (input) => formatHex(parseColor(input));
848
+ function withAlpha(input, alpha) {
849
+ let [r, g, b, a] = parseColor(input);
850
+ return formatHex([r, g, b, a * alpha]);
851
+ }
852
+ function over(top, bottom) {
853
+ let t = parseColor(top), b = parseColor(bottom), a = t[3], mix = (i) => toLinear(toGamma(t[i]) * a + toGamma(b[i]) * (1 - a));
854
+ return formatHex([mix(0), mix(1), mix(2), 1]);
855
+ }
856
+ function apcaY(input) {
857
+ let [r, g, b] = parseColor(input).map(toGamma);
858
+ return 0.2126729 * r ** 2.4 + 0.7151522 * g ** 2.4 + 0.072175 * b ** 2.4;
859
+ }
860
+ function apca(text, background) {
861
+ let bgOpaque = parseColor(background)[3] < 1 ? over(background, "#000") : background, fg = parseColor(text)[3] < 1 ? over(text, bgOpaque) : text, soft = (y) => y > 0.022 ? y : y + (0.022 - y) ** 1.414, yt = soft(apcaY(fg)), yb = soft(apcaY(bgOpaque));
862
+ if (Math.abs(yb - yt) < 0.0005)
863
+ return 0;
864
+ if (yb > yt) {
865
+ let sapc = (yb ** 0.56 - yt ** 0.57) * 1.14;
866
+ return sapc < 0.1 ? 0 : (sapc - 0.027) * 100;
867
+ }
868
+ let sapc = (yb ** 0.65 - yt ** 0.62) * 1.14;
869
+ return sapc > -0.1 ? 0 : -(sapc + 0.027) * 100;
870
+ }
871
+
872
+ // src/tokens/schema.ts
873
+ var theme = { from: "theme" }, css = (s) => ({ css: s }), value = (s) => ({ value: s }), alpha = (pct, of = "var(--k-fg)") => `color-mix(in oklch,${of} calc(${pct}% * var(--k-contrast)),transparent)`, TOKENS = [
874
+ {
875
+ name: "accent",
876
+ tier: "input",
877
+ type: "color",
878
+ group: "Accent",
879
+ source: theme,
880
+ doc: "The one accent: primary actions, handles, focus. Hover, soft and selection derive from it in CSS.",
881
+ deprecated: ["--ku-accent"]
882
+ },
883
+ {
884
+ name: "contrast",
885
+ tier: "input",
886
+ type: "number",
887
+ group: "Inputs",
888
+ source: theme,
889
+ doc: "Contrast multiplier for fills and alpha borders (1 = default; the theme's 0–100 dial maps 50 → 1)."
890
+ },
891
+ {
892
+ name: "radius",
893
+ tier: "input",
894
+ type: "length",
895
+ group: "Shape",
896
+ source: theme,
897
+ doc: "Control corner radius. 0 squares everything, including capsules. Scales with density.",
898
+ deprecated: ["--ku-radius"],
899
+ resolve: "round(calc($ * (1 + (var(--_k-density) - 1) * 1.5)),2px)"
900
+ },
901
+ {
902
+ name: "density",
903
+ tier: "input",
904
+ type: "number",
905
+ group: "Size",
906
+ source: theme,
907
+ doc: "Size multiplier: compact .875, default 1, comfortable 1.1875."
908
+ },
909
+ {
910
+ name: "font",
911
+ tier: "input",
912
+ type: "font",
913
+ group: "Type",
914
+ source: theme,
915
+ doc: "UI font stack.",
916
+ deprecated: ["--ku-font"]
917
+ },
918
+ {
919
+ name: "mono",
920
+ tier: "input",
921
+ type: "font",
922
+ group: "Type",
923
+ source: theme,
924
+ doc: "Monospace font stack.",
925
+ deprecated: ["--ku-mono"]
926
+ },
927
+ {
928
+ name: "bg-page",
929
+ tier: "semantic",
930
+ type: "color",
931
+ group: "Surfaces",
932
+ source: theme,
933
+ doc: "The page behind panels; workspace backdrops.",
934
+ deprecated: ["--k-page", "--ku-page"]
935
+ },
936
+ {
937
+ name: "bg-inset",
938
+ tier: "semantic",
939
+ type: "color",
940
+ group: "Surfaces",
941
+ source: theme,
942
+ doc: "Wells sunk into a panel: tracks, inputs, segmented backgrounds."
943
+ },
944
+ {
945
+ name: "bg",
946
+ tier: "semantic",
947
+ type: "color",
948
+ group: "Surfaces",
949
+ source: theme,
950
+ doc: "The panel surface.",
951
+ deprecated: ["--ku-bg"]
952
+ },
953
+ {
954
+ name: "bg-raised",
955
+ tier: "semantic",
956
+ type: "color",
957
+ group: "Surfaces",
958
+ source: theme,
959
+ doc: "Raised within a panel: the active segment, cards on a panel."
960
+ },
961
+ {
962
+ name: "bg-overlay",
963
+ tier: "semantic",
964
+ type: "color",
965
+ group: "Surfaces",
966
+ source: theme,
967
+ doc: "Floating surfaces: menus, popovers, tooltips."
968
+ },
969
+ {
970
+ name: "fill",
971
+ tier: "semantic",
972
+ type: "color",
973
+ group: "Fills",
974
+ source: css(alpha(5.5)),
975
+ doc: "Resting fill for controls.",
976
+ deprecated: ["--k-surface", "--ku-surface"]
977
+ },
978
+ {
979
+ name: "fill-hover",
980
+ tier: "semantic",
981
+ type: "color",
982
+ group: "Fills",
983
+ source: css(alpha(8)),
984
+ doc: "Hovered fill."
985
+ },
986
+ {
987
+ name: "fill-selected",
988
+ tier: "semantic",
989
+ type: "color",
990
+ group: "Fills",
991
+ source: css(alpha(11)),
992
+ doc: "Pressed or selected fill.",
993
+ deprecated: ["--k-surface-hi", "--ku-surface-hi"]
994
+ },
995
+ {
996
+ name: "fg",
997
+ tier: "semantic",
998
+ type: "color",
999
+ group: "Foreground",
1000
+ source: theme,
1001
+ doc: "Primary text and icons (≥ Lc 90 on bg).",
1002
+ deprecated: ["--k-text", "--ku-text"]
1003
+ },
1004
+ {
1005
+ name: "fg-2",
1006
+ tier: "semantic",
1007
+ type: "color",
1008
+ group: "Foreground",
1009
+ source: theme,
1010
+ doc: "Secondary text: labels (≥ Lc 75).",
1011
+ deprecated: ["--k-label", "--ku-label"]
1012
+ },
1013
+ {
1014
+ name: "fg-3",
1015
+ tier: "semantic",
1016
+ type: "color",
1017
+ group: "Foreground",
1018
+ source: theme,
1019
+ doc: "Tertiary text: metadata, units, captions (≥ Lc 45).",
1020
+ deprecated: ["--k-dim", "--ku-dim"]
1021
+ },
1022
+ {
1023
+ name: "fg-4",
1024
+ tier: "semantic",
1025
+ type: "color",
1026
+ group: "Foreground",
1027
+ source: theme,
1028
+ doc: "Placeholder and disabled text (≥ Lc 30)."
1029
+ },
1030
+ {
1031
+ name: "border-subtle",
1032
+ tier: "semantic",
1033
+ type: "color",
1034
+ group: "Borders",
1035
+ source: css(alpha(6)),
1036
+ doc: "Hairline edges and dividers (below Lc 15 by design).",
1037
+ deprecated: ["--k-edge"]
1038
+ },
1039
+ {
1040
+ name: "border",
1041
+ tier: "semantic",
1042
+ type: "color",
1043
+ group: "Borders",
1044
+ source: css(alpha(10)),
1045
+ doc: "Default borders.",
1046
+ deprecated: ["--k-line", "--ku-line"]
1047
+ },
1048
+ {
1049
+ name: "border-strong",
1050
+ tier: "semantic",
1051
+ type: "color",
1052
+ group: "Borders",
1053
+ source: theme,
1054
+ doc: "Interactive edges (≥ Lc 15; solid).",
1055
+ deprecated: ["--k-line-hi", "--ku-line-hi"]
1056
+ },
1057
+ {
1058
+ name: "accent-hover",
1059
+ tier: "semantic",
1060
+ type: "color",
1061
+ group: "Accent",
1062
+ source: css("color-mix(in oklch,var(--k-accent) 90%,var(--k-bg))"),
1063
+ doc: "Hovered accent."
1064
+ },
1065
+ {
1066
+ name: "accent-soft",
1067
+ tier: "semantic",
1068
+ type: "color",
1069
+ group: "Accent",
1070
+ source: css("color-mix(in oklch,var(--k-accent) 15%,transparent)"),
1071
+ doc: "Accent tint behind accent content."
1072
+ },
1073
+ {
1074
+ name: "accent-fg",
1075
+ tier: "semantic",
1076
+ type: "color",
1077
+ group: "Accent",
1078
+ source: theme,
1079
+ doc: "Accent as text on bg (≥ Lc 60)."
1080
+ },
1081
+ {
1082
+ name: "on-accent",
1083
+ tier: "semantic",
1084
+ type: "color",
1085
+ group: "Accent",
1086
+ source: theme,
1087
+ doc: "Content placed on a solid accent."
1088
+ },
1089
+ { name: "ok", tier: "semantic", type: "color", group: "Status", source: theme, doc: "Success." },
1090
+ {
1091
+ name: "warn",
1092
+ tier: "semantic",
1093
+ type: "color",
1094
+ group: "Status",
1095
+ source: theme,
1096
+ doc: "Warning.",
1097
+ deprecated: ["--ku-warn"]
1098
+ },
1099
+ {
1100
+ name: "danger",
1101
+ tier: "semantic",
1102
+ type: "color",
1103
+ group: "Status",
1104
+ source: theme,
1105
+ doc: "Error, destructive. Put text on danger-soft rather than bare bg.",
1106
+ deprecated: ["--k-critical", "--ku-critical"]
1107
+ },
1108
+ {
1109
+ name: "info",
1110
+ tier: "semantic",
1111
+ type: "color",
1112
+ group: "Status",
1113
+ source: theme,
1114
+ doc: "Informational."
1115
+ },
1116
+ {
1117
+ name: "ok-soft",
1118
+ tier: "semantic",
1119
+ type: "color",
1120
+ group: "Status",
1121
+ source: css("color-mix(in oklch,var(--k-ok) 15%,transparent)"),
1122
+ doc: "Success tint."
1123
+ },
1124
+ {
1125
+ name: "warn-soft",
1126
+ tier: "semantic",
1127
+ type: "color",
1128
+ group: "Status",
1129
+ source: css("color-mix(in oklch,var(--k-warn) 15%,transparent)"),
1130
+ doc: "Warning tint."
1131
+ },
1132
+ {
1133
+ name: "danger-soft",
1134
+ tier: "semantic",
1135
+ type: "color",
1136
+ group: "Status",
1137
+ source: css("color-mix(in oklch,var(--k-danger) 15%,transparent)"),
1138
+ doc: "Danger tint."
1139
+ },
1140
+ {
1141
+ name: "info-soft",
1142
+ tier: "semantic",
1143
+ type: "color",
1144
+ group: "Status",
1145
+ source: css("color-mix(in oklch,var(--k-info) 15%,transparent)"),
1146
+ doc: "Info tint."
1147
+ },
1148
+ {
1149
+ name: "focus",
1150
+ tier: "semantic",
1151
+ type: "color",
1152
+ group: "Interaction",
1153
+ source: css("var(--k-accent)"),
1154
+ doc: "Focus ring colour (drawn as a 2px bg gap, then 2px of focus)."
1155
+ },
1156
+ {
1157
+ name: "selection",
1158
+ tier: "semantic",
1159
+ type: "color",
1160
+ group: "Interaction",
1161
+ source: css("color-mix(in oklch,var(--k-accent) 24%,transparent)"),
1162
+ doc: "Selected rows and ranges.",
1163
+ deprecated: ["--k-ui-select", "--ku-select"]
1164
+ },
1165
+ {
1166
+ name: "scrim",
1167
+ tier: "semantic",
1168
+ type: "color",
1169
+ group: "Interaction",
1170
+ source: theme,
1171
+ doc: "Dimming behind modal layers."
1172
+ },
1173
+ {
1174
+ name: "diff-add",
1175
+ tier: "semantic",
1176
+ type: "color",
1177
+ group: "Data",
1178
+ source: css("var(--k-ok)"),
1179
+ doc: "Added lines; line and word tints derive privately (12% / 38%)."
1180
+ },
1181
+ {
1182
+ name: "diff-del",
1183
+ tier: "semantic",
1184
+ type: "color",
1185
+ group: "Data",
1186
+ source: css("var(--k-danger)"),
1187
+ doc: "Deleted lines."
1188
+ },
1189
+ {
1190
+ name: "diff-mod",
1191
+ tier: "semantic",
1192
+ type: "color",
1193
+ group: "Data",
1194
+ source: css("var(--k-warn)"),
1195
+ doc: "Modified lines."
1196
+ },
1197
+ {
1198
+ name: "series-1",
1199
+ tier: "semantic",
1200
+ type: "color",
1201
+ group: "Data",
1202
+ source: theme,
1203
+ doc: "Chart series 1."
1204
+ },
1205
+ {
1206
+ name: "series-2",
1207
+ tier: "semantic",
1208
+ type: "color",
1209
+ group: "Data",
1210
+ source: theme,
1211
+ doc: "Chart series 2."
1212
+ },
1213
+ {
1214
+ name: "series-3",
1215
+ tier: "semantic",
1216
+ type: "color",
1217
+ group: "Data",
1218
+ source: theme,
1219
+ doc: "Chart series 3."
1220
+ },
1221
+ {
1222
+ name: "series-4",
1223
+ tier: "semantic",
1224
+ type: "color",
1225
+ group: "Data",
1226
+ source: theme,
1227
+ doc: "Chart series 4."
1228
+ },
1229
+ {
1230
+ name: "series-5",
1231
+ tier: "semantic",
1232
+ type: "color",
1233
+ group: "Data",
1234
+ source: theme,
1235
+ doc: "Chart series 5."
1236
+ },
1237
+ {
1238
+ name: "series-6",
1239
+ tier: "semantic",
1240
+ type: "color",
1241
+ group: "Data",
1242
+ source: theme,
1243
+ doc: "Chart series 6."
1244
+ },
1245
+ {
1246
+ name: "radius-panel",
1247
+ tier: "semantic",
1248
+ type: "length",
1249
+ group: "Shape",
1250
+ source: css("calc(var(--k-radius) + var(--k-unit))"),
1251
+ doc: "Panel and card radius, concentric with controls.",
1252
+ deprecated: ["--k-panel-radius", "--ku-panel-radius"]
1253
+ },
1254
+ {
1255
+ name: "round",
1256
+ tier: "semantic",
1257
+ type: "length",
1258
+ group: "Shape",
1259
+ source: css("calc(var(--k-radius) * 999)"),
1260
+ doc: "Capsule radius that squares when --k-radius is 0. Use instead of 999px."
1261
+ },
1262
+ {
1263
+ name: "unit",
1264
+ tier: "semantic",
1265
+ type: "length",
1266
+ group: "Size",
1267
+ source: value("4px"),
1268
+ doc: "The spacing unit."
1269
+ },
1270
+ {
1271
+ name: "row",
1272
+ tier: "semantic",
1273
+ type: "length",
1274
+ group: "Size",
1275
+ source: css("round(calc(32px * var(--k-density)),2px)"),
1276
+ doc: "Row height.",
1277
+ deprecated: ["--ku-row"]
1278
+ },
1279
+ {
1280
+ name: "width",
1281
+ tier: "semantic",
1282
+ type: "length",
1283
+ group: "Size",
1284
+ source: value("288px"),
1285
+ doc: "Panel width."
1286
+ },
1287
+ {
1288
+ name: "font-size",
1289
+ tier: "semantic",
1290
+ type: "length",
1291
+ group: "Type",
1292
+ source: css("round(calc(12px * (1 + (var(--k-density) - 1) * .5)),1px)"),
1293
+ doc: "Body size; a 5-step scale derives privately.",
1294
+ deprecated: ["--ku-font-size"]
1295
+ },
1296
+ {
1297
+ name: "value-font",
1298
+ tier: "semantic",
1299
+ type: "font",
1300
+ group: "Type",
1301
+ source: css("var(--k-font)"),
1302
+ doc: "Font for readouts and values (labPreset: mono).",
1303
+ deprecated: ["--ku-value-font"]
1304
+ },
1305
+ {
1306
+ name: "shadow-raised",
1307
+ tier: "semantic",
1308
+ type: "shadow",
1309
+ group: "Material",
1310
+ source: theme,
1311
+ doc: "Small lift for raised controls.",
1312
+ deprecated: ["--k-lift-shadow"]
1313
+ },
1314
+ {
1315
+ name: "shadow-overlay",
1316
+ tier: "semantic",
1317
+ type: "shadow",
1318
+ group: "Material",
1319
+ source: theme,
1320
+ doc: "Floating panels, menus, popovers.",
1321
+ deprecated: ["--k-shadow", "--ku-shadow"]
1322
+ },
1323
+ {
1324
+ name: "glass",
1325
+ tier: "semantic",
1326
+ type: "number",
1327
+ group: "Material",
1328
+ source: theme,
1329
+ doc: "Backdrop glass amount (0 = opaque)."
1330
+ },
1331
+ {
1332
+ name: "glow",
1333
+ tier: "semantic",
1334
+ type: "number",
1335
+ group: "Material",
1336
+ source: theme,
1337
+ doc: "Specular glow amount."
1338
+ },
1339
+ {
1340
+ name: "rim",
1341
+ tier: "semantic",
1342
+ type: "color",
1343
+ group: "Material",
1344
+ source: theme,
1345
+ doc: "Top-edge highlight hairline.",
1346
+ deprecated: ["--ku-rim"]
1347
+ },
1348
+ {
1349
+ name: "spring",
1350
+ tier: "semantic",
1351
+ type: "spring",
1352
+ group: "Motion",
1353
+ source: value("0.3 0"),
1354
+ doc: "Default spring as `duration bounce` (the motion module's `default`)."
1355
+ },
1356
+ {
1357
+ name: "hover-in",
1358
+ tier: "semantic",
1359
+ type: "number",
1360
+ group: "Motion",
1361
+ source: value("0"),
1362
+ doc: "Hover wash fade-in, unitless milliseconds.",
1363
+ deprecated: ["--ku-hover-in"]
1364
+ },
1365
+ {
1366
+ name: "hover-out",
1367
+ tier: "semantic",
1368
+ type: "number",
1369
+ group: "Motion",
1370
+ source: value("120"),
1371
+ doc: "Hover wash fade-out, unitless milliseconds.",
1372
+ deprecated: ["--ku-hover-out"]
1373
+ },
1374
+ {
1375
+ name: "z",
1376
+ tier: "semantic",
1377
+ type: "integer",
1378
+ group: "Motion",
1379
+ source: value("2147480000"),
1380
+ doc: "Base of knobs' stacking ladder; layers add small offsets."
1381
+ },
1382
+ {
1383
+ name: "slider-track",
1384
+ tier: "hook",
1385
+ type: "color",
1386
+ group: "Hooks",
1387
+ source: css("var(--k-fill)"),
1388
+ doc: "Slider track."
1389
+ },
1390
+ {
1391
+ name: "slider-fill",
1392
+ tier: "hook",
1393
+ type: "color",
1394
+ group: "Hooks",
1395
+ source: css("color-mix(in oklch,var(--k-accent) 20%,var(--k-fill-selected))"),
1396
+ doc: "Slider value fill.",
1397
+ deprecated: ["--k-fill-rest"]
1398
+ },
1399
+ {
1400
+ name: "slider-handle",
1401
+ tier: "hook",
1402
+ type: "color",
1403
+ group: "Hooks",
1404
+ source: css("var(--k-accent)"),
1405
+ doc: "Slider handle and range thumbs.",
1406
+ deprecated: ["--k-handle"]
1407
+ },
1408
+ {
1409
+ name: "toggle-thumb-off",
1410
+ tier: "hook",
1411
+ type: "color",
1412
+ group: "Hooks",
1413
+ source: css("#ffffff"),
1414
+ doc: "A switch's thumb while off, and the ring around colour and gradient thumbs.",
1415
+ deprecated: ["--k-thumb"]
1416
+ },
1417
+ {
1418
+ name: "toggle-track",
1419
+ tier: "hook",
1420
+ type: "color",
1421
+ group: "Hooks",
1422
+ source: css("var(--k-fill-selected)"),
1423
+ doc: "Toggle track, off."
1424
+ },
1425
+ {
1426
+ name: "toggle-track-on",
1427
+ tier: "hook",
1428
+ type: "color",
1429
+ group: "Hooks",
1430
+ source: css("var(--k-accent)"),
1431
+ doc: "Toggle track, on."
1432
+ },
1433
+ {
1434
+ name: "toggle-thumb",
1435
+ tier: "hook",
1436
+ type: "color",
1437
+ group: "Hooks",
1438
+ source: css("var(--k-on-accent)"),
1439
+ doc: "Toggle thumb."
1440
+ },
1441
+ {
1442
+ name: "segmented-track",
1443
+ tier: "hook",
1444
+ type: "color",
1445
+ group: "Hooks",
1446
+ source: css("var(--k-bg-inset)"),
1447
+ doc: "Segmented control background.",
1448
+ deprecated: ["--k-seg-bg", "--ku-seg-bg"]
1449
+ },
1450
+ {
1451
+ name: "segmented-active",
1452
+ tier: "hook",
1453
+ type: "color",
1454
+ group: "Hooks",
1455
+ source: css("var(--k-bg-raised)"),
1456
+ doc: "Active segment.",
1457
+ deprecated: ["--k-seg-active"]
1458
+ },
1459
+ {
1460
+ name: "timeline-playhead",
1461
+ tier: "hook",
1462
+ type: "color",
1463
+ group: "Hooks",
1464
+ source: css("var(--k-accent)"),
1465
+ doc: "Timeline playhead."
1466
+ },
1467
+ {
1468
+ name: "split-gutter",
1469
+ tier: "hook",
1470
+ type: "color",
1471
+ group: "Hooks",
1472
+ source: css("var(--k-border-subtle)"),
1473
+ doc: "Split pane divider.",
1474
+ deprecated: ["--k-ui-divider", "--ku-divider"]
1475
+ },
1476
+ {
1477
+ name: "compare-divider",
1478
+ tier: "hook",
1479
+ type: "color",
1480
+ group: "Hooks",
1481
+ source: css("var(--k-fg)"),
1482
+ doc: "Before/after divider line.",
1483
+ deprecated: ["--k-compare-line"]
1484
+ },
1485
+ {
1486
+ name: "compare-stage",
1487
+ tier: "hook",
1488
+ type: "color",
1489
+ group: "Hooks",
1490
+ source: css("var(--k-fill)"),
1491
+ doc: "Compare stage background."
1492
+ },
1493
+ {
1494
+ name: "activity-rail",
1495
+ tier: "hook",
1496
+ type: "color",
1497
+ group: "Hooks",
1498
+ source: css("var(--k-border-strong)"),
1499
+ doc: "Activity rail line.",
1500
+ deprecated: ["--k-activity-line"]
1501
+ },
1502
+ {
1503
+ name: "picker-card",
1504
+ tier: "hook",
1505
+ type: "color",
1506
+ group: "Hooks",
1507
+ source: css("var(--k-fill)"),
1508
+ doc: "Picker card."
1509
+ },
1510
+ {
1511
+ name: "pane-bg",
1512
+ tier: "hook",
1513
+ type: "color",
1514
+ group: "Hooks",
1515
+ source: css("var(--k-bg)"),
1516
+ doc: "knobs/ui pane card.",
1517
+ deprecated: ["--k-ui-pane", "--ku-pane-bg"]
1518
+ },
1519
+ {
1520
+ name: "button-bg",
1521
+ tier: "hook",
1522
+ type: "color",
1523
+ group: "Hooks",
1524
+ source: css("var(--k-fill)"),
1525
+ doc: "Button fill."
1526
+ },
1527
+ {
1528
+ name: "button-border",
1529
+ tier: "hook",
1530
+ type: "color",
1531
+ group: "Hooks",
1532
+ source: css("transparent"),
1533
+ doc: "Button border.",
1534
+ deprecated: ["--k-button-line"]
1535
+ },
1536
+ {
1537
+ name: "button-fg",
1538
+ tier: "hook",
1539
+ type: "color",
1540
+ group: "Hooks",
1541
+ source: css("var(--k-fg)"),
1542
+ doc: "Button text.",
1543
+ deprecated: ["--k-button-color"]
1544
+ },
1545
+ {
1546
+ name: "row-hover",
1547
+ tier: "hook",
1548
+ type: "color",
1549
+ group: "Hooks",
1550
+ source: css("color-mix(in oklch,var(--k-fill) 50%,transparent)"),
1551
+ doc: "Row hover wash."
1552
+ },
1553
+ {
1554
+ name: "group-label",
1555
+ tier: "hook",
1556
+ type: "color",
1557
+ group: "Hooks",
1558
+ source: css("var(--k-fg-3)"),
1559
+ doc: "Folder and group headings.",
1560
+ deprecated: ["--k-group-ink", "--k-group-color"]
1561
+ },
1562
+ {
1563
+ name: "modified",
1564
+ tier: "hook",
1565
+ type: "color",
1566
+ group: "Hooks",
1567
+ source: css("var(--k-fg-3)"),
1568
+ doc: "Marker for values changed from their default."
1569
+ },
1570
+ {
1571
+ name: "tray-pad",
1572
+ tier: "private",
1573
+ type: "length",
1574
+ group: "Private",
1575
+ source: css("calc(var(--k-unit) * .5)"),
1576
+ doc: "Padding inside a tray around its controls.",
1577
+ deprecated: ["--k-tray-pad"]
1578
+ },
1579
+ {
1580
+ name: "pad",
1581
+ tier: "private",
1582
+ type: "length",
1583
+ group: "Private",
1584
+ source: css("round(calc(10px * var(--k-density)),2px)"),
1585
+ doc: "Panel padding.",
1586
+ deprecated: ["--k-pad"]
1587
+ },
1588
+ {
1589
+ name: "inset",
1590
+ tier: "private",
1591
+ type: "length",
1592
+ group: "Private",
1593
+ source: css("var(--_k-pad)"),
1594
+ doc: "Row content inset.",
1595
+ deprecated: ["--k-inset", "--ku-inset"]
1596
+ },
1597
+ {
1598
+ name: "gap",
1599
+ tier: "private",
1600
+ type: "length",
1601
+ group: "Private",
1602
+ source: css("round(calc(var(--k-unit) * (1 + (var(--k-density) - 1) * 2.5)),1px)"),
1603
+ doc: "Gap between rows.",
1604
+ deprecated: ["--k-gap"]
1605
+ },
1606
+ {
1607
+ name: "radius-md",
1608
+ tier: "private",
1609
+ type: "length",
1610
+ group: "Private",
1611
+ source: css("max(0px,calc(var(--k-radius) - var(--_k-tray-pad)))"),
1612
+ doc: "Concentric radius one tray in.",
1613
+ deprecated: ["--k-radius-md"]
1614
+ },
1615
+ {
1616
+ name: "radius-sm",
1617
+ tier: "private",
1618
+ type: "length",
1619
+ group: "Private",
1620
+ source: css("max(0px,calc(var(--k-radius) - var(--_k-tray-pad) * 2))"),
1621
+ doc: "Concentric radius two trays in.",
1622
+ deprecated: ["--k-radius-sm"]
1623
+ },
1624
+ {
1625
+ name: "control-h",
1626
+ tier: "private",
1627
+ type: "length",
1628
+ group: "Private",
1629
+ source: css("calc(var(--k-row) - var(--k-unit) * 2)"),
1630
+ doc: "Control height inside a row.",
1631
+ deprecated: ["--k-control-h", "--ku-control-h"]
1632
+ },
1633
+ {
1634
+ name: "value-size",
1635
+ tier: "private",
1636
+ type: "length",
1637
+ group: "Private",
1638
+ source: css("calc(var(--k-font-size) - .5px)"),
1639
+ doc: "Readout size.",
1640
+ deprecated: ["--k-value-size", "--ku-value-size"]
1641
+ },
1642
+ {
1643
+ name: "text-title",
1644
+ tier: "private",
1645
+ type: "length",
1646
+ group: "Private",
1647
+ source: css("calc(var(--k-font-size) + 1px)"),
1648
+ doc: "Type scale: titles.",
1649
+ deprecated: ["--k-text-title"]
1650
+ },
1651
+ {
1652
+ name: "text-body",
1653
+ tier: "private",
1654
+ type: "length",
1655
+ group: "Private",
1656
+ source: css("var(--k-font-size)"),
1657
+ doc: "Type scale: body.",
1658
+ deprecated: ["--k-text-body"]
1659
+ },
1660
+ {
1661
+ name: "text-control",
1662
+ tier: "private",
1663
+ type: "length",
1664
+ group: "Private",
1665
+ source: css("calc(var(--k-font-size) - .5px)"),
1666
+ doc: "Type scale: controls.",
1667
+ deprecated: ["--k-text-control"]
1668
+ },
1669
+ {
1670
+ name: "text-meta",
1671
+ tier: "private",
1672
+ type: "length",
1673
+ group: "Private",
1674
+ source: css("calc(var(--k-font-size) - 1px)"),
1675
+ doc: "Type scale: metadata.",
1676
+ deprecated: ["--k-text-meta", "--ku-text-meta"]
1677
+ },
1678
+ {
1679
+ name: "text-cap",
1680
+ tier: "private",
1681
+ type: "length",
1682
+ group: "Private",
1683
+ source: css("calc(var(--k-font-size) - 2px)"),
1684
+ doc: "Type scale: caps and captions.",
1685
+ deprecated: ["--k-text-cap"]
1686
+ },
1687
+ {
1688
+ name: "weight",
1689
+ tier: "private",
1690
+ type: "number",
1691
+ group: "Private",
1692
+ source: value("400"),
1693
+ doc: "Body weight.",
1694
+ deprecated: ["--k-font-weight", "--ku-font-weight"]
1695
+ },
1696
+ {
1697
+ name: "weight-label",
1698
+ tier: "private",
1699
+ type: "number",
1700
+ group: "Private",
1701
+ source: value("500"),
1702
+ doc: "Label weight.",
1703
+ deprecated: ["--k-label-weight", "--ku-label-weight"]
1704
+ },
1705
+ {
1706
+ name: "weight-title",
1707
+ tier: "private",
1708
+ type: "number",
1709
+ group: "Private",
1710
+ source: value("600"),
1711
+ doc: "Title weight.",
1712
+ deprecated: ["--k-title-weight", "--ku-title-weight"]
1713
+ },
1714
+ {
1715
+ name: "focus-ring",
1716
+ tier: "private",
1717
+ type: "shadow",
1718
+ group: "Private",
1719
+ source: css("0 0 0 2px var(--k-bg),0 0 0 4px var(--k-focus)"),
1720
+ doc: "Two-layer focus ring: a bg gap, then the focus colour."
1721
+ },
1722
+ {
1723
+ name: "diff-add-line",
1724
+ tier: "private",
1725
+ type: "color",
1726
+ group: "Private",
1727
+ source: css("color-mix(in oklch,var(--k-diff-add) 12%,transparent)"),
1728
+ doc: "Added line tint."
1729
+ },
1730
+ {
1731
+ name: "diff-add-word",
1732
+ tier: "private",
1733
+ type: "color",
1734
+ group: "Private",
1735
+ source: css("color-mix(in oklch,var(--k-diff-add) 38%,transparent)"),
1736
+ doc: "Added word tint."
1737
+ },
1738
+ {
1739
+ name: "diff-del-line",
1740
+ tier: "private",
1741
+ type: "color",
1742
+ group: "Private",
1743
+ source: css("color-mix(in oklch,var(--k-diff-del) 12%,transparent)"),
1744
+ doc: "Deleted line tint."
1745
+ },
1746
+ {
1747
+ name: "diff-del-word",
1748
+ tier: "private",
1749
+ type: "color",
1750
+ group: "Private",
1751
+ source: css("color-mix(in oklch,var(--k-diff-del) 38%,transparent)"),
1752
+ doc: "Deleted word tint."
1753
+ },
1754
+ {
1755
+ name: "diff-mod-line",
1756
+ tier: "private",
1757
+ type: "color",
1758
+ group: "Private",
1759
+ source: css("color-mix(in oklch,var(--k-diff-mod) 12%,transparent)"),
1760
+ doc: "Modified line tint."
1761
+ },
1762
+ {
1763
+ name: "diff-mod-word",
1764
+ tier: "private",
1765
+ type: "color",
1766
+ group: "Private",
1767
+ source: css("color-mix(in oklch,var(--k-diff-mod) 38%,transparent)"),
1768
+ doc: "Modified word tint."
1769
+ }
1770
+ ], TOKEN_BY_NAME = new Map(TOKENS.map((t) => [t.name, t])), cssName = (t) => `${t.tier === "private" ? "--_k-" : "--k-"}${t.name}`, PROPERTY_TO_NAME = new Map(TOKENS.map((t) => [cssName(t), t.name])), tokenForProperty = (property) => PROPERTY_TO_NAME.get(property), DEPRECATED = new Map(TOKENS.flatMap((t) => (t.deprecated ?? []).map((old) => [old, cssName(t)])));
1771
+
1772
+ // src/tokens/css.ts
1773
+ function pair(def, dark, light) {
1774
+ if (dark === void 0 && light === void 0)
1775
+ return;
1776
+ if (dark === void 0 || light === void 0 || dark === light || def.type !== "color")
1777
+ return dark ?? light;
1778
+ return `light-dark(${light},${dark})`;
1779
+ }
1780
+ function declaredValue(theme, def) {
1781
+ let name = def.name, dark = theme.declared.dark[name], light = theme.declared.light[name];
1782
+ if (def.type === "color" && dark === void 0 !== (light === void 0))
1783
+ return pair(def, dark ?? theme.dark[name], light ?? theme.light[name]);
1784
+ return pair(def, dark, light);
1785
+ }
1786
+ var SCHEMES = [
1787
+ [":where(.knobs-root)", "light dark"],
1788
+ [
1789
+ ':where(.dark,.dark-theme,[data-theme="dark"],[data-appearance="dark"],[data-knobs-theme="dark"]) :where(.knobs-root)',
1790
+ "dark"
1791
+ ],
1792
+ [
1793
+ ':where(.light,.light-theme,[data-theme="light"],[data-appearance="light"],[data-knobs-theme="light"]) :where(.knobs-root)',
1794
+ "light"
1795
+ ],
1796
+ [":where(.knobs-root) :where(.knobs-root:not([data-appearance]))", "inherit"],
1797
+ [':where(.knobs-root[data-appearance="dark"])', "dark"],
1798
+ [':where(.knobs-root[data-appearance="light"])', "light"],
1799
+ [':where(.knobs-root[data-appearance="system"])', "light dark"],
1800
+ [':where(.knobs-root[data-appearance="inherit"])', "inherit"]
1801
+ ], APPEARANCE_CSS = SCHEMES.map(([selector, scheme]) => {
1802
+ let rule = `${selector}{color-scheme:${scheme};--_k-light:${scheme === "light" ? "1" : scheme === "inherit" ? "inherit" : "0"}}`;
1803
+ return scheme === "light dark" ? `${rule}
1804
+ @media(prefers-color-scheme:light){${selector}{--_k-light:1}}` : rule;
1805
+ }).join(`
1806
+ `), privately = (css) => css.replace(/var\(--k-([a-z0-9-]+)/g, (m, name) => tokenForProperty(`--k-${name}`) ? `var(--_k-${name}` : m);
1807
+ function resolver(def) {
1808
+ let reads = [...def.deprecated ?? []];
1809
+ if (def.tier !== "private")
1810
+ reads.push(cssName(def));
1811
+ let source = def.source, out = ("css" in source ? privately(source.css) : ("value" in source) && def.tier === "private" ? source.value : void 0) ?? "";
1812
+ for (let i = reads.length - 1;i >= 0; i--)
1813
+ out = out === "" ? `var(${reads[i]})` : `var(${reads[i]},${out})`;
1814
+ return def.resolve ? privately(def.resolve).replaceAll("$", out) : out;
1815
+ }
1816
+ function tokensCss(theme) {
1817
+ let root = [], resolved = [];
1818
+ for (let def of TOKENS) {
1819
+ let source = def.source, own = declaredValue(theme, def) ?? ("from" in source ? "" : ("value" in source) && def.tier !== "private" ? source.value : void 0);
1820
+ if (own !== void 0 && def.tier !== "private")
1821
+ root.push(`${cssName(def)}:${own}`);
1822
+ resolved.push(`--_k-${def.name}:${resolver(def)}`);
1823
+ }
1824
+ return `@layer knobs.tokens{
1825
+ :where(:root,:host){${root.join(";")}}
1826
+ :where(.knobs-root){${resolved.join(";")}}
1827
+ ${APPEARANCE_CSS}
1828
+ }`;
1829
+ }
1830
+ function themeCss(theme, selector) {
1831
+ let decls = [];
1832
+ for (let def of TOKENS) {
1833
+ let own = declaredValue(theme, def);
1834
+ if (own !== void 0)
1835
+ decls.push(`${cssName(def)}:${own}`);
1836
+ }
1837
+ return `@layer knobs.tokens{${selector}{${decls.join(";")}}}`;
1838
+ }
1839
+
1840
+ // src/tokens/evaluate.ts
1841
+ function splitTop(s) {
1842
+ let out = [], depth = 0, start = 0;
1843
+ for (let i = 0;i < s.length; i++) {
1844
+ let ch = s[i];
1845
+ if (ch === "(")
1846
+ depth++;
1847
+ else if (ch === ")")
1848
+ depth--;
1849
+ else if (ch === "," && depth === 0)
1850
+ out.push(s.slice(start, i).trim()), start = i + 1;
1851
+ }
1852
+ return out.push(s.slice(start).trim()), out;
1853
+ }
1854
+ var call = (s, fn) => s.startsWith(`${fn}(`) && s.endsWith(")") ? s.slice(fn.length + 1, -1) : void 0;
1855
+ function evaluate(input, lookup) {
1856
+ let s = input.trim(), v = call(s, "var");
1857
+ if (v !== void 0) {
1858
+ let [name, ...fallback] = splitTop(v), value = lookup(name);
1859
+ if (value !== void 0)
1860
+ return evaluate(value, lookup);
1861
+ if (fallback.length)
1862
+ return evaluate(fallback.join(","), lookup);
1863
+ throw Error(`Unresolved ${name}`);
1864
+ }
1865
+ let mix = call(s, "color-mix");
1866
+ if (mix !== void 0)
1867
+ return colorMix(mix, lookup);
1868
+ return normalize(s);
1869
+ }
1870
+ function percent(s, lookup) {
1871
+ let c = call(s, "calc");
1872
+ if (c === void 0)
1873
+ return Number.parseFloat(s) / 100;
1874
+ let [a, b] = c.split("*").map((x) => x.trim()), num = (x) => {
1875
+ let inner = call(x, "var");
1876
+ if (inner !== void 0)
1877
+ return Number.parseFloat(lookup(splitTop(inner)[0]) ?? Number.NaN.toString());
1878
+ return x.endsWith("%") ? Number.parseFloat(x) / 100 : Number.parseFloat(x);
1879
+ }, out = num(a) * num(b);
1880
+ if (!Number.isFinite(out))
1881
+ throw Error(`Bad percentage: ${s}`);
1882
+ return out;
1883
+ }
1884
+ function stop(s, lookup) {
1885
+ let m = /^(.*?)\s+((?:calc\(.*\))|(?:[\d.]+%))$/.exec(s);
1886
+ if (!m)
1887
+ return { color: evaluate(s, lookup) };
1888
+ return { color: evaluate(m[1], lookup), p: percent(m[2], lookup) };
1889
+ }
1890
+ function colorMix(args, lookup) {
1891
+ let [space, a, b] = splitTop(args);
1892
+ if (space !== "in oklch")
1893
+ throw Error(`Only color-mix(in oklch, …) is supported, got ${space}`);
1894
+ let x = stop(a, lookup), y = stop(b, lookup), p1 = x.p ?? (y.p === void 0 ? 0.5 : 1 - y.p), p2 = y.p ?? 1 - p1, sum = p1 + p2, scale = sum < 1 ? sum : 1;
1895
+ p1 /= sum, p2 /= sum;
1896
+ let ca = linearToOklch(parseColor(x.color)), cb = linearToOklch(parseColor(y.color)), a1 = ca.alpha ?? 1, a2 = cb.alpha ?? 1, alpha = a1 * p1 + a2 * p2;
1897
+ if (alpha <= 0)
1898
+ return "#00000000";
1899
+ let powerless = (c, alpha) => c.c < 0.0002 || alpha === 0, h1 = powerless(ca, a1) ? cb.h : ca.h, dh = (powerless(cb, a2) ? h1 : cb.h) - h1;
1900
+ if (dh > 180)
1901
+ dh -= 360;
1902
+ if (dh < -180)
1903
+ dh += 360;
1904
+ let pre = (u, v) => (u * a1 * p1 + v * a2 * p2) / alpha, rgb = oklchToLinear({
1905
+ l: pre(ca.l, cb.l),
1906
+ c: pre(ca.c, cb.c),
1907
+ h: (h1 + dh * p2 + 360) % 360
1908
+ });
1909
+ return formatHex([rgb[0], rgb[1], rgb[2], alpha * scale]);
1910
+ }
1911
+
1912
+ // src/themes/define.ts
1913
+ var DEFAULT_SANS = 'system-ui,-apple-system,"SF Pro Text",sans-serif', DEFAULT_MONO = '"SF Mono",SFMono-Regular,ui-monospace,Menlo,monospace', BASE = {
1914
+ gray: { hue: 0, chroma: 0 },
1915
+ accent: "#ffffff",
1916
+ contrast: 50,
1917
+ radius: 8,
1918
+ density: "default",
1919
+ material: "solid",
1920
+ font: { sans: DEFAULT_SANS, mono: DEFAULT_MONO },
1921
+ tokens: { dark: {}, light: {} }
1922
+ }, DENSITY = { compact: 0.875, default: 1, comfortable: 1.1875 }, SURFACES = {
1923
+ dark: { "bg-page": 14.5, "bg-inset": 19.6, bg: 22.6, "bg-raised": 25.7, "bg-overlay": 28.1 },
1924
+ light: { "bg-page": 92.6, "bg-inset": 94.6, bg: 97.1, "bg-raised": 100, "bg-overlay": 100 }
1925
+ }, INKS = {
1926
+ dark: { fg: 99.7, "fg-2": 76.7, "fg-3": 48.4, "fg-4": 31.9, "border-strong": 15.8 },
1927
+ light: { fg: 98.35, "fg-2": 78, "fg-3": 50, "fg-4": 34, "border-strong": 17 }
1928
+ }, APCA_BUDGET = {
1929
+ fg: 90,
1930
+ "fg-2": 75,
1931
+ "fg-3": 45,
1932
+ "fg-4": 30,
1933
+ "accent-fg": 60,
1934
+ "border-strong": 15
1935
+ }, TINT = { surface: { dark: 0.5, light: 0.7 }, fg: 1.35, ink: 1.5, border: 1.25 }, STATUS = {
1936
+ dark: {
1937
+ ok: [78, 0.15, 155],
1938
+ warn: [83, 0.14, 80],
1939
+ danger: [70, 0.18, 25],
1940
+ info: [75, 0.13, 240]
1941
+ },
1942
+ light: {
1943
+ ok: [52, 0.14, 150],
1944
+ warn: [60, 0.14, 65],
1945
+ danger: [55, 0.2, 27],
1946
+ info: [53, 0.15, 245]
1947
+ }
1948
+ }, SERIES_HUES = [250, 155, 75, 25, 305, 195], SERIES = { dark: { l: 74, c: 0.12 }, light: { l: 56, c: 0.14 } }, contrastMultiplier = (contrast) => 0.5 + Math.min(100, Math.max(0, contrast)) / 100;
1949
+ function fontStack(family, fallback) {
1950
+ if (family.includes(","))
1951
+ return family;
1952
+ let quoted = /\s/.test(family) && !/^["']/.test(family) ? `"${family}"` : family;
1953
+ return family === fallback ? family : `${quoted},${fallback}`;
1954
+ }
1955
+ function mergeInputs(parent, spec) {
1956
+ return {
1957
+ gray: { ...parent.gray, ...spec.gray },
1958
+ accent: spec.accent ?? parent.accent,
1959
+ contrast: spec.contrast ?? parent.contrast,
1960
+ radius: spec.radius ?? parent.radius,
1961
+ density: spec.density ?? parent.density,
1962
+ material: spec.material ?? parent.material,
1963
+ font: {
1964
+ sans: spec.font?.sans ? fontStack(spec.font.sans, DEFAULT_SANS) : parent.font.sans,
1965
+ mono: spec.font?.mono ? fontStack(spec.font.mono, DEFAULT_MONO) : parent.font.mono
1966
+ },
1967
+ tokens: {
1968
+ dark: { ...parent.tokens.dark, ...spec.tokens?.dark },
1969
+ light: { ...parent.tokens.light, ...spec.tokens?.light }
1970
+ }
1971
+ };
1972
+ }
1973
+ function meet(l, floor, bg, away, make) {
1974
+ let x = l;
1975
+ while (apca(make(x), bg) < floor + 0.5 && x >= 0 && x <= 100)
1976
+ x += away * 0.25;
1977
+ return make(Math.min(100, Math.max(0, x)));
1978
+ }
1979
+ function solve(target, bg, away, make) {
1980
+ let near = toOklch(bg).l * 100, far = away > 0 ? 100 : 0;
1981
+ if (apca(make(far), bg) <= target)
1982
+ return far;
1983
+ for (let i = 0;i < 30; i++) {
1984
+ let mid = (near + far) / 2;
1985
+ if (apca(make(mid), bg) < target)
1986
+ near = mid;
1987
+ else
1988
+ far = mid;
1989
+ }
1990
+ return far;
1991
+ }
1992
+ function accentPair(inputs) {
1993
+ if (typeof inputs.accent !== "string")
1994
+ return { ...inputs.accent };
1995
+ let dark = inputs.accent, o = toOklch(dark), light = o.c < 0.02 ? oklchToHex({ l: 0.227, c: inputs.gray.chroma, h: inputs.gray.hue }) : oklchToHex({ l: Math.min(0.6, Math.max(0.45, o.l - 0.15)), c: o.c * 1.1, h: o.h });
1996
+ return { dark, light };
1997
+ }
1998
+ function generate(inputs, appearance, accent) {
1999
+ let m = contrastMultiplier(inputs.contrast), { hue, chroma } = inputs.gray, neutral = (l, tint) => oklchToHex({ l: l / 100, c: chroma * tint, h: hue }), user = inputs.tokens[appearance], out = {}, surfaces = SURFACES[appearance];
2000
+ for (let [role, l] of Object.entries(surfaces)) {
2001
+ let spread = surfaces.bg + (l - surfaces.bg) * m;
2002
+ out[role] = user[role] ?? neutral(Math.min(100, Math.max(0, spread)), TINT.surface[appearance]);
2003
+ }
2004
+ let bg = out.bg, away = appearance === "dark" ? 1 : -1, inkSpread = 1 + (m - 1) * 0.4;
2005
+ for (let [role, target] of Object.entries(INKS[appearance])) {
2006
+ let tint = role === "fg" ? TINT.fg : role === "border-strong" ? TINT.border : TINT.ink, make = (x) => neutral(x, tint), l = solve(target * inkSpread, bg, away, make);
2007
+ out[role] = meet(l, APCA_BUDGET[role], bg, away, make);
2008
+ }
2009
+ out.accent = accent;
2010
+ let a = toOklch(accent);
2011
+ out["accent-fg"] = meet(a.l * 100, APCA_BUDGET["accent-fg"], bg, away, (x) => oklchToHex({ l: x / 100, c: a.c, h: a.h })), out["on-accent"] = apca("#111111", accent) >= apca("#ffffff", accent) ? "#111111" : "#ffffff";
2012
+ for (let [role, [l, c, h]] of Object.entries(STATUS[appearance]))
2013
+ out[role] = oklchToHex({ l: l / 100, c, h });
2014
+ let s = SERIES[appearance], start = a.c >= 0.04 ? a.h - SERIES_HUES[0] : 0;
2015
+ SERIES_HUES.forEach((h, i) => {
2016
+ out[`series-${i + 1}`] = oklchToHex({ l: s.l / 100, c: s.c, h: (h + start + 360) % 360 });
2017
+ }), out.scrim = appearance === "dark" ? "#00000099" : "#00000040", out.contrast = String(Math.round(m * 1000) / 1000), out.radius = `${inputs.radius}px`, out.density = String(DENSITY[inputs.density]), out.font = inputs.font.sans, out.mono = inputs.font.mono;
2018
+ let material = inputs.material;
2019
+ if (out.glass = material === "glass" ? "0.6" : "0", out.glow = material === "glass" ? "0.5" : "0", out.rim = material === "flat" ? "transparent" : appearance === "dark" ? "#ffffff1a" : "#ffffff99", material === "flat")
2020
+ out["border-subtle"] = over(withAlpha(out.fg, 0.06 * m), bg), out.border = over(withAlpha(out.fg, 0.1 * m), bg);
2021
+ return out;
2022
+ }
2023
+ function shadows(material, borderStrong) {
2024
+ if (material === "flat")
2025
+ return {
2026
+ "shadow-raised": "none",
2027
+ "shadow-overlay": `0 0 0 1px light-dark(${borderStrong.light},${borderStrong.dark})`
2028
+ };
2029
+ return {
2030
+ "shadow-raised": "0 1px 2px light-dark(#0000001f,#00000029)",
2031
+ "shadow-overlay": "0 12px 36px light-dark(#00000024,#00000085),0 1px 2px light-dark(#00000014,#0000004d)"
2032
+ };
2033
+ }
2034
+ function resolve(declared) {
2035
+ let raw = (name) => {
2036
+ let def = TOKEN_BY_NAME.get(name), own = declared[name];
2037
+ if (own !== void 0)
2038
+ return own;
2039
+ let source = def.source;
2040
+ if ("css" in source)
2041
+ return source.css;
2042
+ if ("value" in source)
2043
+ return source.value;
2044
+ throw Error(`Theme does not supply ${name}`);
2045
+ }, lookup = (property) => {
2046
+ let name = tokenForProperty(property);
2047
+ return name ? raw(name) : void 0;
2048
+ }, out = {};
2049
+ for (let t of TOKENS)
2050
+ out[t.name] = t.type === "color" ? evaluate(raw(t.name), lookup) : raw(t.name);
2051
+ return out;
2052
+ }
2053
+ function gpuOf(resolved) {
2054
+ let out = {};
2055
+ for (let t of TOKENS)
2056
+ if (t.type === "color")
2057
+ out[t.name] = parseColor(resolved[t.name]);
2058
+ return out;
2059
+ }
2060
+ function validate(name, inputs) {
2061
+ if (!/^[\w-]+$/.test(name))
2062
+ throw Error(`Invalid theme name: ${name}`);
2063
+ if (name === "dark" || name === "light")
2064
+ throw Error(`Reserved theme name: ${name}`);
2065
+ for (let appearance of ["dark", "light"])
2066
+ for (let key of Object.keys(inputs.tokens[appearance]))
2067
+ if (!TOKEN_BY_NAME.has(key))
2068
+ throw Error(`Unknown token in theme ${name}: ${key}`);
2069
+ }
2070
+ function defineTheme(spec) {
2071
+ let inputs = mergeInputs(spec.extends?.inputs ?? BASE, spec);
2072
+ validate(spec.name, inputs);
2073
+ let accent = accentPair(inputs), generated = {
2074
+ dark: generate(inputs, "dark", accent.dark),
2075
+ light: generate(inputs, "light", accent.light)
2076
+ }, material = shadows(inputs.material, {
2077
+ dark: inputs.tokens.dark["border-strong"] ?? generated.dark["border-strong"],
2078
+ light: inputs.tokens.light["border-strong"] ?? generated.light["border-strong"]
2079
+ }), declared = {
2080
+ dark: { ...generated.dark, ...material, ...inputs.tokens.dark },
2081
+ light: { ...generated.light, ...material, ...inputs.tokens.light }
2082
+ };
2083
+ for (let [key, dark] of Object.entries(declared.dark)) {
2084
+ let def = TOKEN_BY_NAME.get(key), light = declared.light[key];
2085
+ if (def.type !== "color" && light !== void 0 && light !== dark)
2086
+ throw Error(`Theme ${spec.name}: only colours may differ by appearance (${key})`);
2087
+ }
2088
+ let dark = resolve(declared.dark), light = resolve(declared.light), theme = {
2089
+ name: spec.name,
2090
+ inputs,
2091
+ dark,
2092
+ light,
2093
+ declared,
2094
+ gpu: { dark: gpuOf(dark), light: gpuOf(light) },
2095
+ css: (options) => options?.selector ? themeCss(theme, options.selector) : tokensCss(theme)
2096
+ };
2097
+ return theme;
2098
+ }
2099
+
2100
+ // src/themes/knobs.ts
2101
+ var knobs = defineTheme({
2102
+ name: "knobs",
2103
+ gray: { hue: 285, chroma: 0.004 },
2104
+ accent: { dark: "#ffffff", light: "#1c1c1e" },
2105
+ contrast: 50,
2106
+ radius: 8,
2107
+ density: "default",
2108
+ material: "glass"
2109
+ });
2110
+
2111
+ // src/core/glide.ts
2112
+ var COLOR_TOKENS = [
679
2113
  "bg",
680
- "surface",
681
- "surface-hi",
682
- "line",
683
- "line-hi",
684
- "text",
685
- "label",
686
- "dim",
2114
+ "fill",
2115
+ "fill-selected",
2116
+ "border",
2117
+ "border-strong",
2118
+ "fg",
2119
+ "fg-2",
2120
+ "fg-3",
687
2121
  "accent",
688
2122
  "modified",
689
- "seg-bg",
690
- "seg-active",
2123
+ "segmented-track",
2124
+ "segmented-active",
691
2125
  "toggle-track",
692
2126
  "toggle-thumb",
2127
+ "toggle-thumb-off",
2128
+ "slider-handle",
693
2129
  "rim",
694
- "edge",
695
- "page"
696
- ], LENGTH_TOKENS = ["pad", "inset", "row", "gap", "radius", "panel-radius", "font-size"], NUMBER_TOKENS = ["label-weight", "blur", "glow", "glass", "glass-tone"], ANIMATED = [...COLOR_TOKENS, ...LENGTH_TOKENS, ...NUMBER_TOKENS, "width"], TOKEN_TRANSITIONS = ANIMATED.map((t) => `--kt-${t} var(--k-token-t)`).join(","), register = (names, syntax, initial) => names.map((n) => `@property --kt-${n}{syntax:"${syntax}";inherits:false;initial-value:${initial}}`).join(`
697
- `), DRIVERS = `${register(COLOR_TOKENS, "<color>", "transparent")}
2130
+ "border-subtle",
2131
+ "bg-page"
2132
+ ], LENGTH_TOKENS = ["pad", "inset", "row", "gap", "radius", "radius-panel", "font-size"], NUMBER_TOKENS = ["weight-label", "blur", "glow", "glass", "glass-tone"], ANIMATED = [...COLOR_TOKENS, ...LENGTH_TOKENS, ...NUMBER_TOKENS, "width"], TOKEN_TRANSITIONS = ANIMATED.map((t) => `--kt-${t} var(--k-token-t)`).join(","), source = (t) => t === "blur" ? "--k-blur" : `--_k-${t}`, register = (names, syntax, initial) => names.map((n) => `@property --kt-${n}{syntax:"${syntax}";inherits:false;initial-value:${initial}}`).join(`
2133
+ `);
2134
+ var DRIVERS = `${register(COLOR_TOKENS, "<color>", "transparent")}
698
2135
  ${register(LENGTH_TOKENS, "<length>", "0px")}
699
2136
  ${register(NUMBER_TOKENS, "<number>", "0")}
700
2137
  ${register(["width"], "<length-percentage>", "288px")}
701
- .knobs-panel,.knobs-chip,.knobs-toast{${ANIMATED.map((t) => `--kt-${t}:var(--k-${t});--kv-${t}:var(--kt-${t})`).join(";")}}`, aliased = (css) => css.replace(new RegExp(`var\\(--k-(${ANIMATED.join("|")})\\)`, "g"), "var(--kv-$1)"), lightVars = `
702
- --k-bg:#f5f5f7;--k-surface:rgba(0,0,0,calc(.05 * var(--k-contrast)));--k-surface-hi:rgba(0,0,0,calc(.095 * var(--k-contrast)));--k-line:rgba(0,0,0,calc(.1 * var(--k-contrast)));--k-line-hi:rgba(0,0,0,calc(.2 * var(--k-contrast)));
703
- --k-text:rgba(0,0,0,.88);--k-label:rgba(60,60,67,.68);--k-dim:rgba(60,60,67,.5);--k-accent:#1c1c1e;--k-modified:rgba(0,0,0,.42);
704
- --k-seg-bg:rgba(0,0,0,.065);--k-seg-active:#fff;--k-toggle-track:rgba(0,0,0,.14);--k-toggle-thumb:#fff;--k-shadow:0 10px 32px rgba(0,0,0,.14),0 1px 3px rgba(0,0,0,.08);
705
- --k-rim:rgba(255,255,255,.6);--k-edge:rgba(0,0,0,calc(.07 * var(--k-contrast)));--k-glass-tone:1.08;--k-page:#e6e6eb;--k-group-ink:var(--k-dim);
706
- color-scheme:light;`, defaultsCss = `
707
- @property --k-fill{syntax:"<percentage>";inherits:false;initial-value:0%}
2138
+ :where(.knobs-panel,.knobs-chip,.knobs-notice,.knobs-ui){${ANIMATED.map((t) => `--kt-${t}:var(${source(t)});--kv-${t}:var(--kt-${t})`).join(";")};--k-token-t:calc(var(--k-fill-ms) * 1ms) var(--k-fill-ease)}
2139
+ :where(.knobs-ui){transition:${TOKEN_TRANSITIONS}}
2140
+ :root[data-knobs-scrub] :where(.knobs-chip,.knobs-ui){--k-token-t:0s}
2141
+ @media(prefers-reduced-motion:reduce){:where(.knobs-chip,.knobs-ui){--k-token-t:0s}}`, aliased = (css) => css.replace(new RegExp(`var\\(--_k-(${ANIMATED.join("|")})\\)`, "g"), "var(--kv-$1)").replace(/var\(--k-blur\)/g, "var(--kv-blur)");
2142
+
2143
+ // src/core/root.ts
2144
+ var ROOT_CLASS = "knobs-root", extras = `:where(.${ROOT_CLASS}){--_k-shadow-k:calc(var(--k-shadow-strength,calc(.48 - .32 * var(--_k-light,0))) / .48);--_k-glass-tone:var(--k-glass-tone,calc(.5 + .58 * var(--_k-light,0)));--_k-fill-base:var(--k-fill-base,var(--_k-fill-selected));--_k-fill-hover-mix:var(--k-fill-hover-mix,var(--k-fill-rest-mix,20%));--_k-reveal-ease:var(--k-ease,cubic-bezier(.2,.8,.2,1))}`, spring = `:where(:root,:host){--k-fill-ease:${DEFAULT_LINEAR.easing};--k-fill-ms:${DEFAULT_LINEAR.ms}}`, rootCss = `${tokensCss(knobs)}
2145
+ ${extras}
2146
+ ${spring}
2147
+ ${DRIVERS}
2148
+ ${motionCss}`;
2149
+ function injectTokens(doc) {
2150
+ if (doc.querySelector("style[data-knobs-tokens]"))
2151
+ return;
2152
+ let style = doc.createElement("style");
2153
+ style.dataset.knobsTokens = "", style.textContent = rootCss, doc.head.append(style);
2154
+ }
2155
+
2156
+ // src/panel/styles.ts
2157
+ var lead = springEasing(LEAD.omega, LEAD.zeta), trail = springEasing(TRAIL.omega, TRAIL.zeta), LEAD_T = `${lead.ms}ms var(--k-lead)`, TRAIL_T = `calc(${trail.ms}ms * (.6 + .4 * clamp(0, var(--k-blur), 2))) var(--k-trail)`, FILL_T = "calc(var(--k-fill-ms) * 1ms * clamp(var(--k-blur),.1,2)) var(--k-fill-ease)", SLIDE_T = "calc(var(--k-fill-ms) * 1ms) var(--k-fill-ease)", snappy = springLinear(SPRINGS2.snappy), snappyOut = springLinear({ duration: 0.2, bounce: 0 }), BLOOM_IN = `${snappy.ms}ms ${snappy.easing}`, BLOOM_OUT = `${snappyOut.ms}ms ${snappyOut.easing}`, DELAY = "var(--k-delay,0ms)", armed = springLinear(SPRINGS2.default), ARMED_T = `${armed.ms}ms ${armed.easing}`, POINTER_ROW = ".knobs-panel[data-k-row-hover]:not([data-keyboard])", DELAYED = ".knobs-fill,.knobs-handle,.knobs-seg-pill,.knobs-toggle,.knobs-toggle i,.knobs-arm,.knobs-curve,.knobs-swatch,.knobs-strip-thumb,.knobs-pad>i,.knobs-ease-handle,.knobs-range-track,.knobs-range-fill,.knobs-range-thumb,.knobs-dial-hand,.knobs-grad,.knobs-grad-mini,.knobs-grad-mini>i,.knobs-grad-stop,.knobs-graph-pt", GRAD_N = GRADIENT_SAMPLES, gradStops = (at) => Array.from({ length: GRAD_N }, (_, i) => `var(--kgrad-${i}) ${at(i)}`).join(","), GRAD_STRIP = `linear-gradient(to right,${gradStops((i) => `calc(var(--kg-r) + (100% - var(--kg-r) * 2) * ${Number((i / (GRAD_N - 1)).toFixed(5))})`)})`, GRAD_MINI = `linear-gradient(to right,${gradStops((i) => `${Number((i / (GRAD_N - 1) * 100).toFixed(3))}%`)})`, GRAD_PROPS = Array.from({ length: GRAD_N }, (_, i) => `@property --kgrad-${i}{syntax:"<color>";inherits:false;initial-value:transparent}`).join(`
2158
+ `), defaultsCss = `
2159
+ @property --_k-fill-at{syntax:"<percentage>";inherits:false;initial-value:0%}
708
2160
  @property --k-fill-mix{syntax:"<percentage>";inherits:false;initial-value:20%}
709
2161
  @property --k-readout{syntax:"<length>";inherits:true;initial-value:0px}
710
2162
  @property --k-copy{syntax:"<number>";inherits:true;initial-value:1}
@@ -712,7 +2164,6 @@ ${register(["width"], "<length-percentage>", "288px")}
712
2164
  @property --k-check-a{syntax:"<number>";inherits:true;initial-value:0}
713
2165
  @property --k-head-s{syntax:"<number>";inherits:true;initial-value:0}
714
2166
  @property --k-head-v{syntax:"<number>";inherits:true;initial-value:0}
715
- @property --kc-value-size{syntax:"<length>";inherits:true;initial-value:11.5px}
716
2167
  @property --k-armed{syntax:"<number>";inherits:false;initial-value:0}
717
2168
  @property --kr-lo{syntax:"<number>";inherits:true;initial-value:0}
718
2169
  @property --kpt-sel{syntax:"<number>";inherits:false;initial-value:1}
@@ -721,20 +2172,14 @@ ${register(["width"], "<length-percentage>", "288px")}
721
2172
  @property --kr-show-lo{syntax:"<number>";inherits:true;initial-value:0}
722
2173
  @property --kr-show-hi{syntax:"<number>";inherits:true;initial-value:0}
723
2174
  ${GRAD_PROPS}
2175
+ /* The panel's own dials (the design tokens come from the token sheet, core/root.ts). */
724
2176
  :where(:root,:host){
725
- --k-bg:#1c1c1e;--k-contrast:1;--k-surface:rgba(255,255,255,calc(.055 * var(--k-contrast)));--k-surface-hi:rgba(255,255,255,calc(.11 * var(--k-contrast)));--k-line:rgba(255,255,255,calc(.1 * var(--k-contrast)));--k-line-hi:rgba(255,255,255,calc(.18 * var(--k-contrast)));
726
- --k-text:rgba(255,255,255,.92);--k-label:rgba(255,255,255,.64);--k-dim:rgba(255,255,255,.42);--k-accent:#fff;--k-modified:rgba(255,255,255,.5);
727
- --k-seg-bg:rgba(0,0,0,.26);--k-seg-active:var(--k-surface-hi);--k-toggle-track:rgba(255,255,255,.14);--k-toggle-thumb:var(--k-bg);--k-shadow:0 12px 36px rgba(0,0,0,.52),0 1px 2px rgba(0,0,0,.3);
728
- --k-rim:rgba(255,255,255,.1);--k-edge:rgba(255,255,255,calc(.07 * var(--k-contrast)));--k-rim-width:1px;--k-glass-tone:.5;--k-page:#101012;
729
- --k-group-ink:rgba(255,255,255,.48);
730
- --k-unit:4px;--k-density:1;--k-width:288px;--k-row:round(calc(32px * var(--k-density)),2px);--k-pad:round(calc(10px * var(--k-density)),2px);--k-inset:var(--k-pad);--k-gap:round(calc(var(--k-unit) * var(--k-density)),1px);--k-radius:round(calc(8px * var(--k-density)),2px);--k-panel-radius:calc(var(--k-radius) + var(--k-unit));
731
- --k-font-size:round(calc(12px * var(--k-density)),.5px);--k-label-weight:500;--k-blur:1;--k-glow:0.5;--k-roll:320;--k-drag-roll:0;--k-cascade:12;--k-glass:0.6;
732
- --k-font:system-ui,-apple-system,"SF Pro Text",sans-serif;
733
- --k-mono:"SF Mono",SFMono-Regular,ui-monospace,Menlo,monospace;
734
- --k-spring:0.24 0.16;--k-ease:cubic-bezier(.2,.8,.2,1);--k-reveal-ease:var(--k-ease);
735
- --k-font-weight:400;--k-title-weight:600;--k-thumb:#fff;--k-lift:1;--k-frame:card;
736
- --k-row-gap:0px;--k-hover-in:0;--k-hover-out:120;--k-fill-base:var(--k-surface-hi);--k-fill-rest-mix:20%;--k-fill-hover-mix:var(--k-fill-rest-mix);--k-fill-active-mix:30%;--k-chrome:1;--k-handle:var(--k-accent);--k-handle-inset:0px;--k-handle-rest:0;--k-step-resist:0.25;--k-motion-blur:0;--k-range-blur:.5;--k-curve-blur:.5;--k-group-transform:uppercase;--k-value-font:var(--k-font);
737
- --k-lead:${lead.easing};--k-trail:${trail.easing};--k-fill-ease:${fill.easing};--k-fill-ms:${fill.ms};
2177
+ --k-rim-width:1px;
2178
+ --k-blur:1;--k-roll:320;--k-drag-roll:0;--k-cascade:12;
2179
+ --k-ease:cubic-bezier(.2,.8,.2,1);
2180
+ --k-lift:1;--k-frame:card;
2181
+ --k-row-gap:0px;--k-fill-rest-mix:20%;--k-fill-active-mix:30%;--k-chrome:1;--k-handle-inset:0px;--k-handle-rest:0;--k-step-resist:0.25;--k-motion-blur:0;--k-range-blur:.5;--k-curve-blur:.5;--k-group-transform:uppercase;
2182
+ --k-lead:${lead.easing};--k-trail:${trail.easing};
738
2183
  --k-lens-ms:180;--k-lens-lead:1;--k-lens-wash:.9;--k-lens-line:.65;--k-lens-panel-wash:.35;--k-lens-inset:0px;--k-lens-panel-inset:0px;
739
2184
  --k-armed-edge:.1;--k-armed-glow:0;--k-armed-glow-a:0;--k-title-rest:.6;--k-esc-hint-ms:1800;
740
2185
  }
@@ -742,45 +2187,23 @@ ${GRAD_PROPS}
742
2187
  @media(min-resolution:1.5dppx){:where(:root,:host){--k-rim-width:.67px}}
743
2188
  @media(min-resolution:2dppx){:where(:root,:host){--k-rim-width:.5px}}
744
2189
  @media(min-resolution:3dppx){:where(:root,:host){--k-rim-width:.34px}}
745
- :where(.knobs-panel,.knobs-chip,.knobs-toast)[data-theme="light"],
746
- :where([data-knobs-theme="light"]) :where(.knobs-panel,.knobs-chip,.knobs-toast):not([data-theme="dark"]),
747
- :where(:root[data-theme="light"]) :where(.knobs-panel,.knobs-chip,.knobs-toast)[data-theme="auto"]{${lightVars}}
748
- @media(prefers-color-scheme:light){
749
- :where(:root:not([data-theme="dark"])) :where(.knobs-panel,.knobs-chip,.knobs-toast)[data-theme="auto"]{${lightVars}}
750
- }
751
- :where(.knobs-panel)[data-density="compact"]{--k-density:.875;--k-row:28px;--k-gap:3px;--k-radius:6px;--k-panel-radius:calc(var(--k-radius) + var(--k-unit));--k-pad:8px;--k-inset:8px;--k-font-size:11px}
752
- :where(.knobs-panel)[data-density="comfortable"]{--k-density:1.1875;--k-row:38px;--k-gap:6px;--k-radius:10px;--k-panel-radius:calc(var(--k-radius) + var(--k-unit));--k-pad:12px;--k-inset:12px;--k-font-size:13px}
753
- `, css = `
2190
+ :where(.knobs-root)[data-density="compact"]{--k-density:.875}
2191
+ :where(.knobs-root)[data-density="comfortable"]{--k-density:1.1875}
2192
+ `, css2 = `
754
2193
  :where(.knobs-panel,.knobs-chip,.knobs-menu){
755
- --k-tray-pad:calc(var(--k-unit) * .5);
756
- --k-section-gap:calc(var(--k-gap) * 2);
757
- --k-group-gap:calc(var(--k-gap) * 3);
758
- /* Public sizes a host may set anywhere (:root, the panel, a preset); derived otherwise. */
759
- --kc-control-h:var(--k-control-h,calc(var(--k-row) - var(--k-unit) * 2));
760
- --kc-value-size:var(--k-value-size,calc(var(--k-font-size) - .5px));
761
- --k-action-h:calc(var(--k-row) - var(--k-unit));
762
- --k-track-h:calc(var(--k-row) - 14px);
2194
+ --k-section-gap:calc(var(--_k-gap) * 2);
2195
+ --k-group-gap:calc(var(--_k-gap) * 3);
2196
+ --k-action-h:calc(var(--_k-row) - var(--_k-unit));
2197
+ --k-track-h:calc(var(--_k-row) - 14px);
763
2198
  --k-icon-btn:22px;
764
2199
  --k-icon-size:14px;
765
2200
  --k-icon-sm:13px;
766
- --k-radius-md:max(0px,calc(var(--k-radius) - var(--k-tray-pad)));
767
- --k-radius-sm:max(0px,calc(var(--k-radius) - var(--k-tray-pad) * 2));
768
- /* Round things (switches, icon buttons, handles, thumbs): capsules, or square with --k-radius 0. */
769
- --k-round:calc(var(--k-radius) * 999);
770
- --k-lift-shadow:0 1px 2px rgba(0,0,0,calc(.16 * var(--k-lift)));
771
- --k-text-title:calc(var(--k-font-size) + 1px);
772
- --k-text-body:var(--k-font-size);
773
- --k-text-control:calc(var(--k-font-size) - .5px);
774
- --k-text-meta:calc(var(--k-font-size) - 1px);
775
- --k-text-cap:calc(var(--k-font-size) - 2px);
776
- --k-row-hover:color-mix(in srgb,var(--k-surface) 50%,transparent);
777
- --k-pill-bg:color-mix(in srgb,var(--k-accent) 18%,var(--k-seg-active));
778
- --k-pill-border:color-mix(in srgb,var(--k-accent) 18%,transparent);
779
- --k-fill-rest:color-mix(in srgb,var(--k-accent) var(--k-fill-rest-mix),var(--k-fill-base));
780
- --k-fill-active:color-mix(in srgb,var(--k-accent) var(--k-fill-active-mix),var(--k-fill-base));
2201
+ --k-pill-bg:color-mix(in srgb,var(--_k-accent) 18%,var(--_k-segmented-active));
2202
+ --k-pill-border:color-mix(in srgb,var(--_k-accent) 18%,transparent);
2203
+ --k-fill-active:color-mix(in srgb,var(--_k-accent) var(--k-fill-active-mix),var(--_k-fill-base));
781
2204
  --k-disabled-opacity:.32;
782
- --k-unit-gap:.28em;--k-unit-color:var(--k-dim);--k-readout-mark:0;
783
- --k-group-size:var(--k-text-cap);--k-group-color:var(--k-group-ink);--k-group-inset:var(--k-inset);--k-group-tracking:.04em;--k-group-divider:transparent;--k-group-divider-gap:0px;
2205
+ --k-unit-gap:.28em;--k-unit-color:var(--_k-fg-3);--k-readout-mark:0;
2206
+ --k-group-size:var(--_k-text-cap);--k-group-inset:var(--_k-inset);--k-group-tracking:.04em;--k-group-divider:transparent;--k-group-divider-gap:0px;
784
2207
  --k-curve-inset:6px;--k-curve-guide:solid;--k-curve-dot:1;
785
2208
  --k-hint-typed-opacity:.42;
786
2209
  }
@@ -790,11 +2213,11 @@ ${GRAD_PROPS}
790
2213
  .knobs-panel *:where(:not(.knobs-accessory,.knobs-accessory *,.knobs-live *)),.knobs-menu *{box-sizing:border-box;color:inherit;letter-spacing:inherit;word-spacing:inherit;line-height:inherit;text-transform:inherit;text-shadow:inherit;font-style:inherit}
791
2214
  /* Hover washes come in at --k-hover-in and leave at --k-hover-out (ms). Set per element, so a
792
2215
  hovered card doesn't hand its quick entrance to the rows inside it. */
793
- :where(.knobs-panel,.knobs-menu) *{--k-hover-t:calc(var(--k-hover-out) * 1ms)}
794
- :where(.knobs-panel,.knobs-menu) :is(:hover,.knobs-active){--k-hover-t:calc(var(--k-hover-in) * 1ms)}
2216
+ :where(.knobs-panel,.knobs-menu) *{--k-hover-t:calc(var(--_k-hover-out) * 1ms)}
2217
+ :where(.knobs-panel,.knobs-menu) :is(:hover,.knobs-active){--k-hover-t:calc(var(--_k-hover-in) * 1ms)}
795
2218
 
796
2219
  .knobs-panel,.knobs-chip{
797
- box-sizing:border-box;font:var(--k-font-weight) var(--k-font-size)/1.35 var(--k-font);color:var(--k-text);text-align:left;color-scheme:dark;
2220
+ box-sizing:border-box;font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);text-align:left;
798
2221
  -webkit-font-smoothing:antialiased;
799
2222
  }
800
2223
  /* Text properties a host page sets on its own elements (letter-spacing, capitals, shadows) stop
@@ -803,25 +2226,25 @@ ${GRAD_PROPS}
803
2226
  :where(.knobs-panel,.knobs-chip) :where(*,*::before,*::after){box-sizing:border-box}
804
2227
  .knobs-panel .rn-slot{box-sizing:content-box}
805
2228
  .knobs-panel [hidden],.knobs-panel[hidden],.knobs-chip[hidden]{display:none!important}
806
- .knobs-mono{font-family:var(--k-mono);font-variant-numeric:tabular-nums}
2229
+ .knobs-mono{font-family:var(--_k-mono);font-variant-numeric:tabular-nums}
807
2230
 
808
2231
  /* The chip: a round cog button, or a capsule with a label beside the cog. */
809
- .knobs-chip{position:fixed;z-index:2147480000;display:inline-flex;align-items:center;justify-content:center;gap:5px;width:26px;height:26px;padding:0;border-radius:999px;cursor:pointer;background:var(--k-bg);border:1px solid transparent;
810
- color:var(--k-label);font-size:var(--k-text-control);line-height:1;letter-spacing:.01em;white-space:nowrap;--k-chip-edge:var(--k-edge);box-shadow:0 0 0 var(--k-rim-width) var(--k-chip-edge),0 4px 16px rgba(0,0,0,.35),inset 0 var(--k-rim-width) 0 var(--k-rim);transition:color .15s,border-color .15s,transform .2s var(--k-ease),opacity .2s,scale .12s var(--k-ease),${TOKEN_TRANSITIONS};}
2232
+ .knobs-chip{position:fixed;z-index:2147480000;display:inline-flex;align-items:center;justify-content:center;gap:5px;width:26px;height:26px;padding:0;border-radius:999px;cursor:pointer;background:var(--_k-bg);border:1px solid transparent;
2233
+ color:var(--_k-fg-2);font-size:var(--_k-text-control);line-height:1;letter-spacing:.01em;white-space:nowrap;--k-chip-edge:var(--_k-border-subtle);box-shadow:0 0 0 var(--k-rim-width) var(--k-chip-edge),0 4px 16px rgba(0,0,0,calc(.35 * var(--_k-shadow-k,1))),inset 0 var(--k-rim-width) 0 var(--_k-rim);transition:color .15s,border-color .15s,transform .2s var(--k-ease),opacity .2s,scale .12s var(--k-ease),${TOKEN_TRANSITIONS};}
811
2234
  .knobs-chip[data-label]{width:auto;padding:0 10px 0 7px}
812
2235
  .knobs-chip .knobs-icon{display:block;flex:none;width:15px;height:15px}
813
- .knobs-chip:hover{color:var(--k-text);--k-chip-edge:var(--k-line-hi)}
2236
+ .knobs-chip:hover{color:var(--_k-fg);--k-chip-edge:var(--_k-border-strong)}
814
2237
  .knobs-chip[data-shown="true"]{transition:color .15s,border-color .15s,opacity .16s var(--k-ease),transform .22s var(--k-ease),scale .12s var(--k-ease),visibility 0s,${TOKEN_TRANSITIONS}}
815
2238
  .knobs-chip[data-shown="false"]{opacity:0;visibility:hidden;pointer-events:none;transform:translateY(-2px) scale(.94);transition:opacity .12s ease-in,transform .12s ease-in,visibility 0s .12s,${TOKEN_TRANSITIONS}}
816
2239
  /* A press squeezes it, easing in (morph.ts carries the squeeze on into the glass). */
817
2240
  .knobs-chip.knobs-chip[data-pressed]{scale:.94;transition:color .15s,border-color .15s,scale 50ms ease-in-out,${TOKEN_TRANSITIONS}}
818
- .knobs-chip:focus-visible{outline:none;color:var(--k-text);--k-chip-edge:var(--k-line-hi)}
2241
+ .knobs-chip:focus-visible{outline:none;color:var(--_k-fg);--k-chip-edge:var(--_k-border-strong)}
819
2242
  @media(prefers-reduced-motion:reduce){.knobs-chip.knobs-chip{scale:none;transform:none}}
820
2243
  /* "knobs on" / "knobs off" after the reveal shortcut. */
821
- .knobs-toast{position:fixed;left:50%;bottom:24px;z-index:2147480004;translate:-50% 0;padding:6px 12px;border-radius:999px;pointer-events:none;
822
- background:var(--k-bg);border:1px solid var(--k-line);box-shadow:0 4px 16px rgba(0,0,0,.35);color:var(--k-text);font:500 12px/1.2 var(--k-font);letter-spacing:.01em;
2244
+ .knobs-notice{position:fixed;left:50%;bottom:24px;z-index:2147480004;translate:-50% 0;padding:6px 12px;border-radius:999px;pointer-events:none;
2245
+ background:var(--_k-bg);border:1px solid var(--_k-border);box-shadow:0 4px 16px rgba(0,0,0,calc(.35 * var(--_k-shadow-k,1)));color:var(--_k-fg);font:500 12px/1.2 var(--_k-font);letter-spacing:.01em;
823
2246
  transition:opacity .18s var(--k-ease),scale .18s var(--k-ease)}
824
- .knobs-toast[data-shown="false"]{opacity:0;scale:.96;transition:opacity .16s ease-in,scale .16s ease-in}
2247
+ .knobs-notice[data-shown="false"]{opacity:0;scale:.96;transition:opacity .16s ease-in,scale .16s ease-in}
825
2248
 
826
2249
  /* Tokens glide on the panel spring. While a control is dragged (data-knobs-scrub) they follow it
827
2250
  step for step instead: the pointer already moves them continuously, and a declared transition
@@ -835,12 +2258,12 @@ ${GRAD_PROPS}
835
2258
  backdrop, toned toward the theme (--k-glass-tone dims it under dark panels) so text keeps its
836
2259
  contrast. Its edge is a hairline (--k-edge, --k-rim-width wide) and a hairline of light (--k-rim)
837
2260
  catches its top. */
838
- .knobs-panel{-webkit-user-select:none;user-select:none;transition:${TOKEN_TRANSITIONS},--k-armed ${ARMED_T};position:fixed;z-index:2147480001;width:var(--k-width);max-width:calc(100vw - 16px);max-height:calc(100dvh - 16px);overflow:auto;padding:var(--k-pad);
839
- background:color-mix(in srgb,var(--k-bg) calc(100% - var(--k-glass) * 20%),transparent);border:1px solid transparent;border-radius:var(--k-panel-radius);box-shadow:var(--k-shadow),0 0 0 var(--k-rim-width) var(--ka-edge),inset 0 var(--k-rim-width) 0 var(--k-rim),var(--ka-glow);scrollbar-width:thin;
2261
+ .knobs-panel{-webkit-user-select:none;user-select:none;transition:${TOKEN_TRANSITIONS},--k-armed ${ARMED_T};position:fixed;z-index:2147480001;width:var(--_k-width);max-width:calc(100vw - 16px);max-height:calc(100dvh - 16px);overflow:auto;padding:var(--_k-pad);
2262
+ background:color-mix(in srgb,var(--_k-bg) calc(100% - var(--_k-glass) * 20%),transparent);border:1px solid transparent;border-radius:var(--_k-radius-panel);box-shadow:var(--_k-shadow-overlay),0 0 0 var(--k-rim-width) var(--ka-edge),inset 0 var(--k-rim-width) 0 var(--_k-rim),var(--ka-glow);scrollbar-width:thin;
840
2263
  /* Armed (focus inside: keys come here), the edge takes the accent and a faint glow lifts it. */
841
- --ka-edge:color-mix(in srgb,var(--k-accent) calc(var(--k-armed) * var(--k-armed-edge) * 100%),var(--k-edge));
842
- --ka-glow:0 0 calc(var(--k-armed-glow) * 1px) color-mix(in srgb,var(--k-accent) calc(var(--k-armed) * var(--k-armed-glow-a) * var(--k-chrome,1) * 100%),transparent);
843
- --k-backdrop:blur(calc(var(--k-glass) * 24px)) saturate(calc(1 + var(--k-glass) * .8)) brightness(calc(1 + (var(--k-glass-tone) - 1) * var(--k-glass)));
2264
+ --ka-edge:color-mix(in srgb,var(--_k-accent) calc(var(--k-armed) * var(--k-armed-edge) * 100%),var(--_k-border-subtle));
2265
+ --ka-glow:0 0 calc(var(--k-armed-glow) * 1px) color-mix(in srgb,var(--_k-accent) calc(var(--k-armed) * var(--k-armed-glow-a) * var(--k-chrome,1) * 100%),transparent);
2266
+ --k-backdrop:blur(calc(var(--_k-glass) * 24px)) saturate(calc(1 + var(--_k-glass) * .8)) brightness(calc(1 + (var(--_k-glass-tone) - 1) * var(--_k-glass)));
844
2267
  -webkit-backdrop-filter:var(--k-backdrop);backdrop-filter:var(--k-backdrop);
845
2268
  animation:knobs-in .16s var(--k-ease);}
846
2269
  .knobs-panel[data-restored]{animation:none}
@@ -848,21 +2271,21 @@ ${GRAD_PROPS}
848
2271
  content, laid out at full size, is clipped to it and revealed top first. */
849
2272
  .knobs-panel[data-morphing]{background:transparent;border-color:transparent;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;animation:none}
850
2273
  .knobs-morph{position:fixed;left:0;top:0;z-index:2147480001;pointer-events:none;box-sizing:border-box;--p:0;--spec:0;
851
- background:color-mix(in srgb,var(--k-bg) calc(100% - var(--k-glass) * 20% * var(--p)),transparent);border:1px solid transparent;
852
- box-shadow:0 0 0 var(--k-rim-width) var(--k-edge),inset 0 0 0 var(--k-rim-width) rgb(255 255 255/var(--spec)),inset 0 var(--k-rim-width) 0 color-mix(in srgb,var(--k-rim) calc(var(--p) * 100%),transparent);
853
- --k-backdrop:blur(calc(var(--k-glass) * 24px)) saturate(calc(1 + var(--k-glass) * .8)) brightness(calc(1 + (var(--k-glass-tone) - 1) * var(--k-glass)));
2274
+ background:color-mix(in srgb,var(--_k-bg) calc(100% - var(--_k-glass) * 20% * var(--p)),transparent);border:1px solid transparent;
2275
+ box-shadow:0 0 0 var(--k-rim-width) var(--_k-border-subtle),inset 0 0 0 var(--k-rim-width) rgb(255 255 255/var(--spec)),inset 0 var(--k-rim-width) 0 color-mix(in srgb,var(--_k-rim) calc(var(--p) * 100%),transparent);
2276
+ --k-backdrop:blur(calc(var(--_k-glass) * 24px)) saturate(calc(1 + var(--_k-glass) * .8)) brightness(calc(1 + (var(--_k-glass-tone) - 1) * var(--_k-glass)));
854
2277
  -webkit-backdrop-filter:var(--k-backdrop);backdrop-filter:var(--k-backdrop)}
855
2278
  .knobs-morph::before,.knobs-morph::after{content:"";position:absolute;inset:-1px;border-radius:inherit;pointer-events:none}
856
- .knobs-morph::before{box-shadow:0 4px 16px rgba(0,0,0,.35);opacity:calc(1 - var(--p))}
857
- .knobs-morph::after{box-shadow:var(--k-shadow);opacity:var(--p)}
2279
+ .knobs-morph::before{box-shadow:0 4px 16px rgba(0,0,0,calc(.35 * var(--_k-shadow-k,1)));opacity:calc(1 - var(--p))}
2280
+ .knobs-morph::after{box-shadow:var(--_k-shadow-overlay);opacity:var(--p)}
858
2281
  /* Meanwhile the chip is just its label, fading on the shape. */
859
2282
  .knobs-chip.knobs-chip[data-morph]{visibility:visible;pointer-events:auto;transform:none;transition:none;background:transparent;border-color:transparent;box-shadow:none}
860
- .knobs-panel.knobs-inline{position:relative;z-index:auto;left:auto!important;top:auto!important;max-width:100%;max-height:none;box-shadow:0 0 0 var(--k-rim-width) color-mix(in srgb,var(--ka-edge) calc(var(--k-chrome) * 100%),transparent),inset 0 var(--k-rim-width) 0 color-mix(in srgb,var(--k-rim) calc(var(--k-chrome) * 100%),transparent),var(--ka-glow);animation:none;
2283
+ .knobs-panel.knobs-inline{position:relative;z-index:auto;left:auto!important;top:auto!important;max-width:100%;max-height:none;box-shadow:0 0 0 var(--k-rim-width) color-mix(in srgb,var(--ka-edge) calc(var(--k-chrome) * 100%),transparent),inset 0 var(--k-rim-width) 0 color-mix(in srgb,var(--_k-rim) calc(var(--k-chrome) * 100%),transparent),var(--ka-glow);animation:none;
861
2284
  /* --k-chrome 0: an embedded panel sheds its card (background, border, rim) for the host's column,
862
2285
  border width too, so its rows line up with the column's edges. */
863
2286
  border-width:calc(var(--k-chrome) * 1px);
864
- background:color-mix(in srgb,color-mix(in srgb,var(--k-bg) calc(100% - var(--k-glass) * 20%),transparent) calc(var(--k-chrome) * 100%),transparent);border-color:transparent;
865
- --k-backdrop:blur(calc(var(--k-glass) * var(--k-chrome) * 24px)) saturate(calc(1 + var(--k-glass) * var(--k-chrome) * .8)) brightness(calc(1 + (var(--k-glass-tone) - 1) * var(--k-glass) * var(--k-chrome)))}
2287
+ background:color-mix(in srgb,color-mix(in srgb,var(--_k-bg) calc(100% - var(--_k-glass) * 20%),transparent) calc(var(--k-chrome) * 100%),transparent);border-color:transparent;
2288
+ --k-backdrop:blur(calc(var(--_k-glass) * var(--k-chrome) * 24px)) saturate(calc(1 + var(--_k-glass) * var(--k-chrome) * .8)) brightness(calc(1 + (var(--_k-glass-tone) - 1) * var(--_k-glass) * var(--k-chrome)))}
866
2289
  @keyframes knobs-in{from{opacity:0;transform:translateY(4px) scale(.985)}to{opacity:1;transform:none}}
867
2290
  @media(prefers-reduced-motion:reduce){.knobs-panel{animation:none}.knobs-panel *{transition:none!important}.knobs-keys .knobs-keys-text,.knobs-number,.knobs-cell-edit{animation:none}}
868
2291
 
@@ -870,13 +2293,13 @@ ${GRAD_PROPS}
870
2293
  input[type=text]{...}) and below every knobs rule that styles these elements, which are all
871
2294
  (0,1,1) or more and come later. */
872
2295
  :is(.knobs-panel,.knobs-menu) :is(button,input,select,textarea):where(:not(.knobs-accessory *)){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;text-transform:inherit;text-shadow:none;
873
- background:var(--k-surface);border:0;border-radius:var(--k-radius);min-width:0;box-shadow:none;outline:none}
2296
+ background:var(--_k-fill);border:0;border-radius:var(--_k-radius);min-width:0;box-shadow:none;outline:none}
874
2297
  :is(.knobs-panel,.knobs-menu) :is(header,strong,p,kbd,aside,mark):where(:not(.knobs-accessory *)){all:revert;box-sizing:border-box;margin:0;padding:0;font:inherit;color:inherit;letter-spacing:inherit;text-transform:inherit}
875
2298
  .knobs-panel .knobs-icon>path{fill:currentColor}
876
2299
  :is(.knobs-panel,.knobs-menu) :is(:focus,:focus-visible):where(:not(.knobs-accessory *)){outline:none}
877
2300
 
878
2301
  /* Header */
879
- .knobs-panel header{position:relative;display:flex;align-items:center;justify-content:space-between;gap:6px;cursor:grab;touch-action:none;padding:0 var(--k-inset) var(--k-section-gap);min-height:var(--k-icon-btn)}
2302
+ .knobs-panel header{position:relative;display:flex;align-items:center;justify-content:space-between;gap:6px;cursor:grab;touch-action:none;padding:0 var(--_k-inset) var(--k-section-gap);min-height:var(--k-icon-btn)}
880
2303
  .knobs-panel.knobs-inline header,.knobs-panel.knobs-inline header:active{cursor:default}
881
2304
  /* The title row stays pinned while the rows scroll under it, in the panel (it scrolls once it's
882
2305
  bounded) or, with .knobs-pin-ancestor (which also makes the panel overflow:visible), in the
@@ -892,8 +2315,8 @@ ${GRAD_PROPS}
892
2315
  @supports (animation-timeline:scroll()){
893
2316
  .knobs-panel:not(.knobs-page){scroll-timeline:--knobs-self block}
894
2317
  .knobs-panel.knobs-pin-ancestor:not(.knobs-page){overflow:visible;view-timeline:--knobs-view block}
895
- .knobs-panel:not(.knobs-page)>header{position:sticky;top:0;z-index:4;border-radius:max(0px,calc(var(--k-panel-radius) - 1px)) max(0px,calc(var(--k-panel-radius) - 1px)) 0 0;
896
- --k-head-on:max(var(--k-head-s),var(--k-head-v));--k-head-bg:color-mix(in srgb,var(--k-bg) 88%,transparent);
2318
+ .knobs-panel:not(.knobs-page)>header{position:sticky;top:0;z-index:4;border-radius:max(0px,calc(var(--_k-radius-panel) - 1px)) max(0px,calc(var(--_k-radius-panel) - 1px)) 0 0;
2319
+ --k-head-on:max(var(--k-head-s),var(--k-head-v));--k-head-bg:color-mix(in srgb,var(--_k-bg) 88%,transparent);
897
2320
  background:color-mix(in srgb,var(--k-head-bg) calc(var(--k-head-on) * 100%),transparent);
898
2321
  animation:knobs-head-s linear both;animation-timeline:--knobs-self;animation-range:0px 24px}
899
2322
  .knobs-panel.knobs-pin-ancestor:not(.knobs-page)>header{animation:knobs-head-v linear both;animation-timeline:--knobs-view;animation-range:exit-crossing 0px exit-crossing 24px}
@@ -903,41 +2326,41 @@ ${GRAD_PROPS}
903
2326
  .knobs-panel[data-gpu-active="true"]:not(.knobs-page)>header::after{display:none}
904
2327
  }
905
2328
  .knobs-panel header:active{cursor:grabbing}
906
- .knobs-panel header strong{flex:1;min-width:0;font-weight:var(--k-title-weight);font-size:var(--k-text-title);letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:opacity .2s var(--k-ease),color ${ARMED_T};
907
- color:color-mix(in srgb,var(--k-text) calc(var(--k-title-rest) * 100%),var(--k-label))}
2329
+ .knobs-panel header strong{flex:1;min-width:0;font-weight:var(--_k-weight-title);font-size:var(--_k-text-title);letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:opacity .2s var(--k-ease),color ${ARMED_T};
2330
+ color:color-mix(in srgb,var(--_k-fg) calc(var(--k-title-rest) * 100%),var(--_k-fg-2))}
908
2331
  /* At rest a panel's title is a little quiet; armed (keys come here) it's at full strength. */
909
- .knobs-panel[data-k-armed] header strong{color:var(--k-text)}
2332
+ .knobs-panel[data-k-armed] header strong{color:var(--_k-fg)}
910
2333
  /* The scope line beside the title (crumbs.ts): where keys go, and for a moment where Esc goes. */
911
- .knobs-crumbs{position:absolute;left:0;top:50%;height:0;pointer-events:none;white-space:nowrap;font-size:var(--k-text-meta);font-weight:var(--k-label-weight);line-height:1.2;letter-spacing:0;text-transform:none}
912
- .knobs-crumbs>*{position:absolute;left:0;top:0;translate:0 -50%;color:var(--k-dim);transition:opacity .2s var(--k-ease),translate ${CRUMB_GLIDE},color .2s var(--k-ease)}
2334
+ .knobs-crumbs{position:absolute;left:0;top:50%;height:0;pointer-events:none;white-space:nowrap;font-size:var(--_k-text-meta);font-weight:var(--_k-weight-label);line-height:1.2;letter-spacing:0;text-transform:none}
2335
+ .knobs-crumbs>*{position:absolute;left:0;top:0;translate:0 -50%;color:var(--_k-fg-3);transition:opacity .2s var(--k-ease),translate ${CRUMB_GLIDE},color .2s var(--k-ease)}
913
2336
  .knobs-crumbs>[data-leaving]{transition:opacity .14s cubic-bezier(.4,0,1,1),translate .14s cubic-bezier(.4,0,1,1)}
914
2337
  .knobs-crumbs>.knobs-crumb-crumb{pointer-events:auto;cursor:pointer}
915
- .knobs-crumbs>.knobs-crumb-crumb[data-deep]{color:var(--k-text)}
916
- .knobs-crumbs>.knobs-crumb-crumb:not([data-deep]):hover{color:var(--k-label)}
917
- .knobs-crumbs>.knobs-crumb-sep{color:color-mix(in srgb,var(--k-dim) 70%,transparent)}
918
- .knobs-crumbs>.knobs-crumb-esc{font-family:var(--k-mono);font-size:var(--k-text-cap);transition:opacity .35s var(--k-ease),translate ${CRUMB_GLIDE}}
2338
+ .knobs-crumbs>.knobs-crumb-crumb[data-deep]{color:var(--_k-fg)}
2339
+ .knobs-crumbs>.knobs-crumb-crumb:not([data-deep]):hover{color:var(--_k-fg-2)}
2340
+ .knobs-crumbs>.knobs-crumb-sep{color:color-mix(in srgb,var(--_k-fg-3) 70%,transparent)}
2341
+ .knobs-crumbs>.knobs-crumb-esc{font-family:var(--_k-mono);font-size:var(--_k-text-cap);transition:opacity .35s var(--k-ease),translate ${CRUMB_GLIDE}}
919
2342
  @media(prefers-reduced-motion:reduce){.knobs-panel .knobs-crumbs>*{transition:opacity .15s linear!important}}
920
2343
  .knobs-panel[data-gpu-active="true"] .knobs-crumbs>*{color:transparent!important}
921
2344
  /* Holding \\ shows the values from before the last change; the title dims meanwhile. */
922
2345
  .knobs-panel[data-comparing] header strong{opacity:.4}
923
2346
  .knobs-head-actions{display:flex;align-items:center;margin-right:calc((var(--k-icon-size) - var(--k-icon-btn)) / 2)}
924
- .knobs-head-split{margin-left:calc(var(--k-unit) * 1.5)}
2347
+ .knobs-head-split{margin-left:calc(var(--_k-unit) * 1.5)}
925
2348
  .knobs-icon{width:var(--k-icon-size);height:var(--k-icon-size);display:block;flex:none}
926
2349
  .knobs-die-icon{position:relative;display:block;width:var(--k-icon-size);height:var(--k-icon-size);flex:none}
927
2350
  .knobs-die-icon>canvas{position:absolute;margin:0}
928
2351
  .knobs-panel[data-gpu-active="true"] .knobs-die-icon>canvas{visibility:hidden}
929
2352
  /* The tools sit quiet (--k-dim) until the panel has the pointer or keyboard focus, then read as
930
2353
  labels, and as text under the pointer. */
931
- .knobs-panel header button{position:relative;width:var(--k-icon-btn);height:var(--k-icon-btn);padding:0;display:inline-flex;align-items:center;justify-content:center;color:var(--k-dim);background:transparent;border-radius:var(--k-round);cursor:pointer;font-size:12px;line-height:1;transition:background var(--k-hover-t),color var(--k-hover-t),opacity .15s}
932
- .knobs-panel:is(:hover,:has(:focus-visible)) header button{color:var(--k-label)}
933
- .knobs-panel header button:is(:hover:not([disabled]),:focus-visible),.knobs-panel header button[aria-expanded="true"]{background:var(--k-surface-hi);color:var(--k-text)}
2354
+ .knobs-panel header button{position:relative;width:var(--k-icon-btn);height:var(--k-icon-btn);padding:0;display:inline-flex;align-items:center;justify-content:center;color:var(--_k-fg-3);background:transparent;border-radius:var(--_k-round);cursor:pointer;font-size:12px;line-height:1;transition:background var(--k-hover-t),color var(--k-hover-t),opacity .15s}
2355
+ .knobs-panel:is(:hover,:has(:focus-visible)) header button{color:var(--_k-fg-2)}
2356
+ .knobs-panel header button:is(:hover:not([disabled]),:focus-visible),.knobs-panel header button[aria-expanded="true"]{background:var(--_k-fill-selected);color:var(--_k-fg)}
934
2357
  .knobs-panel header button[disabled]{opacity:var(--k-disabled-opacity);cursor:default}
935
2358
  /* The close X's ink sits a fifth of its box in from each side, a digit's barely: nudged right, its
936
2359
  ink ends where the values' digits do. */
937
2360
  .knobs-panel header .knobs-close>.knobs-icon{translate:calc(var(--k-icon-size) * .1) 0}
938
2361
  /* Undo · Redo sit apart from Reset · Copy · Random. Undo, Redo and Reset (and a group's reset)
939
2362
  keep their slots while they're away and bloom in and out of them: nothing beside them moves. */
940
- .knobs-head-history{display:flex;flex:none;margin-right:calc(var(--k-unit) * 1.5)}
2363
+ .knobs-head-history{display:flex;flex:none;margin-right:calc(var(--_k-unit) * 1.5)}
941
2364
  .knobs-panel :is(.knobs-head-actions,.knobs-group-head) button[data-shown]{transition:background var(--k-hover-t),color var(--k-hover-t),opacity ${BLOOM_IN},scale ${BLOOM_IN},filter 0s,visibility 0s}
942
2365
  .knobs-panel :is(.knobs-head-actions,.knobs-group-head) button[data-shown="false"]{opacity:0;scale:.9;filter:blur(2.5px);visibility:hidden;
943
2366
  transition:background var(--k-hover-t),color var(--k-hover-t),opacity ${BLOOM_OUT},scale ${BLOOM_OUT},filter ${BLOOM_OUT},visibility 0s ${snappyOut.ms}ms}
@@ -946,9 +2369,9 @@ ${GRAD_PROPS}
946
2369
  .knobs-panel :is(.knobs-head-actions,.knobs-group-head) button[data-shown="false"]{scale:1;filter:none;transition:opacity .15s,visibility 0s .15s!important}}
947
2370
  /* A press flash (flash.ts): from a key or a click, the button's wash brightens at once and eases
948
2371
  back to its own, its ink with it. Two names, so a second press restarts it. */
949
- @keyframes knobs-flash-a{from{background-color:var(--k-flash-bg);color:var(--k-text)}}
950
- @keyframes knobs-flash-b{from{background-color:var(--k-flash-bg);color:var(--k-text)}}
951
- .knobs-panel :is(header,.knobs-group-head) button{--k-flash-bg:color-mix(in srgb,var(--k-surface-hi),var(--k-text) 10%)}
2372
+ @keyframes knobs-flash-a{from{background-color:var(--k-flash-bg);color:var(--_k-fg)}}
2373
+ @keyframes knobs-flash-b{from{background-color:var(--k-flash-bg);color:var(--_k-fg)}}
2374
+ .knobs-panel :is(header,.knobs-group-head) button{--k-flash-bg:color-mix(in srgb,var(--_k-fill-selected),var(--_k-fg) 10%)}
952
2375
  .knobs-panel :is(header,.knobs-group-head) button[data-k-flash="a"]{animation:knobs-flash-a ${FLASH_MS}ms cubic-bezier(.33,1,.68,1)}
953
2376
  .knobs-panel :is(header,.knobs-group-head) button[data-k-flash="b"]{animation:knobs-flash-b ${FLASH_MS}ms cubic-bezier(.33,1,.68,1)}
954
2377
  /* Copied: the glyph shrinks away and a check draws itself in its place, held, then they trade
@@ -956,7 +2379,7 @@ ${GRAD_PROPS}
956
2379
  drawn) and --k-check-a (its opacity), which the GPU renderer reads too. */
957
2380
  .knobs-panel header .knobs-copy{--k-copy:1;--k-check:0;--k-check-a:0;
958
2381
  transition:background var(--k-hover-t),color var(--k-hover-t),opacity .15s,--k-copy ${BLOOM_IN} .04s,--k-check 0s .1s,--k-check-a .1s cubic-bezier(.4,0,1,1)}
959
- .knobs-panel header .knobs-copy[data-copied]{--k-copy:0;--k-check:1;--k-check-a:1;color:var(--k-text);
2382
+ .knobs-panel header .knobs-copy[data-copied]{--k-copy:0;--k-check:1;--k-check-a:1;color:var(--_k-fg);
960
2383
  transition:background var(--k-hover-t),color var(--k-hover-t),opacity .15s,--k-copy .1s cubic-bezier(.4,0,1,1),--k-check .18s cubic-bezier(.2,.8,.2,1) .03s,--k-check-a .04s linear .03s}
961
2384
  .knobs-copy>.knobs-icon:not(.knobs-check){opacity:var(--k-copy);scale:calc(.5 + .5 * var(--k-copy))}
962
2385
  .knobs-copy>.knobs-check{position:absolute;inset:0;margin:auto;opacity:var(--k-check-a)}
@@ -965,56 +2388,56 @@ ${GRAD_PROPS}
965
2388
  .knobs-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
966
2389
 
967
2390
  /* Shortcuts Popover */
968
- .knobs-popover{margin:0 0 var(--k-section-gap);padding:var(--k-section-gap) var(--k-inset);background:var(--k-surface-hi);border:1px solid var(--k-line);border-radius:var(--k-radius);font-size:var(--k-text-meta)}
2391
+ .knobs-popover{margin:0 0 var(--k-section-gap);padding:var(--k-section-gap) var(--_k-inset);background:var(--_k-fill-selected);border:1px solid var(--_k-border);border-radius:var(--_k-radius);font-size:var(--_k-text-meta)}
969
2392
  .knobs-popover-grid{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;align-items:baseline}
970
- .knobs-popover-grid kbd{font:var(--k-text-cap)/1 var(--k-mono);font-variant-numeric:tabular-nums;color:var(--k-text);background:var(--k-seg-bg);padding:2px 5px;border-radius:var(--k-radius-sm);justify-self:start;white-space:nowrap}
971
- .knobs-popover-grid span{color:var(--k-label)}
2393
+ .knobs-popover-grid kbd{font:var(--_k-text-cap)/1 var(--_k-mono);font-variant-numeric:tabular-nums;color:var(--_k-fg);background:var(--_k-segmented-track);padding:2px 5px;border-radius:var(--_k-radius-sm);justify-self:start;white-space:nowrap}
2394
+ .knobs-popover-grid span{color:var(--_k-fg-2)}
972
2395
 
973
2396
  /* Custom Preset Strip */
974
- .knobs-presets{position:relative;display:flex;align-items:flex-start;gap:var(--k-tray-pad);margin:0 0 var(--k-section-gap);padding:var(--k-tray-pad);background:var(--k-seg-bg);border-radius:var(--k-radius);user-select:none;touch-action:none}
975
- .knobs-presets-track{position:relative;flex:1;min-width:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,var(--k-preset-min,58px)),1fr));align-items:stretch;gap:var(--k-tray-pad)}
2397
+ .knobs-presets{position:relative;display:flex;align-items:flex-start;gap:var(--_k-tray-pad);margin:0 0 var(--k-section-gap);padding:var(--_k-tray-pad);background:var(--_k-segmented-track);border-radius:var(--_k-radius);user-select:none;touch-action:none}
2398
+ .knobs-presets-track{position:relative;flex:1;min-width:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,var(--k-preset-min,58px)),1fr));align-items:stretch;gap:var(--_k-tray-pad)}
976
2399
  /* The selected pill is placed by its edges: the edge facing the move leads, the other trails. */
977
- .knobs-presets-pill{position:absolute;top:0;left:0;background:var(--k-pill-bg);border:0;border-radius:var(--k-button-radius,var(--k-radius-md));box-shadow:inset 0 0 0 var(--k-rim-width) var(--k-pill-border),inset 0 var(--k-rim-width) 0 var(--k-rim),var(--k-lift-shadow),0 0 calc(var(--k-glow) * 10px) color-mix(in srgb,var(--k-accent) 24%,transparent);pointer-events:none;
2400
+ .knobs-presets-pill{position:absolute;top:0;left:0;background:var(--k-pill-bg);border:0;border-radius:var(--k-button-radius,var(--_k-radius-md));box-shadow:inset 0 0 0 var(--k-rim-width) var(--k-pill-border),inset 0 var(--k-rim-width) 0 var(--_k-rim),var(--_k-shadow-raised),0 0 calc(var(--_k-glow) * 10px) color-mix(in srgb,var(--_k-accent) 24%,transparent);pointer-events:none;
978
2401
  transition:left ${TRAIL_T},right ${LEAD_T},top ${LEAD_T},opacity .15s,scale .15s}
979
2402
  .knobs-presets-pill[data-dir="left"]{transition:left ${LEAD_T},right ${TRAIL_T},top ${LEAD_T},opacity .15s,scale .15s}
980
- .knobs-panel .knobs-preset-chip{position:relative;z-index:1;height:var(--k-button-h,var(--kc-control-h));min-height:20px;padding:0 6px;font-size:var(--k-button-font-size,var(--k-text-control));font-weight:var(--k-label-weight);color:var(--k-button-color,var(--k-label));background:transparent!important;border-radius:var(--k-button-radius,var(--k-radius-md));cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .15s,background .15s,box-shadow .15s}
2403
+ .knobs-panel .knobs-preset-chip{position:relative;z-index:1;height:var(--k-button-h,var(--_k-control-h));min-height:20px;padding:0 6px;font-size:var(--k-button-font-size,var(--_k-text-control));font-weight:var(--_k-weight-label);color:var(--k-button-color,var(--_k-fg-2));background:transparent!important;border-radius:var(--k-button-radius,var(--_k-radius-md));cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .15s,background .15s,box-shadow .15s}
981
2404
  .knobs-panel[data-buttons] .knobs-presets{background:transparent;padding:0}
982
2405
  .knobs-panel[data-buttons] .knobs-preset-chip{background:var(--k-button-bg,transparent)!important;box-shadow:inset 0 0 0 1px var(--k-button-line,transparent)}
983
- .knobs-panel[data-buttons] .knobs-preset-chip:hover{background:var(--k-button-hover-bg,var(--k-surface-hi))!important;box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent))}
984
- .knobs-panel .knobs-preset-chip:hover{color:var(--k-text)}
985
- .knobs-panel .knobs-preset-chip[aria-checked="true"]{color:var(--k-text);font-weight:var(--k-title-weight)}
986
- .knobs-panel .knobs-preset-save{flex:none;width:calc((var(--k-inset) - var(--k-tray-pad)) * 2 + 8px);padding:0!important;color:var(--k-dim)!important;font-weight:400!important;font-size:var(--k-text-title)!important}
987
- .knobs-panel .knobs-preset-save:hover{color:var(--k-text)!important}
2406
+ .knobs-panel[data-buttons] .knobs-preset-chip:hover{background:var(--k-button-hover-bg,var(--_k-fill-selected))!important;box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent))}
2407
+ .knobs-panel .knobs-preset-chip:hover{color:var(--_k-fg)}
2408
+ .knobs-panel .knobs-preset-chip[aria-checked="true"]{color:var(--_k-fg);font-weight:var(--_k-weight-title)}
2409
+ .knobs-panel .knobs-preset-save{flex:none;width:calc((var(--_k-inset) - var(--_k-tray-pad)) * 2 + 8px);padding:0!important;color:var(--_k-fg-3)!important;font-weight:400!important;font-size:var(--_k-text-title)!important}
2410
+ .knobs-panel .knobs-preset-save:hover{color:var(--_k-fg)!important}
988
2411
  /* The active preset's modified mark: the values have drifted off it (a row's dot, in its corner). */
989
- .knobs-panel .knobs-preset-chip::after{content:"";position:absolute;top:4px;right:4px;width:4px;height:4px;border-radius:50%;background:var(--k-modified);opacity:0;transform:scale(.4);pointer-events:none;transition:opacity .16s ease-out,transform .28s cubic-bezier(.34,1.5,.64,1)}
2412
+ .knobs-panel .knobs-preset-chip::after{content:"";position:absolute;top:4px;right:4px;width:4px;height:4px;border-radius:50%;background:var(--_k-modified);opacity:0;transform:scale(.4);pointer-events:none;transition:opacity .16s ease-out,transform .28s cubic-bezier(.34,1.5,.64,1)}
990
2413
  .knobs-panel .knobs-preset-chip[data-drifted]::after{opacity:.95;transform:none}
991
2414
  /* Naming a saved preset: a field over its chip that opens out from the middle to the chip's width;
992
2415
  the chip's own name hides beneath it. Leaving, it fades. */
993
2416
  .knobs-panel .knobs-preset-chip[data-naming]{color:transparent!important}
994
- .knobs-panel .knobs-preset-name{position:absolute;z-index:2;box-sizing:border-box;min-width:0;margin:0;padding:0 6px;border:1px solid color-mix(in srgb,var(--k-accent) 55%,transparent);border-radius:var(--k-button-radius,var(--k-radius-md));outline:none;background:color-mix(in srgb,var(--k-accent) 10%,transparent);color:var(--k-text);caret-color:var(--k-accent);
995
- font-family:inherit;font-size:var(--k-button-font-size,var(--k-text-control));font-weight:var(--k-title-weight);letter-spacing:inherit;text-align:center;animation:knobs-name-in .25s cubic-bezier(.2,.8,.2,1);transition:opacity .11s cubic-bezier(.4,0,1,1)}
996
- .knobs-preset-name::selection{background:color-mix(in srgb,var(--k-accent) 24%,transparent);color:var(--k-text)}
2417
+ .knobs-panel .knobs-preset-name{position:absolute;z-index:2;box-sizing:border-box;min-width:0;margin:0;padding:0 6px;border:1px solid color-mix(in srgb,var(--_k-accent) 55%,transparent);border-radius:var(--k-button-radius,var(--_k-radius-md));outline:none;background:color-mix(in srgb,var(--_k-accent) 10%,transparent);color:var(--_k-fg);caret-color:var(--_k-accent);
2418
+ font-family:inherit;font-size:var(--k-button-font-size,var(--_k-text-control));font-weight:var(--_k-weight-title);letter-spacing:inherit;text-align:center;animation:knobs-name-in .25s cubic-bezier(.2,.8,.2,1);transition:opacity .11s cubic-bezier(.4,0,1,1)}
2419
+ .knobs-preset-name::selection{background:color-mix(in srgb,var(--_k-accent) 24%,transparent);color:var(--_k-fg)}
997
2420
  .knobs-panel .knobs-preset-name[data-leaving]{opacity:0;pointer-events:none}
998
2421
  @keyframes knobs-name-in{from{clip-path:inset(0 50% round 6px);opacity:.4}to{clip-path:inset(0 round 6px);opacity:1}}
999
2422
  @media(prefers-reduced-motion:reduce){.knobs-panel .knobs-preset-name{animation:knobs-fade .15s ease-out}}
1000
2423
 
1001
2424
  /* Group headers */
1002
- .knobs-group-head{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:20px;margin:var(--k-group-gap) 0 var(--k-gap);padding:0 var(--k-group-inset);color:var(--k-group-color);font-size:var(--k-group-size);font-weight:var(--k-title-weight);letter-spacing:var(--k-group-tracking);text-transform:var(--k-group-transform)}
2425
+ .knobs-group-head{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:20px;margin:var(--k-group-gap) 0 var(--_k-gap);padding:0 var(--k-group-inset);color:var(--_k-group-label);font-size:var(--k-group-size);font-weight:var(--_k-weight-title);letter-spacing:var(--k-group-tracking);text-transform:var(--k-group-transform)}
1003
2426
  .knobs-panel:not(.knobs-page) .knobs-group-head:not(:first-child){border-top:1px solid var(--k-group-divider);padding-top:var(--k-group-divider-gap)}
1004
2427
  .knobs-group-head:first-child{margin-top:0}
1005
- .knobs-group-head>span:last-child{display:flex;align-items:center;gap:var(--k-tray-pad);margin-right:calc((var(--k-icon-sm) - 20px) / 2)}
1006
- .knobs-group-head button{height:20px;padding:0 6px;font-size:var(--k-text-meta);font-weight:500;letter-spacing:0;text-transform:none;color:var(--k-label);background:transparent;border-radius:var(--k-radius-sm);cursor:pointer}
1007
- .knobs-group-head button:is(:hover:not([disabled]),:focus-visible){background:var(--k-surface-hi);color:var(--k-text)}
1008
- .knobs-group-head .knobs-group-reset{width:20px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--k-round)}
2428
+ .knobs-group-head>span:last-child{display:flex;align-items:center;gap:var(--_k-tray-pad);margin-right:calc((var(--k-icon-sm) - 20px) / 2)}
2429
+ .knobs-group-head button{height:20px;padding:0 6px;font-size:var(--_k-text-meta);font-weight:500;letter-spacing:0;text-transform:none;color:var(--_k-fg-2);background:transparent;border-radius:var(--_k-radius-sm);cursor:pointer}
2430
+ .knobs-group-head button:is(:hover:not([disabled]),:focus-visible){background:var(--_k-fill-selected);color:var(--_k-fg)}
2431
+ .knobs-group-head .knobs-group-reset{width:20px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--_k-round)}
1009
2432
  .knobs-group-head :is(.knobs-icon,.knobs-die-icon){width:var(--k-icon-sm);height:var(--k-icon-sm)}
1010
- .knobs-group-head .knobs-group-die{width:20px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--k-round);color:var(--k-dim)}
2433
+ .knobs-group-head .knobs-group-die{width:20px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--_k-round);color:var(--_k-fg-3)}
1011
2434
  .knobs-group-head .knobs-group-die[disabled]{opacity:var(--k-disabled-opacity);cursor:default}
1012
2435
  .knobs-panel .knobs-group-head button:where(:not(.knobs-group-reset)){transition:background var(--k-hover-t),color var(--k-hover-t),opacity .2s,transform .12s}
1013
2436
 
1014
2437
  /* Grouped cards: rows share one surface, split by hairlines that stay put whatever a row is doing */
1015
- .knobs-card{position:relative;margin-bottom:var(--k-section-gap);border-radius:var(--k-radius);background:var(--k-surface);overflow:hidden}
2438
+ .knobs-card{position:relative;margin-bottom:var(--k-section-gap);border-radius:var(--_k-radius);background:var(--_k-fill);overflow:hidden}
1016
2439
  .knobs-card:last-child{margin-bottom:0}
1017
- .knobs-card>*{position:relative;min-height:var(--k-row);transition:background var(--k-hover-t),opacity .2s}
2440
+ .knobs-card>*{position:relative;min-height:var(--_k-row);transition:background var(--k-hover-t),opacity .2s}
1018
2441
  .knobs-panel [data-tab-opacity]{transition:none!important}
1019
2442
  /* Rubber-band ends (drawStretch in give.ts): past a limit a control stretches about its far end
1020
2443
  and thins a little, its stretching corners rounding off; a row draws past its card's edge
@@ -1023,21 +2446,21 @@ ${GRAD_PROPS}
1023
2446
  .knobs-card[data-k-stretch]{overflow:visible}
1024
2447
  .knobs-card>:first-child{--k-rt:1}
1025
2448
  .knobs-card>:last-child{--k-rb:1}
1026
- .knobs-card>.knobs-stretching{--k-r:var(--k-radius);border-radius:calc(var(--k-r) * var(--k-rt,0)) calc(var(--k-r) * var(--k-rt,0)) calc(var(--k-r) * var(--k-rb,0)) calc(var(--k-r) * var(--k-rb,0))}
2449
+ .knobs-card>.knobs-stretching{--k-r:var(--_k-radius);border-radius:calc(var(--k-r) * var(--k-rt,0)) calc(var(--k-r) * var(--k-rt,0)) calc(var(--k-r) * var(--k-rb,0)) calc(var(--k-r) * var(--k-rb,0))}
1027
2450
  .knobs-card>.knobs-stretching[data-stretch="end"]{border-top-right-radius:calc(var(--k-r) * max(var(--k-rt,0),var(--k-sf)));border-bottom-right-radius:calc(var(--k-r) * max(var(--k-rb,0),var(--k-sf)))}
1028
2451
  .knobs-card>.knobs-stretching[data-stretch="start"]{border-top-left-radius:calc(var(--k-r) * max(var(--k-rt,0),var(--k-sf)));border-bottom-left-radius:calc(var(--k-r) * max(var(--k-rb,0),var(--k-sf)))}
1029
2452
  .knobs-stretching>:is(.knobs-track,.knobs-range-track){border-radius:inherit}
1030
2453
  .knobs-slider.knobs-stretching :is(.knobs-label,.knobs-value),.knobs-range.knobs-stretching .knobs-range-text{scale:calc(1 / var(--k-sx)) calc(1 / var(--k-sy))}
1031
- .knobs-slider.knobs-stretching .knobs-label{transform-origin:calc(var(--k-ox) - var(--k-inset)) 0}
1032
- .knobs-panel .knobs-slider.knobs-stretching .knobs-value{transform-origin:calc(var(--k-ox) - var(--k-w) + var(--k-inset) + 100%) 0}
2454
+ .knobs-slider.knobs-stretching .knobs-label{transform-origin:calc(var(--k-ox) - var(--_k-inset)) 0}
2455
+ .knobs-panel .knobs-slider.knobs-stretching .knobs-value{transform-origin:calc(var(--k-ox) - var(--k-w) + var(--_k-inset) + 100%) 0}
1033
2456
  .knobs-range.knobs-stretching .knobs-range-text{transform-origin:var(--k-sox) 50%}
1034
2457
  .knobs-stretching>:is(.knobs-strip-thumb,.knobs-pad-puck,.knobs-pad-home){transform:scale(calc(1 / var(--k-sx)),calc(1 / var(--k-sy)))}
1035
- .knobs-card>:hover,.knobs-card>.knobs-active{background:var(--k-row-hover)}
1036
- .knobs-card>*+*::before{content:"";position:absolute;z-index:1;left:0;right:0;top:0;height:1px;transform:scaleY(.5);transform-origin:top;background:var(--k-line);pointer-events:none;transition:opacity .15s}
1037
- .knobs-card>::after{content:"";position:absolute;z-index:2;inset:0;background:var(--k-surface-hi);opacity:0;pointer-events:none;transition:opacity .15s,box-shadow .15s}
2458
+ .knobs-card>:hover,.knobs-card>.knobs-active{background:var(--_k-row-hover)}
2459
+ .knobs-card>*+*::before{content:"";position:absolute;z-index:1;left:0;right:0;top:0;height:1px;transform:scaleY(.5);transform-origin:top;background:var(--_k-border);pointer-events:none;transition:opacity .15s}
2460
+ .knobs-card>::after{content:"";position:absolute;z-index:2;inset:0;background:var(--_k-fill-selected);opacity:0;pointer-events:none;transition:opacity .15s,box-shadow .15s}
1038
2461
  /* The card focus is on (a click on its empty area or heading, Esc from a row): a soft wash over all
1039
2462
  of it, for R and ⇧R acting on its group. */
1040
- :is(.knobs-card,.knobs-tile)::after{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--k-surface);opacity:0;pointer-events:none;transition:opacity .2s var(--k-ease)}
2463
+ :is(.knobs-card,.knobs-tile)::after{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--_k-fill);opacity:0;pointer-events:none;transition:opacity .2s var(--k-ease)}
1041
2464
  :is(.knobs-card,.knobs-tile)[data-k-scope]::after{opacity:1}
1042
2465
  .knobs-panel:focus{outline:none}
1043
2466
  .knobs-card>:has(:focus-visible)::after{opacity:1}
@@ -1048,18 +2471,18 @@ ${POINTER_ROW} :is(.knobs-card>*,.knobs-sub,.knobs-x-head):not(:hover)::after{op
1048
2471
  a soft wash and a hairline edge, placed from script (--kl-w, --kl-l). */
1049
2472
  .knobs-panel[data-k-lens] :is(.knobs-card>*,.knobs-sub,.knobs-x-head,.knobs-card,.knobs-tile)::after{opacity:0!important}
1050
2473
  .knobs-lens{position:absolute;left:0;top:0;z-index:2;width:0;height:0;opacity:0;pointer-events:none;box-sizing:border-box;contain:strict;will-change:transform,opacity;
1051
- background:color-mix(in srgb,var(--k-surface-hi) calc(var(--kl-w,0) * 100%),transparent);
1052
- box-shadow:inset 0 0 0 var(--k-rim-width) color-mix(in srgb,var(--k-line-hi) calc(var(--kl-l,0) * 100%),transparent)}
2474
+ background:color-mix(in srgb,var(--_k-fill-selected) calc(var(--kl-w,0) * 100%),transparent);
2475
+ box-shadow:inset 0 0 0 var(--k-rim-width) color-mix(in srgb,var(--_k-border-strong) calc(var(--kl-l,0) * 100%),transparent)}
1053
2476
  .knobs-panel[data-gpu-active="true"] .knobs-lens{visibility:hidden}
1054
- .knobs-panel .knobs-slider{height:var(--k-row);contain:layout style}
1055
- .knobs-panel .knobs-row:where(:not(.knobs-slider,.knobs-x,.knobs-spring)){display:flex;align-items:center;justify-content:space-between;gap:8px;height:var(--k-row);padding:0 var(--k-inset);contain:layout style}
1056
- .knobs-panel .knobs-row>span:first-child{color:var(--k-label);font-weight:var(--k-label-weight);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1057
- .knobs-row>span:first-child::after{content:"";display:inline-block;width:4px;height:4px;margin-left:5px;border-radius:50%;background:var(--k-modified);vertical-align:middle;opacity:0;transform:scale(.4);transition:opacity .16s ease-out,transform .28s cubic-bezier(.34,1.5,.64,1)}
2477
+ .knobs-panel .knobs-slider{height:var(--_k-row);contain:layout style}
2478
+ .knobs-panel .knobs-row:where(:not(.knobs-slider,.knobs-x,.knobs-spring)){display:flex;align-items:center;justify-content:space-between;gap:8px;height:var(--_k-row);padding:0 var(--_k-inset);contain:layout style}
2479
+ .knobs-panel .knobs-row>span:first-child{color:var(--_k-fg-2);font-weight:var(--_k-weight-label);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
2480
+ .knobs-row>span:first-child::after{content:"";display:inline-block;width:4px;height:4px;margin-left:5px;border-radius:50%;background:var(--_k-modified);vertical-align:middle;opacity:0;transform:scale(.4);transition:opacity .16s ease-out,transform .28s cubic-bezier(.34,1.5,.64,1)}
1058
2481
  .knobs-modified.knobs-row>span:first-child::after{opacity:.95;transform:none}
1059
2482
  /* A locked row's lock sits just left of its readout (or its control), where the eye reads the value.
1060
2483
  Its room opens at once (it's right-aligned, so nothing beside it moves); the icon fades and
1061
2484
  scales in place. */
1062
- .knobs-lock{position:relative;flex:none;order:-1;display:inline-block;width:0;height:10px;color:var(--k-dim)}
2485
+ .knobs-lock{position:relative;flex:none;order:-1;display:inline-block;width:0;height:10px;color:var(--_k-fg-3)}
1063
2486
  .knobs-lock>svg{position:absolute;right:0;top:0;width:10px;height:10px;opacity:0;transform:scale(.5);transition:opacity .14s ease-in,transform .14s ease-in}
1064
2487
  .knobs-locked .knobs-lock{width:10px}
1065
2488
  .knobs-value>.knobs-lock>svg{right:6px}
@@ -1073,74 +2496,74 @@ ${POINTER_ROW} :is(.knobs-card>*,.knobs-sub,.knobs-x-head):not(:hover)::after{op
1073
2496
  The ticks and handle fade where the label and readout sit (--k-text-mask). The fill and handle
1074
2497
  are moved by transforms, never layout or background sizes, which snap to whole pixels: the
1075
2498
  edge and the handle's centre both land on the value's exact sub-pixel position, as on the GPU. */
1076
- .knobs-track{position:absolute;left:0;right:0;top:0;height:var(--k-row);overflow:hidden;contain:layout style paint;cursor:ew-resize;user-select:none;touch-action:none;transition:--k-readout .25s var(--k-ease);
1077
- --k-text-mask:linear-gradient(to right,transparent calc(var(--k-label-end,0px) + 4px),#000 calc(var(--k-label-end,0px) + 12px),#000 calc(100% - var(--k-inset) - var(--k-readout) - 12px),transparent calc(100% - var(--k-inset) - var(--k-readout) - 4px))}
2499
+ .knobs-track{position:absolute;left:0;right:0;top:0;height:var(--_k-row);overflow:hidden;contain:layout style paint;cursor:ew-resize;user-select:none;touch-action:none;transition:--k-readout .25s var(--k-ease);
2500
+ --k-text-mask:linear-gradient(to right,transparent calc(var(--k-label-end,0px) + 4px),#000 calc(var(--k-label-end,0px) + 12px),#000 calc(100% - var(--_k-inset) - var(--k-readout) - 12px),transparent calc(100% - var(--_k-inset) - var(--k-readout) - 4px))}
1078
2501
  .knobs-panel .knobs-track:focus-visible{outline:none;box-shadow:none}
1079
2502
  .knobs-marks,.knobs-handle-zone{position:absolute;inset:0;pointer-events:none;-webkit-mask:var(--k-text-mask);mask:var(--k-text-mask)}
1080
2503
  .knobs-marks>i{position:absolute;top:50%;width:1px;height:7px;border-radius:999px;transform:translate(-50%,-50%);background:transparent;transition:background .2s}
1081
- .knobs-fill{position:absolute;inset:0;pointer-events:none;--k-fill-mix:var(--k-fill-rest-mix);--k-fill-tint:color-mix(in srgb,var(--k-accent) var(--k-fill-mix),var(--k-fill-base));
1082
- background:var(--k-fill-tint);transform:translateX(calc(var(--k-fill) - 100%));transition:--k-fill-mix .15s}
1083
- .knobs-slider:hover .knobs-fill{--k-fill-mix:var(--k-fill-hover-mix)}
2504
+ .knobs-fill{position:absolute;inset:0;pointer-events:none;--k-fill-mix:var(--k-fill-rest-mix);--k-fill-tint:color-mix(in srgb,var(--_k-accent) var(--k-fill-mix),var(--_k-fill-base));
2505
+ background:var(--k-fill-tint);transform:translateX(calc(var(--_k-fill-at) - 100%));transition:--k-fill-mix .15s}
2506
+ .knobs-slider:hover .knobs-fill{--k-fill-mix:var(--_k-fill-hover-mix)}
1084
2507
  .knobs-active .knobs-fill,.knobs-active:hover .knobs-fill{--k-fill-mix:var(--k-fill-active-mix)}
1085
2508
  /* --k-motion-blur: a moving edge smears into a ramp as wide as its speed (--k-smear, px), as a
1086
2509
  horizontal box blur would; the handle widens and thins to match. */
1087
- .knobs-smear .knobs-fill{background:linear-gradient(to left,transparent,var(--k-fill-tint) calc(var(--k-smear) * 1px));transform:translateX(calc(var(--k-fill) - 100% + var(--k-smear) * .5px))}
2510
+ .knobs-smear .knobs-fill{background:linear-gradient(to left,transparent,var(--k-fill-tint) calc(var(--k-smear) * 1px));transform:translateX(calc(var(--_k-fill-at) - 100% + var(--k-smear) * .5px))}
1088
2511
  .knobs-smear .knobs-handle::before{scale:calc(1 + var(--k-smear) / 3) 1;opacity:calc(3 / (3 + var(--k-smear)))}
1089
2512
  .knobs-animate .knobs-fill,.knobs-animate .knobs-handle{transition:--k-fill ${SLIDE_T} ${DELAY},--k-fill-mix .15s,opacity .15s}
1090
2513
  /* The default: a short notch rising from the bottom edge, only while the row is in hand. The
1091
2514
  active preset's value hangs one from the top edge. */
1092
- .knobs-marks>.knobs-notch{top:auto;bottom:0;width:1.5px;height:4px;border-radius:999px 999px 0 0;transform:translateX(-50%);background:var(--k-accent);opacity:0;transition:opacity .2s,height .15s var(--k-ease)}
2515
+ .knobs-marks>.knobs-notch{top:auto;bottom:0;width:1.5px;height:4px;border-radius:999px 999px 0 0;transform:translateX(-50%);background:var(--_k-accent);opacity:0;transition:opacity .2s,height .15s var(--k-ease)}
1093
2516
  .knobs-marks>.knobs-base{top:0;bottom:auto;border-radius:0 0 999px 999px}
1094
2517
  .knobs-slider:is(:hover,.knobs-active,:has(:focus-visible)) .knobs-notch{opacity:.38}
1095
2518
  .knobs-slider.knobs-modified:is(:hover,.knobs-active,:has(:focus-visible)) .knobs-notch:not(.knobs-base){opacity:.55}
1096
2519
  .knobs-magnet .knobs-notch:not(.knobs-base),.knobs-held-base .knobs-base{opacity:.95;height:6px}
1097
2520
  /* Precision by distance: a fine ruler around the handle, a level for each halving of the rate,
1098
2521
  each finer, shorter and fainter than the last. */
1099
- .knobs-ruler{position:absolute;inset:0;pointer-events:none;--k-ruler-w:linear-gradient(to right,transparent calc(var(--k-fill) - ${RULER_FADE}px),#000 calc(var(--k-fill) - ${RULER_NEAR}px),#000 calc(var(--k-fill) + ${RULER_NEAR}px),transparent calc(var(--k-fill) + ${RULER_FADE}px));-webkit-mask:var(--k-ruler-w);mask:var(--k-ruler-w)}
2522
+ .knobs-ruler{position:absolute;inset:0;pointer-events:none;--k-ruler-w:linear-gradient(to right,transparent calc(var(--_k-fill-at) - ${RULER_FADE}px),#000 calc(var(--_k-fill-at) - ${RULER_NEAR}px),#000 calc(var(--_k-fill-at) + ${RULER_NEAR}px),transparent calc(var(--_k-fill-at) + ${RULER_FADE}px));-webkit-mask:var(--k-ruler-w);mask:var(--k-ruler-w)}
1100
2523
  .knobs-ruler>i{position:absolute;left:0;right:0;top:50%;opacity:0;translate:-.5px 0;transition:opacity .18s var(--k-ease)}
1101
- ${RULER.map(([n, h, a], i) => `.knobs-ruler>i:nth-child(${i + 1}){height:${h}px;margin-top:${-h / 2}px;background:repeating-linear-gradient(to right,color-mix(in srgb,var(--k-accent) ${a * 100}%,transparent) 0 1px,transparent 1px calc(100% / ${n}))}`).join(`
2524
+ ${RULER.map(([n, h, a], i) => `.knobs-ruler>i:nth-child(${i + 1}){height:${h}px;margin-top:${-h / 2}px;background:repeating-linear-gradient(to right,color-mix(in srgb,var(--_k-accent) ${a * 100}%,transparent) 0 1px,transparent 1px calc(100% / ${n}))}`).join(`
1102
2525
  `)}
1103
2526
  /* The handle is a full-width layer moved by the fill (translate's % is its own width, the track's). */
1104
- .knobs-handle{position:absolute;inset:0;pointer-events:none;transform:translateX(var(--k-fill));opacity:var(--k-handle-rest);transition:opacity .15s}
1105
- .knobs-handle::before{content:"";position:absolute;left:0;top:50%;width:3px;height:calc(var(--k-row) - 12px);margin-top:calc(6px - var(--k-row) / 2);translate:calc(-50% - var(--k-handle-inset)) 0;border-radius:var(--k-round);background:var(--k-handle);
1106
- box-shadow:0 0 calc(var(--k-glow) * 8px) color-mix(in srgb,var(--k-accent) 60%,transparent);transform:scaleX(calc(.25 + .75 * min(1, var(--k-handle-rest) * 4)));transition:transform .22s var(--k-ease)}
2527
+ .knobs-handle{position:absolute;inset:0;pointer-events:none;transform:translateX(var(--_k-fill-at));opacity:var(--k-handle-rest);transition:opacity .15s}
2528
+ .knobs-handle::before{content:"";position:absolute;left:0;top:50%;width:3px;height:calc(var(--_k-row) - 12px);margin-top:calc(6px - var(--_k-row) / 2);translate:calc(-50% - var(--k-handle-inset)) 0;border-radius:var(--_k-round);background:var(--_k-slider-handle);
2529
+ box-shadow:0 0 calc(var(--_k-glow) * 8px) color-mix(in srgb,var(--_k-accent) 60%,transparent);transform:scaleX(calc(.25 + .75 * min(1, var(--k-handle-rest) * 4)));transition:transform .22s var(--k-ease)}
1107
2530
  .knobs-slider:hover .knobs-handle,.knobs-track:focus-visible .knobs-handle{opacity:max(.65,var(--k-handle-rest))}
1108
2531
  .knobs-active .knobs-handle{opacity:.95}
1109
2532
  .knobs-slider:is(:hover,.knobs-active) .knobs-handle::before,.knobs-track:focus-visible .knobs-handle::before{transform:scaleX(1)}
1110
- .knobs-slider:is(:hover,:has(:focus-visible)) .knobs-marks>i:not(.knobs-notch){background:color-mix(in srgb,var(--k-accent) 15%,transparent)}
1111
- .knobs-active .knobs-marks>i:not(.knobs-notch){background:color-mix(in srgb,var(--k-accent) 22%,transparent)}
2533
+ .knobs-slider:is(:hover,:has(:focus-visible)) .knobs-marks>i:not(.knobs-notch){background:color-mix(in srgb,var(--_k-accent) 15%,transparent)}
2534
+ .knobs-active .knobs-marks>i:not(.knobs-notch){background:color-mix(in srgb,var(--_k-accent) 22%,transparent)}
1112
2535
  /* A focused slider the pointer has left for another row rests meanwhile (one row lit at a time). */
1113
2536
  ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-marks>i:not(.knobs-notch){background:transparent}
1114
2537
  ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-notch{opacity:0}
1115
2538
  ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-handle{opacity:var(--k-handle-rest)}
1116
2539
  ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-handle::before{transform:scaleX(calc(.25 + .75 * min(1, var(--k-handle-rest) * 4)))}
1117
- ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-value{color:var(--k-label)}
1118
- ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-value{color:color-mix(in srgb,var(--k-modified) calc(var(--k-readout-mark) * 100%),var(--k-label))}
2540
+ ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-value{color:var(--_k-fg-2)}
2541
+ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-value{color:color-mix(in srgb,var(--_k-modified) calc(var(--k-readout-mark) * 100%),var(--_k-fg-2))}
1119
2542
  .knobs-digits{display:inline-flex;align-items:center;line-height:2.1;margin-block:-.375em;--rn-edge-fade:.5em}
1120
2543
  .knobs-unit{color:var(--k-unit-color);margin-left:var(--k-unit-gap)}
1121
2544
  /* --k-readout-mark (0 or 1): a modified value takes the modified colour behind a small dot. */
1122
- .knobs-value::before{content:"";flex:none;width:calc(5px * var(--k-readout-mark));height:5px;margin-right:calc(6px * var(--k-readout-mark));border-radius:50%;background:var(--k-modified);opacity:0;transform:scale(0);transition:opacity .16s ease,transform .3s cubic-bezier(.34,1.56,.64,1)}
1123
- :is(.knobs-slider,.knobs-sub).knobs-modified .knobs-value{color:color-mix(in srgb,var(--k-modified) calc(var(--k-readout-mark) * 100%),var(--k-label))}
1124
- :is(.knobs-slider,.knobs-sub).knobs-modified:is(.knobs-active,:has(.knobs-track:focus-visible)) .knobs-value{color:color-mix(in srgb,var(--k-modified) calc(var(--k-readout-mark) * 100%),var(--k-text))}
2545
+ .knobs-value::before{content:"";flex:none;width:calc(5px * var(--k-readout-mark));height:5px;margin-right:calc(6px * var(--k-readout-mark));border-radius:50%;background:var(--_k-modified);opacity:0;transform:scale(0);transition:opacity .16s ease,transform .3s cubic-bezier(.34,1.56,.64,1)}
2546
+ :is(.knobs-slider,.knobs-sub).knobs-modified .knobs-value{color:color-mix(in srgb,var(--_k-modified) calc(var(--k-readout-mark) * 100%),var(--_k-fg-2))}
2547
+ :is(.knobs-slider,.knobs-sub).knobs-modified:is(.knobs-active,:has(.knobs-track:focus-visible)) .knobs-value{color:color-mix(in srgb,var(--_k-modified) calc(var(--k-readout-mark) * 100%),var(--_k-fg))}
1125
2548
  :is(.knobs-slider,.knobs-sub).knobs-modified .knobs-value::before{opacity:var(--k-readout-mark);transform:none}
1126
- .knobs-label{position:absolute;left:var(--k-inset);top:50%;transform:translateY(-50%);max-width:calc(100% - var(--k-inset) * 2 - var(--k-readout,48px) - 8px - var(--k-accessory-w,0px));overflow:hidden;text-overflow:ellipsis;color:var(--k-label);font-weight:var(--k-label-weight);pointer-events:none;white-space:nowrap}
1127
- .knobs-panel .knobs-value{position:absolute;right:var(--k-inset);top:50%;transform:translateY(-50%);transform-origin:100% 0;display:inline-flex;align-items:center;justify-content:flex-end;gap:0;padding:4px 0 4px 8px;background:transparent!important;border-radius:0!important;line-height:1.35;overflow:visible;white-space:nowrap;
1128
- color:var(--k-label);font-family:var(--k-value-font);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";font-size:var(--kc-value-size);
2549
+ .knobs-label{position:absolute;left:var(--_k-inset);top:50%;transform:translateY(-50%);max-width:calc(100% - var(--_k-inset) * 2 - var(--k-readout,48px) - 8px - var(--k-accessory-w,0px));overflow:hidden;text-overflow:ellipsis;color:var(--_k-fg-2);font-weight:var(--_k-weight-label);pointer-events:none;white-space:nowrap}
2550
+ .knobs-panel .knobs-value{position:absolute;right:var(--_k-inset);top:50%;transform:translateY(-50%);transform-origin:100% 0;display:inline-flex;align-items:center;justify-content:flex-end;gap:0;padding:4px 0 4px 8px;background:transparent!important;border-radius:0!important;line-height:1.35;overflow:visible;white-space:nowrap;
2551
+ color:var(--_k-fg-2);font-family:var(--_k-value-font);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";font-size:var(--_k-value-size);
1129
2552
  cursor:text;transition:color .15s}
1130
- .knobs-active .knobs-value,.knobs-track:focus-visible .knobs-value{color:var(--k-text)}
2553
+ .knobs-active .knobs-value,.knobs-track:focus-visible .knobs-value{color:var(--_k-fg)}
1131
2554
  /* Editing: the digits' own text, in place (edit() gives it their right edge and width), with no
1132
2555
  box: a soft accent selection, an accent caret, and the unit still after it. */
1133
2556
  .knobs-panel :is(.knobs-number,.knobs-number-fit){position:absolute;top:50%;z-index:2;margin:0;padding:0 1px 0 0;border:0;border-radius:0;background:transparent;box-shadow:none;outline:none;
1134
- font-family:var(--k-value-font);font-size:var(--kc-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";letter-spacing:normal;line-height:1.35;text-align:right;white-space:pre}
1135
- .knobs-panel .knobs-number{transform:translateY(-50%);color:var(--k-text);caret-color:var(--k-accent)}
1136
- .knobs-number::selection{background:color-mix(in srgb,var(--k-accent) 24%,transparent);color:var(--k-text)}
2557
+ font-family:var(--_k-value-font);font-size:var(--_k-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";letter-spacing:normal;line-height:1.35;text-align:right;white-space:pre}
2558
+ .knobs-panel .knobs-number{transform:translateY(-50%);color:var(--_k-fg);caret-color:var(--_k-accent)}
2559
+ .knobs-number::selection{background:color-mix(in srgb,var(--_k-accent) 24%,transparent);color:var(--_k-fg)}
1137
2560
  .knobs-panel .knobs-number-fit{left:0;visibility:hidden;pointer-events:none}
1138
2561
  .knobs-editing .knobs-digits{visibility:hidden}
1139
2562
  .knobs-editing .knobs-value{pointer-events:none}
1140
2563
 
1141
2564
  /* Segmented choice */
1142
- .knobs-seg{position:relative;display:flex;flex-wrap:nowrap;align-items:center;justify-content:flex-end;gap:var(--k-tray-pad);height:var(--kc-control-h);padding:var(--k-tray-pad);max-width:76%;background:var(--k-seg-bg);border-radius:var(--k-radius-md)}
1143
- .knobs-seg-pill{position:absolute;top:var(--k-tray-pad);bottom:var(--k-tray-pad);left:0;right:100%;border-radius:var(--k-radius-sm);background:var(--k-pill-bg);box-shadow:var(--k-lift-shadow);pointer-events:none;
2565
+ .knobs-seg{position:relative;display:flex;flex-wrap:nowrap;align-items:center;justify-content:flex-end;gap:var(--_k-tray-pad);height:var(--_k-control-h);padding:var(--_k-tray-pad);max-width:76%;background:var(--_k-segmented-track);border-radius:var(--_k-radius-md)}
2566
+ .knobs-seg-pill{position:absolute;top:var(--_k-tray-pad);bottom:var(--_k-tray-pad);left:0;right:100%;border-radius:var(--_k-radius-sm);background:var(--k-pill-bg);box-shadow:var(--_k-shadow-raised);pointer-events:none;
1144
2567
  transition:left ${TRAIL_T} ${DELAY},right ${LEAD_T} ${DELAY},opacity .15s}
1145
2568
  .knobs-seg-pill[data-dir="left"]{transition:left ${LEAD_T} ${DELAY},right ${TRAIL_T} ${DELAY},opacity .15s}
1146
2569
  .knobs-seg-pill[data-off]{opacity:0}
@@ -1148,107 +2571,107 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1148
2571
  .knobs-smear-pill{margin-inline:calc(var(--k-smear) * -.5px);
1149
2572
  -webkit-mask:linear-gradient(to right,transparent,#000 calc(var(--k-smear) * 1px),#000 calc(100% - var(--k-smear) * 1px),transparent);
1150
2573
  mask:linear-gradient(to right,transparent,#000 calc(var(--k-smear) * 1px),#000 calc(100% - var(--k-smear) * 1px),transparent)}
1151
- .knobs-seg button{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;height:100%;padding:0 7px;font-size:var(--k-text-control);font-weight:var(--k-label-weight);white-space:nowrap;color:var(--k-label);background:transparent;cursor:pointer;border-radius:var(--k-radius-sm);transition:background var(--k-hover-t),color var(--k-hover-t)}
1152
- .knobs-seg button:is(:hover,:focus-visible){color:var(--k-text)}
1153
- .knobs-seg button[aria-checked=true]{color:var(--k-text)}
2574
+ .knobs-seg button{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;height:100%;padding:0 7px;font-size:var(--_k-text-control);font-weight:var(--_k-weight-label);white-space:nowrap;color:var(--_k-fg-2);background:transparent;cursor:pointer;border-radius:var(--_k-radius-sm);transition:background var(--k-hover-t),color var(--k-hover-t)}
2575
+ .knobs-seg button:is(:hover,:focus-visible){color:var(--_k-fg)}
2576
+ .knobs-seg button[aria-checked=true]{color:var(--_k-fg)}
1154
2577
 
1155
2578
  /* Long choices: a compact button that drops down a menu */
1156
- .knobs-panel .knobs-select{position:relative;display:inline-flex;align-items:center;gap:6px;min-width:0;max-width:62%;height:var(--kc-control-h);padding:0 6px 0 10px;background:var(--k-seg-bg);border-radius:var(--k-radius-md);color:var(--k-label);font-size:var(--k-text-control);font-weight:var(--k-label-weight);cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t)}
1157
- .knobs-panel .knobs-select:is(:hover,:focus-visible,[aria-expanded="true"]),.knobs-panel .knobs-active>.knobs-select{background:var(--k-surface-hi);color:var(--k-text)}
2579
+ .knobs-panel .knobs-select{position:relative;display:inline-flex;align-items:center;gap:6px;min-width:0;max-width:62%;height:var(--_k-control-h);padding:0 6px 0 10px;background:var(--_k-segmented-track);border-radius:var(--_k-radius-md);color:var(--_k-fg-2);font-size:var(--_k-text-control);font-weight:var(--_k-weight-label);cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t)}
2580
+ .knobs-panel .knobs-select:is(:hover,:focus-visible,[aria-expanded="true"]),.knobs-panel .knobs-active>.knobs-select{background:var(--_k-fill-selected);color:var(--_k-fg)}
1158
2581
  .knobs-select-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1159
2582
  .knobs-panel .knobs-row-full .knobs-select{flex:1;max-width:none;justify-content:space-between}
1160
- .knobs-select .knobs-icon{width:calc(var(--k-icon-sm) - 2px);height:calc(var(--k-icon-sm) - 2px);color:var(--k-dim)}
2583
+ .knobs-select .knobs-icon{width:calc(var(--k-icon-sm) - 2px);height:calc(var(--k-icon-sm) - 2px);color:var(--_k-fg-3)}
1161
2584
  .knobs-menu[data-checks] .knobs-menu-item{padding-left:24px}
1162
2585
  .knobs-menu-item[aria-checked="true"]::before{content:"";position:absolute;left:9px;top:50%;width:7px;height:4px;margin-top:-3.5px;border:solid currentColor;border-width:0 0 1.5px 1.5px;transform:rotate(-45deg)}
1163
2586
 
1164
2587
  /* Action rows: a button the width of the row */
1165
2588
  .knobs-panel .knobs-action-row{padding:0}
1166
- .knobs-panel .knobs-action{width:100%;height:100%;padding:0 var(--k-inset);text-align:left;background:transparent;border-radius:0;color:var(--k-button-color,var(--k-text));font-size:var(--k-button-font-size,calc(var(--k-text-control) + .5px));font-weight:var(--k-label-weight);cursor:pointer;transition:color var(--k-hover-t),background var(--k-hover-t),box-shadow var(--k-hover-t)}
1167
- .knobs-panel .knobs-action:is(:hover,:focus-visible){color:var(--k-accent)}
2589
+ .knobs-panel .knobs-action{width:100%;height:100%;padding:0 var(--_k-inset);text-align:left;background:transparent;border-radius:0;color:var(--k-button-color,var(--_k-fg));font-size:var(--k-button-font-size,calc(var(--_k-text-control) + .5px));font-weight:var(--_k-weight-label);cursor:pointer;transition:color var(--k-hover-t),background var(--k-hover-t),box-shadow var(--k-hover-t)}
2590
+ .knobs-panel .knobs-action:is(:hover,:focus-visible){color:var(--_k-accent)}
1168
2591
  .knobs-panel .knobs-action:is(:active,.knobs-pressed){opacity:.7}
1169
- .knobs-panel .knobs-action.knobs-pressed{color:var(--k-accent)}
2592
+ .knobs-panel .knobs-action.knobs-pressed{color:var(--_k-accent)}
1170
2593
  /* A shortcut: its key cap at the row's end, the button taking the rest. */
1171
2594
  .knobs-panel .knobs-action-row[data-keyed]{gap:6px}
1172
2595
  .knobs-panel .knobs-action-row[data-keyed]>.knobs-action{flex:1 1 0;width:auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1173
- .knobs-panel .knobs-action-row>.knobs-keys{order:1;margin-right:var(--k-inset)}
2596
+ .knobs-panel .knobs-action-row>.knobs-keys{order:1;margin-right:var(--_k-inset)}
1174
2597
  /* With a button fill or outline (--k-button-bg, --k-button-line), an action is a sized button in
1175
2598
  its row, and the presets strip a row of them, as toolbar buttons are. */
1176
- .knobs-panel[data-buttons] .knobs-action-row{padding:0 var(--k-inset)}
2599
+ .knobs-panel[data-buttons] .knobs-action-row{padding:0 var(--_k-inset)}
1177
2600
  .knobs-panel[data-buttons] .knobs-action-row[data-keyed]>.knobs-action{flex:0 1 auto;margin-right:auto}
1178
2601
  .knobs-panel[data-buttons] .knobs-action-row>.knobs-keys{margin-right:0}
1179
- .knobs-panel[data-buttons] .knobs-action{width:auto;max-width:100%;height:var(--k-button-h,var(--kc-control-h));padding:0 10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
1180
- background:var(--k-button-bg,transparent);box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);border-radius:var(--k-button-radius,var(--k-radius-md))}
1181
- .knobs-panel[data-buttons] .knobs-action:is(:hover,:focus-visible){color:var(--k-text);background:var(--k-button-hover-bg,var(--k-surface-hi));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent))}
2602
+ .knobs-panel[data-buttons] .knobs-action{width:auto;max-width:100%;height:var(--k-button-h,var(--_k-control-h));padding:0 10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
2603
+ background:var(--k-button-bg,transparent);box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);border-radius:var(--k-button-radius,var(--_k-radius-md))}
2604
+ .knobs-panel[data-buttons] .knobs-action:is(:hover,:focus-visible){color:var(--_k-fg);background:var(--k-button-hover-bg,var(--_k-fill-selected));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent))}
1182
2605
 
1183
2606
  /* Switch */
1184
2607
  /* The thumb spans two edges: the leading one springs ahead and the other follows, so it stretches
1185
2608
  into a capsule as it travels; a press widens it toward where it will go. */
1186
- .knobs-panel .knobs-toggle{position:relative;flex:none;width:32px;height:18px;padding:0;background:var(--k-toggle-track);border-radius:var(--k-round);cursor:pointer;transition:background .2s ${DELAY},box-shadow .2s ${DELAY}}
1187
- .knobs-panel .knobs-toggle[aria-checked=true]{background:var(--k-accent);box-shadow:0 0 calc(var(--k-glow) * 10px) color-mix(in srgb,var(--k-accent) 42%,transparent)}
1188
- .knobs-toggle i{position:absolute;top:var(--k-tray-pad);bottom:var(--k-tray-pad);left:var(--k-tray-pad);right:16px;border-radius:var(--k-round);background:var(--k-thumb);box-shadow:0 1px 2px rgba(0,0,0,calc(.25 * var(--k-lift)));transition:left ${LEAD_T} ${DELAY},right ${TRAIL_T} ${DELAY},background .2s ${DELAY}}
1189
- .knobs-toggle[aria-checked=true] i{left:16px;right:var(--k-tray-pad);background:var(--k-toggle-thumb);transition:left ${TRAIL_T} ${DELAY},right ${LEAD_T} ${DELAY},background .2s ${DELAY}}
2609
+ .knobs-panel .knobs-toggle{position:relative;flex:none;width:32px;height:18px;padding:0;background:var(--_k-toggle-track);border-radius:var(--_k-round);cursor:pointer;transition:background .2s ${DELAY},box-shadow .2s ${DELAY}}
2610
+ .knobs-panel .knobs-toggle[aria-checked=true]{background:var(--_k-accent);box-shadow:0 0 calc(var(--_k-glow) * 10px) color-mix(in srgb,var(--_k-accent) 42%,transparent)}
2611
+ .knobs-toggle i{position:absolute;top:var(--_k-tray-pad);bottom:var(--_k-tray-pad);left:var(--_k-tray-pad);right:16px;border-radius:var(--_k-round);background:var(--_k-toggle-thumb-off);box-shadow:0 1px 2px rgba(0,0,0,calc(.25 * var(--k-lift)));transition:left ${LEAD_T} ${DELAY},right ${TRAIL_T} ${DELAY},background .2s ${DELAY}}
2612
+ .knobs-toggle[aria-checked=true] i{left:16px;right:var(--_k-tray-pad);background:var(--_k-toggle-thumb);transition:left ${TRAIL_T} ${DELAY},right ${LEAD_T} ${DELAY},background .2s ${DELAY}}
1190
2613
  .knobs-toggle:active i{right:12px;transition:right ${LEAD_T},background .2s}
1191
- .knobs-toggle[aria-checked=true]:active i{left:12px;right:var(--k-tray-pad);transition:left ${LEAD_T},background .2s}
2614
+ .knobs-toggle[aria-checked=true]:active i{left:12px;right:var(--_k-tray-pad);transition:left ${LEAD_T},background .2s}
1192
2615
 
1193
2616
  /* Compound rows: a spring's two sliders beside its curve; disclosure rows with an editor body */
1194
2617
  .knobs-card>:is(.knobs-spring,.knobs-x):hover{background:transparent}
1195
2618
  .knobs-card>:is(.knobs-spring,.knobs-x):has(:focus-visible)::after{opacity:0}
1196
2619
  /* Selected rows: one accent-tinted wash, joined across neighbours. */
1197
- .knobs-panel .knobs-card>.knobs-selected{background:color-mix(in srgb,var(--k-accent) 10%,transparent)}
2620
+ .knobs-panel .knobs-card>.knobs-selected{background:color-mix(in srgb,var(--_k-accent) 10%,transparent)}
1198
2621
  .knobs-card>.knobs-selected+.knobs-selected::before{opacity:0}
1199
2622
  .knobs-spring{display:flex}
1200
2623
  .knobs-spring-tracks{position:relative;flex:1;min-width:0;overflow:hidden}
1201
2624
  .knobs-sub{position:relative;transition:background var(--k-hover-t)}
1202
- .knobs-sub:hover,.knobs-sub.knobs-active,.knobs-x-head:hover,.knobs-x-head[data-panned]{background:var(--k-row-hover)}
1203
- .knobs-sub+.knobs-sub::before{content:"";position:absolute;z-index:1;left:0;right:0;top:0;height:1px;transform:scaleY(.5);transform-origin:top;background:var(--k-line);pointer-events:none;transition:opacity .15s}
1204
- :is(.knobs-sub,.knobs-x-head)::after{content:"";position:absolute;z-index:2;inset:0;background:var(--k-surface-hi);opacity:0;pointer-events:none;transition:opacity .15s}
2625
+ .knobs-sub:hover,.knobs-sub.knobs-active,.knobs-x-head:hover,.knobs-x-head[data-panned]{background:var(--_k-row-hover)}
2626
+ .knobs-sub+.knobs-sub::before{content:"";position:absolute;z-index:1;left:0;right:0;top:0;height:1px;transform:scaleY(.5);transform-origin:top;background:var(--_k-border);pointer-events:none;transition:opacity .15s}
2627
+ :is(.knobs-sub,.knobs-x-head)::after{content:"";position:absolute;z-index:2;inset:0;background:var(--_k-fill-selected);opacity:0;pointer-events:none;transition:opacity .15s}
1205
2628
  :is(.knobs-sub:has(:focus-visible),.knobs-x-head:focus-visible)::after{opacity:1}
1206
- .knobs-spring-curve{position:relative;flex:none;width:calc(var(--k-row) * 2.5);margin:var(--k-gap) var(--k-inset) var(--k-gap) 0;border-radius:var(--k-radius-sm);background:var(--k-seg-bg);pointer-events:none}
2629
+ .knobs-spring-curve{position:relative;flex:none;width:calc(var(--_k-row) * 2.5);margin:var(--_k-gap) var(--_k-inset) var(--_k-gap) 0;border-radius:var(--_k-radius-sm);background:var(--_k-segmented-track);pointer-events:none}
1207
2630
  .knobs-panel :is(.knobs-spring-curve,.knobs-ease)>svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
1208
- .knobs-guide{fill:none;stroke:var(--k-line);stroke-width:1}
1209
- .knobs-arm{fill:none;stroke:var(--k-dim);stroke-width:1}
1210
- .knobs-curve{fill:none;stroke:var(--k-accent);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;transition:d ${FILL_T} ${DELAY}}
1211
- .knobs-spring-dot{position:absolute;left:0;top:0;width:5px;height:5px;margin:-2.5px;border-radius:50%;background:var(--k-accent);box-shadow:0 0 calc(var(--k-glow) * 8px) var(--k-accent);opacity:0;scale:var(--k-curve-dot)}
1212
- .knobs-guide-dashed{stroke:var(--k-line-hi)}
2631
+ .knobs-guide{fill:none;stroke:var(--_k-border);stroke-width:1}
2632
+ .knobs-arm{fill:none;stroke:var(--_k-fg-3);stroke-width:1}
2633
+ .knobs-curve{fill:none;stroke:var(--_k-accent);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;transition:d ${FILL_T} ${DELAY}}
2634
+ .knobs-spring-dot{position:absolute;left:0;top:0;width:5px;height:5px;margin:-2.5px;border-radius:50%;background:var(--_k-accent);box-shadow:0 0 calc(var(--_k-glow) * 8px) var(--_k-accent);opacity:0;scale:var(--k-curve-dot)}
2635
+ .knobs-guide-dashed{stroke:var(--_k-border-strong)}
1213
2636
  .knobs-spring:has(.knobs-active) .knobs-curve{transition:none}
1214
2637
 
1215
2638
  .knobs-panel :is(input,textarea,[contenteditable]){-webkit-user-select:text;user-select:text}
1216
- .knobs-x-head{position:relative;display:flex;align-items:center;justify-content:space-between;gap:8px;height:var(--k-row);padding:0 var(--k-inset);cursor:pointer;user-select:none;transition:background var(--k-hover-t)}
2639
+ .knobs-x-head{position:relative;display:flex;align-items:center;justify-content:space-between;gap:8px;height:var(--_k-row);padding:0 var(--_k-inset);cursor:pointer;user-select:none;transition:background var(--k-hover-t)}
1217
2640
  .knobs-x-head[data-panned]{cursor:ew-resize}
1218
2641
  .knobs-panel .knobs-x-head:focus-visible{outline:none;box-shadow:none}
1219
- .knobs-x-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--k-label);font-weight:var(--k-label-weight)}
1220
- .knobs-x-label::after{content:"";display:inline-block;width:4px;height:4px;margin-left:5px;border-radius:50%;background:var(--k-modified);vertical-align:middle;opacity:0;transform:scale(.4);transition:opacity .16s ease-out,transform .28s cubic-bezier(.34,1.5,.64,1)}
2642
+ .knobs-x-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--_k-fg-2);font-weight:var(--_k-weight-label)}
2643
+ .knobs-x-label::after{content:"";display:inline-block;width:4px;height:4px;margin-left:5px;border-radius:50%;background:var(--_k-modified);vertical-align:middle;opacity:0;transform:scale(.4);transition:opacity .16s ease-out,transform .28s cubic-bezier(.34,1.5,.64,1)}
1221
2644
  .knobs-modified .knobs-x-label::after{opacity:.95;transform:none}
1222
2645
  .knobs-x-sum{display:flex;align-items:center;gap:8px;min-width:0}
1223
- .knobs-x-read,.knobs-strip-read{color:var(--k-label);font-size:var(--kc-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap}
2646
+ .knobs-x-read,.knobs-strip-read{color:var(--_k-fg-2);font-size:var(--_k-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap}
1224
2647
  /* A name crossfading (reel.ts fadeText): the old one fades out over the new, where it was. */
1225
2648
  .knobs-x-read{position:relative}
1226
2649
  .knobs-ghost{position:absolute;right:0;top:0;white-space:nowrap;pointer-events:none}
1227
- .knobs-caret{width:10px;height:10px;flex:none;margin-right:-2.5px;color:var(--k-dim);transition:transform ${LEAD_T},color .15s}
2650
+ .knobs-caret{width:10px;height:10px;flex:none;margin-right:-2.5px;color:var(--_k-fg-3);transition:transform ${LEAD_T},color .15s}
1228
2651
  .knobs-caret path{fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
1229
- .knobs-x-head:hover .knobs-caret{color:var(--k-label)}
2652
+ .knobs-x-head:hover .knobs-caret{color:var(--_k-fg-2)}
1230
2653
  .knobs-x-head[aria-expanded="true"] .knobs-caret{transform:rotate(90deg)}
1231
- .knobs-swatch{flex:none;width:var(--k-track-h);height:var(--k-track-h);border-radius:var(--k-radius-sm);box-shadow:inset 0 0 0 1px var(--k-line);transition:background-color .2s ${DELAY}}
1232
- .knobs-x-body{padding:0 var(--k-inset) var(--k-inset)}
2654
+ .knobs-swatch{flex:none;width:var(--k-track-h);height:var(--k-track-h);border-radius:var(--_k-radius-sm);box-shadow:inset 0 0 0 1px var(--_k-border);transition:background-color .2s ${DELAY}}
2655
+ .knobs-x-body{padding:0 var(--_k-inset) var(--_k-inset)}
1233
2656
  .knobs-strips{display:grid}
1234
2657
  .knobs-strip{display:grid;grid-template-columns:10px 1fr 36px;align-items:center;gap:8px;height:var(--k-action-h)}
1235
- .knobs-strip-label{color:var(--k-dim);font-size:var(--k-text-cap);font-weight:var(--k-title-weight);text-align:left}
2658
+ .knobs-strip-label{color:var(--_k-fg-3);font-size:var(--_k-text-cap);font-weight:var(--_k-weight-title);text-align:left}
1236
2659
  .knobs-strip-read{text-align:right}
1237
- .knobs-strip-track{position:relative;height:var(--k-track-h);border-radius:var(--k-round);box-shadow:inset 0 0 0 1px var(--k-line);cursor:ew-resize;touch-action:none}
1238
- .knobs-strip-thumb{position:absolute;top:50%;left:0;width:calc(var(--k-row) - 12px);height:calc(var(--k-row) - 12px);margin:calc(6px - var(--k-row) / 2);border-radius:var(--k-round);box-shadow:0 0 0 2px var(--k-thumb),0 1px 4px rgba(0,0,0,calc(.4 * var(--k-lift)));pointer-events:none;transition:left ${FILL_T} ${DELAY},background-color .2s ${DELAY},scale .2s var(--k-ease)}
2660
+ .knobs-strip-track{position:relative;height:var(--k-track-h);border-radius:var(--_k-round);box-shadow:inset 0 0 0 1px var(--_k-border);cursor:ew-resize;touch-action:none}
2661
+ .knobs-strip-thumb{position:absolute;top:50%;left:0;width:calc(var(--_k-row) - 12px);height:calc(var(--_k-row) - 12px);margin:calc(6px - var(--_k-row) / 2);border-radius:var(--_k-round);box-shadow:0 0 0 2px var(--_k-toggle-thumb-off),0 1px 4px rgba(0,0,0,calc(.4 * var(--k-lift)));pointer-events:none;transition:left ${FILL_T} ${DELAY},background-color .2s ${DELAY},scale .2s var(--k-ease)}
1239
2662
  .knobs-strip.knobs-active .knobs-strip-thumb{transition:background-color .2s,scale .2s var(--k-ease)}
1240
2663
  .knobs-strip:is(.knobs-active,:has(:focus-visible)) .knobs-strip-thumb{scale:1.1}
1241
- .knobs-pad,.knobs-ease{position:relative;border-radius:var(--k-radius-md);background:var(--k-seg-bg);touch-action:none}
1242
- .knobs-pad{height:calc(var(--k-row) * 4);cursor:crosshair;overflow:hidden}
2664
+ .knobs-pad,.knobs-ease{position:relative;border-radius:var(--_k-radius-md);background:var(--_k-segmented-track);touch-action:none}
2665
+ .knobs-pad{height:calc(var(--_k-row) * 4);cursor:crosshair;overflow:hidden}
1243
2666
  .knobs-pad>i{position:absolute;left:0;top:0;pointer-events:none;transition:translate ${FILL_T} ${DELAY},scale .2s var(--k-ease)}
1244
- .knobs-pad-v{bottom:0;width:1px;margin-left:-.5px;background:var(--k-line)}
1245
- .knobs-pad-h{right:0;height:1px;margin-top:-.5px;background:var(--k-line)}
1246
- .knobs-pad .knobs-pad-home{width:7px;height:7px;margin:-3.5px;border-radius:50%;box-shadow:inset 0 0 0 1px var(--k-dim);transition:none}
1247
- .knobs-pad-puck{width:12px;height:12px;margin:-6px;border-radius:var(--k-round);background:var(--k-accent);box-shadow:0 0 0 1.5px var(--k-bg),0 0 calc(var(--k-glow) * 10px) color-mix(in srgb,var(--k-accent) 50%,transparent)}
2667
+ .knobs-pad-v{bottom:0;width:1px;margin-left:-.5px;background:var(--_k-border)}
2668
+ .knobs-pad-h{right:0;height:1px;margin-top:-.5px;background:var(--_k-border)}
2669
+ .knobs-pad .knobs-pad-home{width:7px;height:7px;margin:-3.5px;border-radius:50%;box-shadow:inset 0 0 0 1px var(--_k-fg-3);transition:none}
2670
+ .knobs-pad-puck{width:12px;height:12px;margin:-6px;border-radius:var(--_k-round);background:var(--_k-accent);box-shadow:0 0 0 1.5px var(--_k-bg),0 0 calc(var(--_k-glow) * 10px) color-mix(in srgb,var(--_k-accent) 50%,transparent)}
1248
2671
  .knobs-pad.knobs-active>i{transition:scale .2s var(--k-ease)}
1249
2672
  .knobs-pad:is(.knobs-active,:focus-visible) .knobs-pad-puck{scale:1.2}
1250
- .knobs-ease{height:calc(var(--k-row) * 4.5)}
1251
- .knobs-panel .knobs-ease-handle{position:absolute;left:0;top:0;width:12px;height:12px;margin:-6px;padding:0;border-radius:var(--k-round);background:var(--k-bg);box-shadow:inset 0 0 0 2px var(--k-accent),0 1px 3px rgba(0,0,0,calc(.3 * var(--k-lift)));cursor:grab;touch-action:none;transition:scale .2s var(--k-ease)}
2673
+ .knobs-ease{height:calc(var(--_k-row) * 4.5)}
2674
+ .knobs-panel .knobs-ease-handle{position:absolute;left:0;top:0;width:12px;height:12px;margin:-6px;padding:0;border-radius:var(--_k-round);background:var(--_k-bg);box-shadow:inset 0 0 0 2px var(--_k-accent),0 1px 3px rgba(0,0,0,calc(.3 * var(--k-lift)));cursor:grab;touch-action:none;transition:scale .2s var(--k-ease)}
1252
2675
  .knobs-ease-handle::before{content:"";position:absolute;inset:-8px;border-radius:50%}
1253
2676
  /* The row's morph moves the curve, arms and handles each frame (ramp-morph.ts), so they don't
1254
2677
  transition. */
@@ -1256,18 +2679,18 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1256
2679
  .knobs-ease-handle:active{scale:1.2;cursor:grabbing}
1257
2680
  .knobs-ease-handle:focus-visible{scale:1.2}
1258
2681
  .knobs-ease-mini{flex:none;width:30px;height:var(--k-track-h);overflow:visible}
1259
- .knobs-ease-chips{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--k-tray-pad);margin-top:6px;padding:var(--k-tray-pad);border-radius:var(--k-radius-md);background:var(--k-seg-bg)}
1260
- .knobs-panel .knobs-ease-chip{min-width:0;height:calc(var(--k-row) - 10px);padding:0 6px;font-size:var(--k-text-control);font-weight:var(--k-label-weight);color:var(--k-label);background:transparent;border-radius:var(--k-radius-sm);cursor:pointer;white-space:nowrap;transition:background var(--k-hover-t),color var(--k-hover-t),box-shadow .15s}
1261
- .knobs-panel .knobs-ease-chip:is(:hover,:focus-visible){color:var(--k-text)}
1262
- .knobs-panel .knobs-ease-chip[aria-checked="true"]{color:var(--k-text);background:var(--k-pill-bg);box-shadow:var(--k-lift-shadow)}
2682
+ .knobs-ease-chips{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--_k-tray-pad);margin-top:6px;padding:var(--_k-tray-pad);border-radius:var(--_k-radius-md);background:var(--_k-segmented-track)}
2683
+ .knobs-panel .knobs-ease-chip{min-width:0;height:calc(var(--_k-row) - 10px);padding:0 6px;font-size:var(--_k-text-control);font-weight:var(--_k-weight-label);color:var(--_k-fg-2);background:transparent;border-radius:var(--_k-radius-sm);cursor:pointer;white-space:nowrap;transition:background var(--k-hover-t),color var(--k-hover-t),box-shadow .15s}
2684
+ .knobs-panel .knobs-ease-chip:is(:hover,:focus-visible){color:var(--_k-fg)}
2685
+ .knobs-panel .knobs-ease-chip[aria-checked="true"]{color:var(--_k-fg);background:var(--k-pill-bg);box-shadow:var(--_k-shadow-raised)}
1263
2686
 
1264
2687
  /* Gradients: a swatch strip with stop ticks in the head; a wide strip with a handle per stop (the
1265
2688
  selected one full size), then that stop's colour strips. The ramp runs a handle's radius in from
1266
2689
  each end, as the colour strips' do. */
1267
- .knobs-grad-mini{position:relative;flex:none;width:calc(var(--k-row) * 2.5);height:var(--k-track-h);border-radius:var(--k-radius-sm);box-shadow:inset 0 0 0 1px var(--k-line);background:${GRAD_MINI}}
1268
- .knobs-grad-mini>i{position:absolute;top:calc(100% + 2px);left:0;width:1px;height:3px;margin-left:-.5px;background:var(--k-dim);scale:1 var(--kgs-grow,1);transform-origin:top;transition:opacity .15s}
1269
- .knobs-grad{--kg-h:calc(var(--k-row) - 6px);--kg-r:calc(var(--kg-h) / 2);--kg-pin:round(calc(var(--kg-h) * .42),1px);position:relative;height:var(--kg-h);margin:2px 0 var(--k-gap);border-radius:var(--k-round);box-shadow:inset 0 0 0 1px var(--k-line);background:${GRAD_STRIP};cursor:pointer;touch-action:none;user-select:none;outline:none}
1270
- .knobs-grad-stop{position:absolute;top:50%;left:0;width:var(--kg-pin);height:calc(var(--kg-h) - 4px);margin:calc(2px - var(--kg-h) / 2) 0 0 calc(var(--kg-pin) / -2);border-radius:var(--k-round);box-shadow:0 0 0 2px var(--k-thumb),0 1px 4px rgba(0,0,0,calc(.4 * var(--k-lift)));pointer-events:none;
2690
+ .knobs-grad-mini{position:relative;flex:none;width:calc(var(--_k-row) * 2.5);height:var(--k-track-h);border-radius:var(--_k-radius-sm);box-shadow:inset 0 0 0 1px var(--_k-border);background:${GRAD_MINI}}
2691
+ .knobs-grad-mini>i{position:absolute;top:calc(100% + 2px);left:0;width:1px;height:3px;margin-left:-.5px;background:var(--_k-fg-3);scale:1 var(--kgs-grow,1);transform-origin:top;transition:opacity .15s}
2692
+ .knobs-grad{--kg-h:calc(var(--_k-row) - 6px);--kg-r:calc(var(--kg-h) / 2);--kg-pin:round(calc(var(--kg-h) * .42),1px);position:relative;height:var(--kg-h);margin:2px 0 var(--_k-gap);border-radius:var(--_k-round);box-shadow:inset 0 0 0 1px var(--_k-border);background:${GRAD_STRIP};cursor:pointer;touch-action:none;user-select:none;outline:none}
2693
+ .knobs-grad-stop{position:absolute;top:50%;left:0;width:var(--kg-pin);height:calc(var(--kg-h) - 4px);margin:calc(2px - var(--kg-h) / 2) 0 0 calc(var(--kg-pin) / -2);border-radius:var(--_k-round);box-shadow:0 0 0 2px var(--_k-toggle-thumb-off),0 1px 4px rgba(0,0,0,calc(.4 * var(--k-lift)));pointer-events:none;
1271
2694
  --kgs-sel:.78;scale:calc(var(--kgs-sel) * var(--kgs-grow,1));transition:--kgs-sel .2s var(--k-ease),opacity .15s}
1272
2695
  /* The row's morph moves the strip, stops and ticks each frame (ramp-morph.ts), so none transition
1273
2696
  but a stop's focus scale (--kgs-sel); its growth (--kgs-grow) buds it from the strip or merges it
@@ -1286,42 +2709,42 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1286
2709
  /* Curves: a mini curve in the head; a graph with a grid, points (the selected one filled) and a
1287
2710
  hover crosshair whose readout sits in the corner. */
1288
2711
  .knobs-curve-mini{flex:none;width:36px;height:var(--k-track-h);overflow:visible}
1289
- .knobs-graph{position:relative;height:calc(var(--k-row) * 4.5);border-radius:var(--k-radius-md);background:var(--k-seg-bg);cursor:crosshair;touch-action:none;user-select:none;outline:none;overflow:hidden}
2712
+ .knobs-graph{position:relative;height:calc(var(--_k-row) * 4.5);border-radius:var(--_k-radius-md);background:var(--_k-segmented-track);cursor:crosshair;touch-action:none;user-select:none;outline:none;overflow:hidden}
1290
2713
  .knobs-panel .knobs-graph>svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
1291
2714
  .knobs-graph>i{position:absolute;left:0;top:0;pointer-events:none}
1292
2715
  /* The row's morph places the line and points each frame (ramp-morph.ts), so neither transitions:
1293
2716
  a point's size is its focus scale (--kpt-sel, which does) times its growth (--kpt-grow, budding
1294
2717
  from the line or merging into a neighbour). */
1295
- .knobs-graph-pt{width:10px;height:10px;margin:-5px;border-radius:var(--k-round);background:var(--k-bg);box-shadow:inset 0 0 0 2px var(--k-accent),0 1px 3px rgba(0,0,0,calc(.3 * var(--k-lift)));
2718
+ .knobs-graph-pt{width:10px;height:10px;margin:-5px;border-radius:var(--_k-round);background:var(--_k-bg);box-shadow:inset 0 0 0 2px var(--_k-accent),0 1px 3px rgba(0,0,0,calc(.3 * var(--k-lift)));
1296
2719
  scale:calc(var(--kpt-sel) * var(--kpt-grow,1));transition:background-color .15s,--kpt-sel .2s var(--k-ease),opacity .15s}
1297
- .knobs-graph-pt[data-selected]{background:var(--k-accent)}
2720
+ .knobs-graph-pt[data-selected]{background:var(--_k-accent)}
1298
2721
  .knobs-graph:is(:focus-visible,.knobs-active) .knobs-graph-pt[data-selected]{--kpt-sel:1.2}
1299
2722
  .knobs-graph-pt[data-leaving]{opacity:.35;--kpt-sel:.7}
1300
2723
  .knobs-graph .knobs-curve,.knobs-curve-mini .knobs-curve{transition:none}
1301
2724
  .knobs-graph :is(.knobs-graph-v,.knobs-graph-h,.knobs-graph-dot,.knobs-graph-read){opacity:0;transition:opacity .15s}
1302
2725
  .knobs-graph[data-hover] :is(.knobs-graph-v,.knobs-graph-h,.knobs-graph-dot,.knobs-graph-read){opacity:1}
1303
- .knobs-graph-v{bottom:0;width:1px;margin-left:-.5px;background:var(--k-line-hi)}
1304
- .knobs-graph-h{right:0;height:1px;margin-top:-.5px;background:var(--k-line-hi)}
1305
- .knobs-graph-dot{width:5px;height:5px;margin:-2.5px;border-radius:50%;background:var(--k-accent)}
1306
- .knobs-graph-read{position:absolute;top:4px;right:4px;padding:1px 5px;border-radius:var(--k-radius-sm);background:var(--k-bg);color:var(--k-label);font-family:var(--k-value-font);font-size:var(--kc-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap;pointer-events:none}
2726
+ .knobs-graph-v{bottom:0;width:1px;margin-left:-.5px;background:var(--_k-border-strong)}
2727
+ .knobs-graph-h{right:0;height:1px;margin-top:-.5px;background:var(--_k-border-strong)}
2728
+ .knobs-graph-dot{width:5px;height:5px;margin:-2.5px;border-radius:50%;background:var(--_k-accent)}
2729
+ .knobs-graph-read{position:absolute;top:4px;right:4px;padding:1px 5px;border-radius:var(--_k-radius-sm);background:var(--_k-bg);color:var(--_k-fg-2);font-family:var(--_k-value-font);font-size:var(--_k-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap;pointer-events:none}
1307
2730
  .knobs-mixed :is(.knobs-curve-mini,.knobs-graph .knobs-curve,.knobs-graph-pt){opacity:0}
1308
2731
 
1309
2732
  /* Rows as separate bars (--k-row-gap above 0): each row carries its own surface, no hairlines.
1310
2733
  A spring stacks its curve over its two sliders. */
1311
2734
  .knobs-panel[data-rows] .knobs-card{display:flex;flex-direction:column;gap:var(--k-row-gap);background:transparent;overflow:visible}
1312
- .knobs-panel[data-rows] .knobs-card>*{background:var(--k-surface);border-radius:var(--k-radius);overflow:hidden;--k-rt:1;--k-rb:1}
1313
- .knobs-panel[data-rows] .knobs-card>:is(:hover,.knobs-active){background:color-mix(in srgb,var(--k-surface-hi) 50%,var(--k-surface))}
2735
+ .knobs-panel[data-rows] .knobs-card>*{background:var(--_k-fill);border-radius:var(--_k-radius);overflow:hidden;--k-rt:1;--k-rb:1}
2736
+ .knobs-panel[data-rows] .knobs-card>:is(:hover,.knobs-active){background:color-mix(in srgb,var(--_k-fill-selected) 50%,var(--_k-fill))}
1314
2737
  .knobs-panel[data-rows] :is(.knobs-card>*,.knobs-sub)::before{display:none}
1315
2738
  .knobs-panel[data-rows] .knobs-card>.knobs-subhead{background:transparent}
1316
2739
  .knobs-panel[data-rows] .knobs-card>.knobs-spring{flex-direction:column-reverse;gap:var(--k-row-gap);background:transparent;overflow:visible}
1317
2740
  .knobs-panel[data-rows] .knobs-spring-tracks{display:flex;flex-direction:column;gap:var(--k-row-gap);overflow:visible}
1318
- .knobs-panel[data-rows] .knobs-sub{background:var(--k-surface);border-radius:var(--k-radius);overflow:hidden}
1319
- .knobs-panel[data-rows] .knobs-sub:is(:hover,.knobs-active){background:color-mix(in srgb,var(--k-surface-hi) 50%,var(--k-surface))}
1320
- .knobs-panel[data-rows] .knobs-spring-curve{width:auto;height:calc(var(--k-row) * 2.8);margin:0;border-radius:var(--k-radius);background:var(--k-surface)}
2741
+ .knobs-panel[data-rows] .knobs-sub{background:var(--_k-fill);border-radius:var(--_k-radius);overflow:hidden}
2742
+ .knobs-panel[data-rows] .knobs-sub:is(:hover,.knobs-active){background:color-mix(in srgb,var(--_k-fill-selected) 50%,var(--_k-fill))}
2743
+ .knobs-panel[data-rows] .knobs-spring-curve{width:auto;height:calc(var(--_k-row) * 2.8);margin:0;border-radius:var(--_k-radius);background:var(--_k-fill)}
1321
2744
  /* --k-frame: flat. Groups are plain sections: no card surfaces, rows split by hairlines and a
1322
2745
  hairline over every group's label but the first. An inline panel sheds its own card and
1323
2746
  padding too, for a host's column or card, so nothing draws a card inside a card. */
1324
- :where(.knobs-panel)[data-frame="flat"]{--k-group-divider:var(--k-line);--k-group-divider-gap:var(--k-gap)}
2747
+ :where(.knobs-panel)[data-frame="flat"]{--k-group-divider:var(--_k-border);--k-group-divider-gap:var(--_k-gap)}
1325
2748
  :where(.knobs-panel.knobs-inline:not(.knobs-page))[data-frame="flat"]{--k-chrome:0;--k-pad:0px}
1326
2749
  .knobs-panel[data-frame="flat"] .knobs-card{background:transparent;border-radius:0}
1327
2750
  .knobs-panel[data-frame="flat"][data-rows] .knobs-card>*,.knobs-panel[data-frame="flat"][data-rows] .knobs-sub{background:transparent;border-radius:0}
@@ -1335,9 +2758,9 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1335
2758
  .knobs-slider:is([data-disabled],[data-readonly]):hover:not(:has(:focus-visible)) :is(.knobs-handle,.knobs-marks>i){opacity:var(--k-handle-rest);background-color:transparent}
1336
2759
  .knobs-slider:is([data-disabled],[data-readonly]):hover:not(:has(:focus-visible)) .knobs-handle::before{transform:scaleX(calc(.25 + .75 * min(1, var(--k-handle-rest) * 4)))}
1337
2760
  .knobs-panel :is([data-disabled],[data-readonly]) .knobs-value:hover{border-bottom-color:transparent}
1338
- .knobs-panel :is([data-disabled],[data-readonly]) .knobs-seg button:not([aria-checked=true]):hover{color:var(--k-label)}
1339
- .knobs-panel :is([data-disabled],[data-readonly]) .knobs-action:hover:not(:focus-visible){color:var(--k-text)}
1340
- .knobs-panel :is([data-disabled],[data-readonly]) .knobs-select:hover:not(:focus-visible){background:var(--k-seg-bg);color:var(--k-label)}
2761
+ .knobs-panel :is([data-disabled],[data-readonly]) .knobs-seg button:not([aria-checked=true]):hover{color:var(--_k-fg-2)}
2762
+ .knobs-panel :is([data-disabled],[data-readonly]) .knobs-action:hover:not(:focus-visible){color:var(--_k-fg)}
2763
+ .knobs-panel :is([data-disabled],[data-readonly]) .knobs-select:hover:not(:focus-visible){background:var(--_k-segmented-track);color:var(--_k-fg-2)}
1341
2764
  /* A mixed value (a multi-selection whose items differ) reads "—" until it's edited. */
1342
2765
  .knobs-mixed :is(.knobs-fill,.knobs-handle-zone,.knobs-marks){opacity:0}
1343
2766
  .knobs-panel .knobs-mixed .knobs-value>:is(.knobs-digits,.knobs-unit,.knobs-lock){display:none}
@@ -1346,63 +2769,63 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1346
2769
  .knobs-panel .knobs-toggle[aria-checked="mixed"] i{left:calc(50% - 7px);right:calc(50% - 7px)}
1347
2770
 
1348
2771
  /* Tabs: text over a hairline; the chosen one's underline slides to it, its leading edge first. */
1349
- .knobs-tabs{position:relative;display:flex;align-items:stretch;gap:calc(var(--k-unit) * 4);margin:0 0 var(--k-section-gap);padding:0 var(--k-inset);overflow:hidden;transition:opacity .2s var(--k-ease)}
1350
- .knobs-tabs::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;transform:scaleY(.5);transform-origin:bottom;background:var(--k-line);pointer-events:none}
1351
- .knobs-panel .knobs-tab{flex:none;height:calc(var(--k-row) - var(--k-unit));padding:0;background:transparent;border-radius:0;font-size:var(--k-text-control);font-weight:var(--k-label-weight);color:var(--k-label);white-space:nowrap;cursor:pointer;transition:color .15s}
1352
- .knobs-panel .knobs-tab:is(:hover,:focus-visible),.knobs-panel .knobs-tab[aria-selected="true"]{color:var(--k-text)}
1353
- .knobs-tabs-bar{position:absolute;bottom:0;left:0;right:100%;height:1.5px;border-radius:1px;background:var(--k-accent);pointer-events:none;transition:left ${TRAIL_T},right ${LEAD_T}}
2772
+ .knobs-tabs{position:relative;display:flex;align-items:stretch;gap:calc(var(--_k-unit) * 4);margin:0 0 var(--k-section-gap);padding:0 var(--_k-inset);overflow:hidden;transition:opacity .2s var(--k-ease)}
2773
+ .knobs-tabs::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;transform:scaleY(.5);transform-origin:bottom;background:var(--_k-border);pointer-events:none}
2774
+ .knobs-panel .knobs-tab{flex:none;height:calc(var(--_k-row) - var(--_k-unit));padding:0;background:transparent;border-radius:0;font-size:var(--_k-text-control);font-weight:var(--_k-weight-label);color:var(--_k-fg-2);white-space:nowrap;cursor:pointer;transition:color .15s}
2775
+ .knobs-panel .knobs-tab:is(:hover,:focus-visible),.knobs-panel .knobs-tab[aria-selected="true"]{color:var(--_k-fg)}
2776
+ .knobs-tabs-bar{position:absolute;bottom:0;left:0;right:100%;height:1.5px;border-radius:1px;background:var(--_k-accent);pointer-events:none;transition:left ${TRAIL_T},right ${LEAD_T}}
1354
2777
  .knobs-tabs-bar[data-dir="left"]{transition:left ${LEAD_T},right ${TRAIL_T}}
1355
2778
  /* A search spans every tab, so the strip steps back while it's on. */
1356
2779
  .knobs-panel[data-searching] .knobs-tabs{opacity:.4}
1357
2780
 
1358
2781
  /* Search: a field and its filter chips. Matches show in labels by colour alone. */
1359
- .knobs-search{display:flex;align-items:center;gap:var(--k-tray-pad);margin:0 0 var(--k-section-gap)}
1360
- .knobs-search-field{flex:1;min-width:0;display:flex;align-items:center;gap:6px;height:var(--kc-control-h);padding:0 8px;background:var(--k-seg-bg);border-radius:var(--k-radius-md);color:var(--k-dim);cursor:text}
2782
+ .knobs-search{display:flex;align-items:center;gap:var(--_k-tray-pad);margin:0 0 var(--k-section-gap)}
2783
+ .knobs-search-field{flex:1;min-width:0;display:flex;align-items:center;gap:6px;height:var(--_k-control-h);padding:0 8px;background:var(--_k-segmented-track);border-radius:var(--_k-radius-md);color:var(--_k-fg-3);cursor:text}
1361
2784
  .knobs-search-field>.knobs-icon{width:calc(var(--k-icon-sm) - 2px);height:calc(var(--k-icon-sm) - 2px)}
1362
- .knobs-panel .knobs-search input{flex:1;min-width:0;height:100%;padding:0;background:transparent;border-radius:0;color:var(--k-text);font-size:var(--k-text-control);-webkit-appearance:none;appearance:none}
1363
- .knobs-panel .knobs-search input::placeholder{color:var(--k-dim)}
2785
+ .knobs-panel .knobs-search input{flex:1;min-width:0;height:100%;padding:0;background:transparent;border-radius:0;color:var(--_k-fg);font-size:var(--_k-text-control);-webkit-appearance:none;appearance:none}
2786
+ .knobs-panel .knobs-search input::placeholder{color:var(--_k-fg-3)}
1364
2787
  .knobs-panel .knobs-search input::-webkit-search-cancel-button{display:none}
1365
- .knobs-panel .knobs-search-chip{flex:none;display:inline-flex;align-items:center;gap:5px;height:var(--kc-control-h);padding:0 8px;background:transparent;border-radius:var(--k-radius-md);box-shadow:inset 0 0 0 1px var(--k-line);color:var(--k-label);font-size:var(--k-text-meta);font-weight:var(--k-label-weight);white-space:nowrap;cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t),box-shadow .15s,opacity .15s}
1366
- .knobs-panel .knobs-search-chip:is(:hover,:focus-visible){color:var(--k-text);box-shadow:inset 0 0 0 1px var(--k-line-hi)}
1367
- .knobs-panel .knobs-search-chip[aria-pressed="true"]{background:var(--k-pill-bg);box-shadow:inset 0 0 0 1px var(--k-pill-border);color:var(--k-text)}
2788
+ .knobs-panel .knobs-search-chip{flex:none;display:inline-flex;align-items:center;gap:5px;height:var(--_k-control-h);padding:0 8px;background:transparent;border-radius:var(--_k-radius-md);box-shadow:inset 0 0 0 1px var(--_k-border);color:var(--_k-fg-2);font-size:var(--_k-text-meta);font-weight:var(--_k-weight-label);white-space:nowrap;cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t),box-shadow .15s,opacity .15s}
2789
+ .knobs-panel .knobs-search-chip:is(:hover,:focus-visible){color:var(--_k-fg);box-shadow:inset 0 0 0 1px var(--_k-border-strong)}
2790
+ .knobs-panel .knobs-search-chip[aria-pressed="true"]{background:var(--k-pill-bg);box-shadow:inset 0 0 0 1px var(--k-pill-border);color:var(--_k-fg)}
1368
2791
  .knobs-panel .knobs-search-chip[data-none]{opacity:.5}
1369
- .knobs-search-count{color:var(--k-dim);font-variant-numeric:tabular-nums}
1370
- .knobs-search-chip[aria-pressed="true"] .knobs-search-count{color:var(--k-label)}
1371
- .knobs-panel mark.knobs-match{background:none;color:var(--k-accent)}
2792
+ .knobs-search-count{color:var(--_k-fg-3);font-variant-numeric:tabular-nums}
2793
+ .knobs-search-chip[aria-pressed="true"] .knobs-search-count{color:var(--_k-fg-2)}
2794
+ .knobs-panel mark.knobs-match{background:none;color:var(--_k-accent)}
1372
2795
  .knobs-panel[data-gpu-active="true"] .knobs-search{position:relative;z-index:2147480003}
1373
2796
 
1374
2797
  /* Sub-headings: a flat heading inside the group's card, split off by the card's hairline. */
1375
- .knobs-panel .knobs-card>.knobs-subhead{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:0;height:calc(var(--k-row) - var(--k-unit) * 2);padding:0 var(--k-inset);color:var(--k-label);font-size:var(--k-text-meta);font-weight:var(--k-title-weight);cursor:pointer;user-select:none}
2798
+ .knobs-panel .knobs-card>.knobs-subhead{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:0;height:calc(var(--_k-row) - var(--_k-unit) * 2);padding:0 var(--_k-inset);color:var(--_k-fg-2);font-size:var(--_k-text-meta);font-weight:var(--_k-weight-title);cursor:pointer;user-select:none}
1376
2799
  .knobs-subhead-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1377
2800
  .knobs-subhead[aria-expanded="true"] .knobs-caret{transform:rotate(90deg)}
1378
- .knobs-subhead:hover .knobs-caret{color:var(--k-label)}
2801
+ .knobs-subhead:hover .knobs-caret{color:var(--_k-fg-2)}
1379
2802
  .knobs-card>.knobs-subhead:focus-visible::after{opacity:1}
1380
2803
 
1381
2804
  /* Inspector rows: number cells, ranges, dials, seeds and key combinations. */
1382
2805
  .knobs-panel .knobs-insp{gap:8px}
1383
2806
  .knobs-panel .knobs-insp[data-kind="vec"]>span:first-child{flex-shrink:0;max-width:34%}
1384
- .knobs-cells{flex:0 1 auto;display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:var(--k-tray-pad);width:calc(var(--k-row) * 5);max-width:64%}
1385
- .knobs-cells[data-wide]{width:calc(var(--k-row) * 7.5);max-width:72%}
1386
- .knobs-cell{position:relative;display:flex;align-items:center;justify-content:space-between;gap:3px;min-width:0;height:var(--kc-control-h);padding:0 5px;border-radius:var(--k-radius-md);background:var(--k-seg-bg);cursor:ew-resize;user-select:none;touch-action:none;outline:none;transition:background var(--k-hover-t)}
1387
- .knobs-cell:hover,.knobs-cell:focus-visible{background:color-mix(in srgb,var(--k-surface-hi) 70%,var(--k-seg-bg))}
1388
- .knobs-active .knobs-cell:focus,.knobs-cell[data-panned]{background:var(--k-surface-hi)}
1389
- .knobs-cell-axis{flex:none;font-style:normal;font-size:var(--k-text-cap);font-weight:var(--k-title-weight);color:var(--k-dim)}
1390
- .knobs-cell-read,.knobs-range-read,.knobs-angle-read,.knobs-seed-read{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--k-label);font-family:var(--k-value-font);font-size:var(--kc-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
1391
- .knobs-cell:focus-visible .knobs-cell-read,.knobs-active .knobs-cell:focus .knobs-cell-read,.knobs-cell[data-panned] .knobs-cell-read{color:var(--k-text)}
1392
- .knobs-panel .knobs-link{flex:none;width:20px;height:20px;margin:0 -4px 0 auto;padding:0;display:inline-flex;align-items:center;justify-content:center;background:transparent;border-radius:var(--k-round);color:var(--k-dim);cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t)}
1393
- .knobs-panel .knobs-link:hover{background:var(--k-surface-hi);color:var(--k-text)}
1394
- .knobs-panel .knobs-link[aria-pressed="true"]{color:var(--k-text)}
2807
+ .knobs-cells{flex:0 1 auto;display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:var(--_k-tray-pad);width:calc(var(--_k-row) * 5);max-width:64%}
2808
+ .knobs-cells[data-wide]{width:calc(var(--_k-row) * 7.5);max-width:72%}
2809
+ .knobs-cell{position:relative;display:flex;align-items:center;justify-content:space-between;gap:3px;min-width:0;height:var(--_k-control-h);padding:0 5px;border-radius:var(--_k-radius-md);background:var(--_k-segmented-track);cursor:ew-resize;user-select:none;touch-action:none;outline:none;transition:background var(--k-hover-t)}
2810
+ .knobs-cell:hover,.knobs-cell:focus-visible{background:color-mix(in srgb,var(--_k-fill-selected) 70%,var(--_k-segmented-track))}
2811
+ .knobs-active .knobs-cell:focus,.knobs-cell[data-panned]{background:var(--_k-fill-selected)}
2812
+ .knobs-cell-axis{flex:none;font-style:normal;font-size:var(--_k-text-cap);font-weight:var(--_k-weight-title);color:var(--_k-fg-3)}
2813
+ .knobs-cell-read,.knobs-range-read,.knobs-angle-read,.knobs-seed-read{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--_k-fg-2);font-family:var(--_k-value-font);font-size:var(--_k-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
2814
+ .knobs-cell:focus-visible .knobs-cell-read,.knobs-active .knobs-cell:focus .knobs-cell-read,.knobs-cell[data-panned] .knobs-cell-read{color:var(--_k-fg)}
2815
+ .knobs-panel .knobs-link{flex:none;width:20px;height:20px;margin:0 -4px 0 auto;padding:0;display:inline-flex;align-items:center;justify-content:center;background:transparent;border-radius:var(--_k-round);color:var(--_k-fg-3);cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t)}
2816
+ .knobs-panel .knobs-link:hover{background:var(--_k-fill-selected);color:var(--_k-fg)}
2817
+ .knobs-panel .knobs-link[aria-pressed="true"]{color:var(--_k-fg)}
1395
2818
  .knobs-link .knobs-icon{width:var(--k-icon-sm);height:var(--k-icon-sm)}
1396
2819
  /* The inline editor over a readout: above the GPU canvas, which leaves that readout to it. */
1397
- .knobs-panel .knobs-cell-edit{position:absolute;z-index:3;right:calc(var(--k-inset) - 6px);top:50%;transform:translateY(-50%);width:calc(7ch + 12px);height:var(--kc-control-h);padding:0 6px;text-align:right;background:linear-gradient(var(--k-surface-hi),var(--k-surface-hi)),var(--k-bg);border:0;border-radius:var(--k-radius-md);outline:none;color:var(--k-text);caret-color:var(--k-accent);font-family:var(--k-value-font);font-variant-numeric:tabular-nums;font-size:var(--kc-value-size);animation:knobs-fade .12s ease-out}
2820
+ .knobs-panel .knobs-cell-edit{position:absolute;z-index:3;right:calc(var(--_k-inset) - 6px);top:50%;transform:translateY(-50%);width:calc(7ch + 12px);height:var(--_k-control-h);padding:0 6px;text-align:right;background:linear-gradient(var(--_k-fill-selected),var(--_k-fill-selected)),var(--_k-bg);border:0;border-radius:var(--_k-radius-md);outline:none;color:var(--_k-fg);caret-color:var(--_k-accent);font-family:var(--_k-value-font);font-variant-numeric:tabular-nums;font-size:var(--_k-value-size);animation:knobs-fade .12s ease-out}
1398
2821
  .knobs-cell.knobs-editing>:not(.knobs-cell-edit){visibility:hidden}
1399
2822
  .knobs-panel .knobs-cell>.knobs-cell-edit{inset:0;width:auto;height:auto;transform:none}
1400
2823
  .knobs-panel[data-gpu-active="true"] .knobs-cell-edit{z-index:2147480003}
1401
2824
 
1402
- .knobs-panel .knobs-row.knobs-range{display:block;height:var(--k-row);padding:0}
1403
- .knobs-range-track{position:absolute;inset:0;overflow:hidden;cursor:ew-resize;user-select:none;touch-action:none;transition:--kr-lo ${FILL_T} ${DELAY},--kr-hi ${FILL_T} ${DELAY};--kr-tint:var(--k-fill-rest)}
2825
+ .knobs-panel .knobs-row.knobs-range{display:block;height:var(--_k-row);padding:0}
2826
+ .knobs-range-track{position:absolute;inset:0;overflow:hidden;cursor:ew-resize;user-select:none;touch-action:none;transition:--kr-lo ${FILL_T} ${DELAY},--kr-hi ${FILL_T} ${DELAY};--kr-tint:var(--_k-slider-fill)}
1404
2827
  .knobs-range-fill{position:absolute;inset:0;transform-origin:0 0;transform:scaleX(0);background:var(--kr-tint);pointer-events:none;transition:transform ${FILL_T} ${DELAY},background .15s}
1405
- .knobs-range:hover .knobs-range-track{--kr-tint:color-mix(in srgb,var(--k-accent) var(--k-fill-hover-mix),var(--k-fill-base))}
2828
+ .knobs-range:hover .knobs-range-track{--kr-tint:color-mix(in srgb,var(--_k-accent) var(--_k-fill-hover-mix),var(--_k-fill-base))}
1406
2829
  .knobs-range.knobs-active .knobs-range-track{--kr-tint:var(--k-fill-active)}
1407
2830
  /* --k-range-blur: while the ends glide, the band is a gradient in the track's space whose ends ramp
1408
2831
  over their smears (--kr-smear-lo/hi, px; see inspector.ts), standing in for the scaled fill. */
@@ -1421,41 +2844,41 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1421
2844
  .knobs-range:not(.knobs-mixed):hover .knobs-range-text{--kr-show-lo:1;--kr-show-hi:1}
1422
2845
  .knobs-range:not(.knobs-mixed)[data-end-focus="lo"]:is([data-k-fv],.knobs-active) .knobs-range-text{--kr-show-lo:1}
1423
2846
  .knobs-range:not(.knobs-mixed)[data-end-focus="hi"]:is([data-k-fv],.knobs-active) .knobs-range-text{--kr-show-hi:1}
1424
- .knobs-range-thumb::before{content:"";position:absolute;left:0;top:50%;width:3px;height:calc(var(--k-row) - 12px);margin-top:calc(6px - var(--k-row) / 2);translate:-50% 0;border-radius:var(--k-round);background:var(--k-handle);opacity:0;scale:.25 1;transition:opacity .15s,scale .22s var(--k-ease)}
2847
+ .knobs-range-thumb::before{content:"";position:absolute;left:0;top:50%;width:3px;height:calc(var(--_k-row) - 12px);margin-top:calc(6px - var(--_k-row) / 2);translate:-50% 0;border-radius:var(--_k-round);background:var(--_k-slider-handle);opacity:0;scale:.25 1;transition:opacity .15s,scale .22s var(--k-ease)}
1425
2848
  .knobs-range:hover .knobs-range-thumb::before{opacity:.5}
1426
2849
  .knobs-range-thumb:focus-visible::before,.knobs-range.knobs-active .knobs-range-thumb:focus::before{opacity:.95;scale:1}
1427
- .knobs-range .knobs-label{max-width:calc(55% - var(--k-inset))}
1428
- .knobs-range-read{position:absolute;right:var(--k-inset);top:50%;transform:translateY(-50%);pointer-events:none}
1429
- .knobs-range.knobs-active .knobs-range-read,.knobs-range:has(:focus-visible) .knobs-range-read{color:var(--k-text)}
1430
- .knobs-range.knobs-modified .knobs-range-read{color:color-mix(in srgb,var(--k-modified) calc(var(--k-readout-mark) * 100%),var(--k-label))}
2850
+ .knobs-range .knobs-label{max-width:calc(55% - var(--_k-inset))}
2851
+ .knobs-range-read{position:absolute;right:var(--_k-inset);top:50%;transform:translateY(-50%);pointer-events:none}
2852
+ .knobs-range.knobs-active .knobs-range-read,.knobs-range:has(:focus-visible) .knobs-range-read{color:var(--_k-fg)}
2853
+ .knobs-range.knobs-modified .knobs-range-read{color:color-mix(in srgb,var(--_k-modified) calc(var(--k-readout-mark) * 100%),var(--_k-fg-2))}
1431
2854
  .knobs-range.knobs-editing .knobs-range-read{opacity:0}
1432
2855
 
1433
- .knobs-angle{display:inline-flex;align-items:center;gap:8px;height:var(--kc-control-h);margin-left:auto;cursor:ew-resize;user-select:none;touch-action:none;outline:none}
1434
- .knobs-angle:focus-visible .knobs-angle-read,.knobs-active .knobs-angle-read{color:var(--k-text)}
1435
- .knobs-dial{position:relative;flex:none;width:var(--kc-control-h);height:var(--kc-control-h);border-radius:50%;background:var(--k-seg-bg);box-shadow:inset 0 0 0 1px var(--k-line);cursor:grab;transition:box-shadow .15s}
1436
- .knobs-angle:is(:hover,:focus-visible) .knobs-dial,.knobs-active .knobs-dial{box-shadow:inset 0 0 0 1px var(--k-line-hi)}
2856
+ .knobs-angle{display:inline-flex;align-items:center;gap:8px;height:var(--_k-control-h);margin-left:auto;cursor:ew-resize;user-select:none;touch-action:none;outline:none}
2857
+ .knobs-angle:focus-visible .knobs-angle-read,.knobs-active .knobs-angle-read{color:var(--_k-fg)}
2858
+ .knobs-dial{position:relative;flex:none;width:var(--_k-control-h);height:var(--_k-control-h);border-radius:50%;background:var(--_k-segmented-track);box-shadow:inset 0 0 0 1px var(--_k-border);cursor:grab;transition:box-shadow .15s}
2859
+ .knobs-angle:is(:hover,:focus-visible) .knobs-dial,.knobs-active .knobs-dial{box-shadow:inset 0 0 0 1px var(--_k-border-strong)}
1437
2860
  .knobs-active .knobs-dial{cursor:grabbing}
1438
- .knobs-dial::after{content:"";position:absolute;left:50%;top:50%;width:3px;height:3px;margin:-1.5px;border-radius:50%;background:var(--k-accent)}
1439
- .knobs-dial-hand{position:absolute;left:50%;top:18%;bottom:50%;width:1.5px;margin-left:-.75px;border-radius:1px;background:var(--k-accent);transform-origin:50% 100%;transition:rotate ${FILL_T} ${DELAY}}
2861
+ .knobs-dial::after{content:"";position:absolute;left:50%;top:50%;width:3px;height:3px;margin:-1.5px;border-radius:50%;background:var(--_k-accent)}
2862
+ .knobs-dial-hand{position:absolute;left:50%;top:18%;bottom:50%;width:1.5px;margin-left:-.75px;border-radius:1px;background:var(--_k-accent);transform-origin:50% 100%;transition:rotate ${FILL_T} ${DELAY}}
1440
2863
  .knobs-active .knobs-dial-hand{transition:none}
1441
2864
  .knobs-insp.knobs-editing .knobs-angle-read,.knobs-insp.knobs-editing .knobs-seed-read{opacity:0}
1442
2865
 
1443
2866
  .knobs-panel .knobs-insp[data-kind="seed"]{gap:2px}
1444
- .knobs-seed{display:inline-flex;align-items:center;height:var(--kc-control-h);margin-left:auto;padding:0 4px;border-radius:var(--k-radius-sm);cursor:text;outline:none}
1445
- .knobs-seed:focus-visible .knobs-seed-read,.knobs-active>.knobs-seed .knobs-seed-read{color:var(--k-text)}
2867
+ .knobs-seed{display:inline-flex;align-items:center;height:var(--_k-control-h);margin-left:auto;padding:0 4px;border-radius:var(--_k-radius-sm);cursor:text;outline:none}
2868
+ .knobs-seed:focus-visible .knobs-seed-read,.knobs-active>.knobs-seed .knobs-seed-read{color:var(--_k-fg)}
1446
2869
  .knobs-seed-digits{display:inline-flex;align-items:center;line-height:2.1;margin-block:-.375em;--rn-edge-fade:.5em}
1447
2870
  .knobs-seed-read{display:inline-flex;align-items:center}
1448
2871
  .knobs-seed-read[data-mixed]::before{content:"—"}
1449
2872
  .knobs-seed-read[data-mixed]>.knobs-seed-digits{display:none}
1450
- .knobs-panel .knobs-seed-roll{flex:none;width:var(--k-icon-btn);height:var(--k-icon-btn);padding:0;display:inline-flex;align-items:center;justify-content:center;background:transparent;border-radius:var(--k-round);color:var(--k-dim);cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t)}
1451
- .knobs-panel .knobs-seed-roll:hover{background:var(--k-surface-hi);color:var(--k-text)}
2873
+ .knobs-panel .knobs-seed-roll{flex:none;width:var(--k-icon-btn);height:var(--k-icon-btn);padding:0;display:inline-flex;align-items:center;justify-content:center;background:transparent;border-radius:var(--_k-round);color:var(--_k-fg-3);cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t)}
2874
+ .knobs-panel .knobs-seed-roll:hover{background:var(--_k-fill-selected);color:var(--_k-fg)}
1452
2875
  .knobs-seed-roll .knobs-die-icon{width:var(--k-icon-sm);height:var(--k-icon-sm)}
1453
2876
 
1454
- .knobs-panel .knobs-keys{flex:none;display:inline-flex;align-items:center;justify-content:center;max-width:62%;height:var(--kc-control-h);padding:0 8px;overflow:hidden;background:var(--k-seg-bg);border-radius:var(--k-radius-md);color:var(--k-text);font-family:inherit;font-weight:inherit;font-size:var(--kc-value-size);letter-spacing:.08em;white-space:nowrap;cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t)}
1455
- .knobs-panel .knobs-keys:is(:hover,:focus-visible){background:color-mix(in srgb,var(--k-surface-hi) 70%,var(--k-seg-bg))}
1456
- .knobs-panel .knobs-keys[data-empty]{color:var(--k-dim);letter-spacing:0}
2877
+ .knobs-panel .knobs-keys{flex:none;display:inline-flex;align-items:center;justify-content:center;max-width:62%;height:var(--_k-control-h);padding:0 8px;overflow:hidden;background:var(--_k-segmented-track);border-radius:var(--_k-radius-md);color:var(--_k-fg);font-family:inherit;font-weight:inherit;font-size:var(--_k-value-size);letter-spacing:.08em;white-space:nowrap;cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t)}
2878
+ .knobs-panel .knobs-keys:is(:hover,:focus-visible){background:color-mix(in srgb,var(--_k-fill-selected) 70%,var(--_k-segmented-track))}
2879
+ .knobs-panel .knobs-keys[data-empty]{color:var(--_k-fg-3);letter-spacing:0}
1457
2880
  /* Listening: a soft accent wash, no ring, and the text breathing in "Type keys…" (keyCap). */
1458
- .knobs-panel .knobs-keys[aria-pressed="true"]{background:var(--k-pill-bg);color:var(--k-label)}
2881
+ .knobs-panel .knobs-keys[aria-pressed="true"]{background:var(--k-pill-bg);color:var(--_k-fg-2)}
1459
2882
  .knobs-keys[aria-pressed="true"] .knobs-keys-text{animation:knobs-breathe 1.6s ease-in-out infinite}
1460
2883
  @keyframes knobs-breathe{50%{opacity:.55}}
1461
2884
  .knobs-keys-text{min-width:0;overflow:hidden;text-overflow:ellipsis}
@@ -1466,35 +2889,35 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1466
2889
  /* Toolbars: icon, label and shortcut per button, in equal columns balanced across their rows
1467
2890
  (inspector.ts sets --k-tool-cols); one gap between them and around them. Buttons take the
1468
2891
  button tokens. */
1469
- .knobs-panel .knobs-row.knobs-toolbar{--k-tool-gap:max(4px,calc((var(--k-row) - var(--k-button-h,var(--kc-control-h))) / 2));display:grid;grid-template-columns:repeat(var(--k-tool-cols,1),minmax(0,1fr));gap:var(--k-tool-gap);height:auto;min-height:var(--k-row);padding:var(--k-tool-gap) var(--k-inset)}
2892
+ .knobs-panel .knobs-row.knobs-toolbar{--k-tool-gap:max(4px,calc((var(--_k-row) - var(--k-button-h,var(--_k-control-h))) / 2));display:grid;grid-template-columns:repeat(var(--k-tool-cols,1),minmax(0,1fr));gap:var(--k-tool-gap);height:auto;min-height:var(--_k-row);padding:var(--k-tool-gap) var(--_k-inset)}
1470
2893
  .knobs-card>.knobs-toolbar:hover{background:transparent}
1471
2894
  .knobs-card>.knobs-toolbar:has(:focus-visible)::after{opacity:0}
1472
- .knobs-panel .knobs-tool{display:flex;align-items:center;gap:6px;min-width:0;height:var(--k-button-h,var(--kc-control-h));padding:0 8px;background:var(--k-button-bg,var(--k-seg-bg));border-radius:var(--k-button-radius,var(--k-radius-md));box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);
1473
- color:var(--k-button-color,var(--k-label));font-size:var(--k-button-font-size,var(--k-text-control));font-weight:var(--k-label-weight);white-space:nowrap;cursor:pointer;transition:background var(--k-hover-t),color .15s,box-shadow .15s,scale .12s var(--k-ease),opacity .15s}
1474
- .knobs-panel .knobs-tool:is(:hover:not([disabled]),:focus-visible){background:var(--k-button-hover-bg,var(--k-surface-hi));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent));color:var(--k-text)}
2895
+ .knobs-panel .knobs-tool{display:flex;align-items:center;gap:6px;min-width:0;height:var(--k-button-h,var(--_k-control-h));padding:0 8px;background:var(--k-button-bg,var(--_k-segmented-track));border-radius:var(--k-button-radius,var(--_k-radius-md));box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);
2896
+ color:var(--k-button-color,var(--_k-fg-2));font-size:var(--k-button-font-size,var(--_k-text-control));font-weight:var(--_k-weight-label);white-space:nowrap;cursor:pointer;transition:background var(--k-hover-t),color .15s,box-shadow .15s,scale .12s var(--k-ease),opacity .15s}
2897
+ .knobs-panel .knobs-tool:is(:hover:not([disabled]),:focus-visible){background:var(--k-button-hover-bg,var(--_k-fill-selected));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent));color:var(--_k-fg)}
1475
2898
  .knobs-panel .knobs-tool:is(:active:not([disabled]),.knobs-pressed){scale:.96}
1476
2899
  .knobs-panel .knobs-tool[disabled]{opacity:var(--k-disabled-opacity);cursor:default}
1477
2900
  .knobs-tool .knobs-icon{flex:none;width:var(--k-icon-sm);height:var(--k-icon-sm)}
1478
2901
  .knobs-tool-label{min-width:0;overflow:hidden;text-overflow:ellipsis}
1479
2902
  /* The shortcut sits at the button's end, so a column of buttons lines their chips up. */
1480
- .knobs-panel .knobs-tool-key{flex:none;margin-left:auto;padding-left:4px;font:inherit;font-size:var(--k-text-cap);font-variant-numeric:tabular-nums;color:var(--k-dim);letter-spacing:.06em}
2903
+ .knobs-panel .knobs-tool-key{flex:none;margin-left:auto;padding-left:4px;font:inherit;font-size:var(--_k-text-cap);font-variant-numeric:tabular-nums;color:var(--_k-fg-3);letter-spacing:.06em}
1481
2904
  .knobs-panel :is([data-disabled],[data-readonly]) :is(.knobs-cell,.knobs-range-track,.knobs-angle,.knobs-dial,.knobs-seed,.knobs-keys,.knobs-tool){cursor:default}
1482
2905
 
1483
2906
  /* Row accessories (rowAccessory): the host's node, just after the label. */
1484
- .knobs-accessory{display:inline-flex;align-items:center;gap:var(--k-tray-pad);flex:none;min-width:0;color:var(--k-label)}
2907
+ .knobs-accessory{display:inline-flex;align-items:center;gap:var(--_k-tray-pad);flex:none;min-width:0;color:var(--_k-fg-2)}
1485
2908
  .knobs-accessory:empty{display:none}
1486
2909
  .knobs-panel .knobs-row:where(:not(.knobs-slider,.knobs-x,.knobs-spring))>.knobs-accessory{margin:0 auto 0 -4px}
1487
2910
  .knobs-track>.knobs-accessory{position:absolute;top:0;bottom:0;left:calc(var(--k-label-right,0px) + 4px);z-index:1}
1488
2911
  .knobs-x-head>.knobs-accessory{margin:0 auto 0 -4px}
1489
- .knobs-action-row>.knobs-accessory{position:absolute;top:0;bottom:0;right:var(--k-inset)}
2912
+ .knobs-action-row>.knobs-accessory{position:absolute;top:0;bottom:0;right:var(--_k-inset)}
1490
2913
  .knobs-action-row[data-keyed]>.knobs-accessory{position:static}
1491
2914
 
1492
2915
  /* Foldable groups (folded / groupFolded): the header toggles its card. */
1493
2916
  .knobs-panel .knobs-group-head[data-foldable]{cursor:pointer;user-select:none;transition:background var(--k-hover-t)}
1494
- .knobs-panel .knobs-group-head[data-foldable]:focus-visible{background:var(--k-surface)}
2917
+ .knobs-panel .knobs-group-head[data-foldable]:focus-visible{background:var(--_k-fill)}
1495
2918
  .knobs-group-head>span:last-child>.knobs-caret{margin:0 5px 0 3px}
1496
2919
  .knobs-group-head[aria-expanded="true"] .knobs-caret{transform:rotate(90deg)}
1497
- .knobs-group-head[data-foldable]:hover .knobs-caret{color:var(--k-label)}
2920
+ .knobs-group-head[data-foldable]:hover .knobs-caret{color:var(--_k-fg-2)}
1498
2921
 
1499
2922
  /* A choice row: the label keeps its words and the value takes the rest, truncating at its end
1500
2923
  (the whole value is in the menu and the button's tooltip); choice.ts sets how far the label may
@@ -1513,61 +2936,61 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1513
2936
  .knobs-hinting .knobs-hint-miss{opacity:var(--k-disabled-opacity);transition:opacity .1s}
1514
2937
  .knobs-hint-layer{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;z-index:5;animation:knobs-in .1s var(--k-ease)}
1515
2938
  /* The badges are <kbd>s, so they outrank the scoped reset's (0,1,1). */
1516
- .knobs-panel .knobs-hint{position:absolute;transform:translateY(-50%);display:inline-flex;align-items:center;height:15px;padding:0 4px;border-radius:var(--k-radius-sm);background:var(--k-accent);color:var(--k-bg);box-shadow:0 1px 3px rgba(0,0,0,calc(.35 * var(--k-lift)));
1517
- font:700 var(--k-text-cap)/1 var(--k-mono);letter-spacing:.04em;text-transform:uppercase;pointer-events:none}
2939
+ .knobs-panel .knobs-hint{position:absolute;transform:translateY(-50%);display:inline-flex;align-items:center;height:15px;padding:0 4px;border-radius:var(--_k-radius-sm);background:var(--_k-accent);color:var(--_k-bg);box-shadow:0 1px 3px rgba(0,0,0,calc(.35 * var(--k-lift)));
2940
+ font:700 var(--_k-text-cap)/1 var(--_k-mono);letter-spacing:.04em;text-transform:uppercase;pointer-events:none}
1518
2941
  .knobs-panel .knobs-hint[hidden]{display:none}
1519
2942
  .knobs-hint-typed{opacity:var(--k-hint-typed-opacity)}
1520
2943
  .knobs-hint-rest{opacity:1}
1521
2944
 
1522
2945
  /* A focused row's options: tiny digits in hint mode's look, once focus settles (optkeys.ts). */
1523
2946
  .knobs-optkeys{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;z-index:5}
1524
- .knobs-panel .knobs-optkey{position:absolute;transform:translateY(-50%);display:inline-flex;align-items:center;height:12px;padding:0 3px;border-radius:var(--k-radius-sm);background:var(--k-accent);color:var(--k-bg);box-shadow:0 1px 3px rgba(0,0,0,calc(.35 * var(--k-lift)));
1525
- font:700 calc(var(--k-text-cap) * .85)/1 var(--k-mono);letter-spacing:.04em;pointer-events:none;opacity:0;transition:opacity .12s var(--k-ease)}
2947
+ .knobs-panel .knobs-optkey{position:absolute;transform:translateY(-50%);display:inline-flex;align-items:center;height:12px;padding:0 3px;border-radius:var(--_k-radius-sm);background:var(--_k-accent);color:var(--_k-bg);box-shadow:0 1px 3px rgba(0,0,0,calc(.35 * var(--k-lift)));
2948
+ font:700 calc(var(--_k-text-cap) * .85)/1 var(--_k-mono);letter-spacing:.04em;pointer-events:none;opacity:0;transition:opacity .12s var(--k-ease)}
1526
2949
  .knobs-panel .knobs-optkey-range{transform:translate(-100%,-50%)}
1527
2950
  .knobs-panel .knobs-optkey[data-shown]{opacity:.85;transition-duration:.15s}
1528
2951
 
1529
2952
  /* Custom actions */
1530
- .knobs-panel .knobs-custom-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:var(--k-gap);margin-top:var(--k-section-gap)}
1531
- .knobs-panel .knobs-custom-actions button{height:var(--k-button-h,var(--k-action-h));min-height:24px;padding:0 8px;font-size:var(--k-button-font-size,var(--k-text-control));font-weight:var(--k-label-weight);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--k-button-color,var(--k-label));cursor:pointer;
1532
- background:var(--k-button-bg,var(--k-surface));border-radius:var(--k-button-radius,var(--k-radius));box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);transition:background var(--k-hover-t),color var(--k-hover-t),opacity .15s,transform .12s,box-shadow .15s}
1533
- .knobs-panel .knobs-custom-actions button:is(:hover:not([disabled]),:focus-visible){background:var(--k-button-hover-bg,var(--k-surface-hi));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent));color:var(--k-text)}
2953
+ .knobs-panel .knobs-custom-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:var(--_k-gap);margin-top:var(--k-section-gap)}
2954
+ .knobs-panel .knobs-custom-actions button{height:var(--k-button-h,var(--k-action-h));min-height:24px;padding:0 8px;font-size:var(--k-button-font-size,var(--_k-text-control));font-weight:var(--_k-weight-label);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--k-button-color,var(--_k-fg-2));cursor:pointer;
2955
+ background:var(--k-button-bg,var(--_k-fill));border-radius:var(--k-button-radius,var(--_k-radius));box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);transition:background var(--k-hover-t),color var(--k-hover-t),opacity .15s,transform .12s,box-shadow .15s}
2956
+ .knobs-panel .knobs-custom-actions button:is(:hover:not([disabled]),:focus-visible){background:var(--k-button-hover-bg,var(--_k-fill-selected));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent));color:var(--_k-fg)}
1534
2957
  .knobs-panel .knobs-custom-actions button:active:not([disabled]){transform:scale(.97)}
1535
2958
  .knobs-panel .knobs-tile-body>.knobs-custom-actions button[disabled]{opacity:var(--k-disabled-opacity);cursor:default}
1536
2959
 
1537
2960
  /* Variants Disclosure Drawer */
1538
- .knobs-transfer{display:grid;grid-template-columns:1fr 1fr;gap:var(--k-gap);margin-top:8px;padding-top:8px;border-top:1px solid var(--k-line)}
1539
- .knobs-transfer button{height:var(--k-button-h,24px);padding:0 8px;background:var(--k-button-bg,var(--k-surface));border-radius:var(--k-button-radius,var(--k-radius));box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);font-size:var(--k-button-font-size,var(--k-text-meta));color:var(--k-button-color,var(--k-label));cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t),box-shadow .15s}
1540
- .knobs-transfer button:is(:hover,:focus-visible){background:var(--k-button-hover-bg,var(--k-surface-hi));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent));color:var(--k-text)}
2961
+ .knobs-transfer{display:grid;grid-template-columns:1fr 1fr;gap:var(--_k-gap);margin-top:8px;padding-top:8px;border-top:1px solid var(--_k-border)}
2962
+ .knobs-transfer button{height:var(--k-button-h,24px);padding:0 8px;background:var(--k-button-bg,var(--_k-fill));border-radius:var(--k-button-radius,var(--_k-radius));box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);font-size:var(--k-button-font-size,var(--_k-text-meta));color:var(--k-button-color,var(--_k-fg-2));cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t),box-shadow .15s}
2963
+ .knobs-transfer button:is(:hover,:focus-visible){background:var(--k-button-hover-bg,var(--_k-fill-selected));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent));color:var(--_k-fg)}
1541
2964
  .knobs-sound-pref{grid-template-columns:1fr}
1542
2965
 
1543
2966
  /* Context menu: borrows its panel's tokens (see menu.ts) and floats above everything. */
1544
- .knobs-menu{position:fixed;z-index:2147480004;min-width:176px;padding:var(--k-unit);box-sizing:border-box;font:var(--k-font-weight) var(--k-text-control)/1.35 var(--k-font);color:var(--k-text);text-align:left;-webkit-font-smoothing:antialiased;
1545
- background:linear-gradient(var(--k-surface-hi),var(--k-surface-hi)),color-mix(in srgb,var(--k-bg) 90%,transparent);border:1px solid var(--k-line);border-radius:var(--k-radius);
1546
- box-shadow:var(--k-shadow),inset 0 1px 0 var(--k-rim);-webkit-backdrop-filter:blur(20px) saturate(1.6);backdrop-filter:blur(20px) saturate(1.6);outline:none;user-select:none}
2967
+ .knobs-menu{position:fixed;z-index:2147480004;min-width:176px;padding:var(--_k-unit);box-sizing:border-box;font:var(--_k-weight) var(--_k-text-control)/1.35 var(--_k-font);color:var(--_k-fg);text-align:left;-webkit-font-smoothing:antialiased;
2968
+ background:linear-gradient(var(--_k-fill-selected),var(--_k-fill-selected)),color-mix(in srgb,var(--_k-bg) 90%,transparent);border:1px solid var(--_k-border);border-radius:var(--_k-radius);
2969
+ box-shadow:var(--_k-shadow-overlay),inset 0 1px 0 var(--_k-rim);-webkit-backdrop-filter:blur(20px) saturate(1.6);backdrop-filter:blur(20px) saturate(1.6);outline:none;user-select:none}
1547
2970
  .knobs-menu{max-width:min(480px,calc(100vw - 12px))}
1548
2971
  .knobs-menu-list{max-height:min(360px,calc(100dvh - 120px));overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin}
1549
- .knobs-menu-item{position:relative;display:flex;align-items:center;justify-content:space-between;gap:24px;height:var(--kc-control-h);min-height:20px;padding:0 8px;border-radius:var(--k-radius-sm);cursor:default;white-space:nowrap;transition:background .08s}
2972
+ .knobs-menu-item{position:relative;display:flex;align-items:center;justify-content:space-between;gap:24px;height:var(--_k-control-h);min-height:20px;padding:0 8px;border-radius:var(--_k-radius-sm);cursor:default;white-space:nowrap;transition:background .08s}
1550
2973
  .knobs-menu-item>span{min-width:0;overflow:hidden;text-overflow:ellipsis}
1551
2974
  .knobs-menu-item[hidden]{display:none}
1552
2975
  /* The match shows by colour, not weight, so a filtered label keeps the width the menu measured. */
1553
- .knobs-menu-item>span[data-marked]{color:var(--k-label)}
1554
- .knobs-menu-item mark{background:none;color:var(--k-text)}
1555
- .knobs-menu .knobs-menu-search{display:block;width:100%;height:var(--kc-control-h);min-height:22px;margin:0 0 var(--k-unit);padding:0 8px;border:0;border-radius:var(--k-radius-sm);background:var(--k-seg-bg);color:var(--k-text);font:inherit;outline:none;-webkit-appearance:none;appearance:none}
1556
- .knobs-menu .knobs-menu-search::placeholder{color:var(--k-dim)}
2976
+ .knobs-menu-item>span[data-marked]{color:var(--_k-fg-2)}
2977
+ .knobs-menu-item mark{background:none;color:var(--_k-fg)}
2978
+ .knobs-menu .knobs-menu-search{display:block;width:100%;height:var(--_k-control-h);min-height:22px;margin:0 0 var(--_k-unit);padding:0 8px;border:0;border-radius:var(--_k-radius-sm);background:var(--_k-segmented-track);color:var(--_k-fg);font:inherit;outline:none;-webkit-appearance:none;appearance:none}
2979
+ .knobs-menu .knobs-menu-search::placeholder{color:var(--_k-fg-3)}
1557
2980
  .knobs-menu .knobs-menu-search::-webkit-search-cancel-button{display:none}
1558
2981
  .knobs-menu [hidden]{display:none!important}
1559
- .knobs-menu-empty{padding:0 8px;height:var(--kc-control-h);display:flex;align-items:center;color:var(--k-dim)}
1560
- .knobs-menu-item[data-active]{background:color-mix(in srgb,var(--k-accent) 14%,transparent)}
1561
- .knobs-menu-item[aria-disabled]{opacity:var(--k-disabled-opacity);color:var(--k-label)}
1562
- .knobs-menu-item kbd{font:var(--k-text-cap)/1 var(--k-mono);font-variant-numeric:tabular-nums;color:var(--k-dim);letter-spacing:0}
1563
- .knobs-menu-item[data-separated]{margin-top:calc(var(--k-unit) * 2 + 1px)}
1564
- .knobs-menu-item[data-separated]::before{content:"";position:absolute;left:8px;right:8px;top:calc(var(--k-unit) * -1 - 1px);height:1px;transform:scaleY(.5);background:var(--k-line)}
2982
+ .knobs-menu-empty{padding:0 8px;height:var(--_k-control-h);display:flex;align-items:center;color:var(--_k-fg-3)}
2983
+ .knobs-menu-item[data-active]{background:color-mix(in srgb,var(--_k-accent) 14%,transparent)}
2984
+ .knobs-menu-item[aria-disabled]{opacity:var(--k-disabled-opacity);color:var(--_k-fg-2)}
2985
+ .knobs-menu-item kbd{font:var(--_k-text-cap)/1 var(--_k-mono);font-variant-numeric:tabular-nums;color:var(--_k-fg-3);letter-spacing:0}
2986
+ .knobs-menu-item[data-separated]{margin-top:calc(var(--_k-unit) * 2 + 1px)}
2987
+ .knobs-menu-item[data-separated]::before{content:"";position:absolute;left:8px;right:8px;top:calc(var(--_k-unit) * -1 - 1px);height:1px;transform:scaleY(.5);background:var(--_k-border)}
1565
2988
 
1566
2989
  /* Status & Transfer Textarea */
1567
- .knobs-panel .knobs-status{margin:6px 0 0;padding:0 var(--k-inset);color:var(--k-label);font-size:var(--k-text-meta);overflow-wrap:anywhere}
2990
+ .knobs-panel .knobs-status{margin:6px 0 0;padding:0 var(--_k-inset);color:var(--_k-fg-2);font-size:var(--_k-text-meta);overflow-wrap:anywhere}
1568
2991
 
1569
- .knobs-panel textarea{width:100%;min-height:84px;margin-top:6px;padding:6px var(--k-inset);resize:vertical;font:var(--k-text-meta)/1.4 var(--k-mono)}
1570
- .knobs-panel .knobs-apply-btn{width:100%;height:26px;margin-top:var(--k-gap);font-size:var(--k-text-control);font-weight:500;color:var(--k-text);background:var(--k-surface-hi);cursor:pointer}
2992
+ .knobs-panel textarea{width:100%;min-height:84px;margin-top:6px;padding:6px var(--_k-inset);resize:vertical;font:var(--_k-text-meta)/1.4 var(--_k-mono)}
2993
+ .knobs-panel .knobs-apply-btn{width:100%;height:26px;margin-top:var(--_k-gap);font-size:var(--_k-text-control);font-weight:500;color:var(--_k-fg);background:var(--_k-fill-selected);cursor:pointer}
1571
2994
 
1572
2995
  /* WebGPU Overlay Active Mirror State */
1573
2996
  .knobs-panel[data-gpu-active="true"]{background:transparent!important;border-color:transparent!important;box-shadow:none!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important}
@@ -1606,26 +3029,26 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1606
3029
  /* Page: sections of cards in balanced columns, under a sticky glass header. The page scrolls the
1607
3030
  window, so nothing here may become a scroll container or a containing block for the fixed
1608
3031
  popover and status. Custom cards (.knobs-live) are drawn by the DOM in both renderers. */
1609
- .knobs-panel.knobs-page{width:auto;max-width:none;min-height:100dvh;padding:0 0 calc(var(--k-unit) * 16);border:0;border-radius:0;box-shadow:none;overflow:visible;background:var(--k-page);-webkit-backdrop-filter:none;backdrop-filter:none;
1610
- --k-page-pad:calc(var(--k-unit) * 8);--k-page-gap:calc(var(--k-unit) * 4)}
1611
- .knobs-panel.knobs-page[data-gpu-active="true"]{background:var(--k-page)!important}
1612
- .knobs-panel.knobs-page>header{position:sticky;top:0;z-index:3;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(max-content,1fr);align-items:center;gap:var(--k-page-gap);min-height:calc(var(--k-row) + var(--k-unit) * 6);padding:calc(var(--k-unit) * 2.5) var(--k-page-pad);
1613
- background:color-mix(in srgb,var(--k-page) 84%,transparent);-webkit-backdrop-filter:blur(24px) saturate(1.6);backdrop-filter:blur(24px) saturate(1.6);border-bottom:1px solid transparent;transition:border-color .2s}
1614
- .knobs-panel.knobs-page>header[data-scrolled]{border-bottom-color:var(--k-line)}
1615
- .knobs-panel.knobs-page>header strong{font-size:calc(var(--k-font-size) + 3px);letter-spacing:-.015em;padding-left:calc(var(--k-pad) + var(--k-inset) + 1px)}
3032
+ .knobs-panel.knobs-page{width:auto;max-width:none;min-height:100dvh;padding:0 0 calc(var(--_k-unit) * 16);border:0;border-radius:0;box-shadow:none;overflow:visible;background:var(--_k-bg-page);-webkit-backdrop-filter:none;backdrop-filter:none;
3033
+ --k-page-pad:calc(var(--_k-unit) * 8);--k-page-gap:calc(var(--_k-unit) * 4)}
3034
+ .knobs-panel.knobs-page[data-gpu-active="true"]{background:var(--_k-bg-page)!important}
3035
+ .knobs-panel.knobs-page>header{position:sticky;top:0;z-index:3;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(max-content,1fr);align-items:center;gap:var(--k-page-gap);min-height:calc(var(--_k-row) + var(--_k-unit) * 6);padding:calc(var(--_k-unit) * 2.5) var(--k-page-pad);
3036
+ background:color-mix(in srgb,var(--_k-bg-page) 84%,transparent);-webkit-backdrop-filter:blur(24px) saturate(1.6);backdrop-filter:blur(24px) saturate(1.6);border-bottom:1px solid transparent;transition:border-color .2s}
3037
+ .knobs-panel.knobs-page>header[data-scrolled]{border-bottom-color:var(--_k-border)}
3038
+ .knobs-panel.knobs-page>header strong{font-size:calc(var(--_k-font-size) + 3px);letter-spacing:-.015em;padding-left:calc(var(--_k-pad) + var(--_k-inset) + 1px)}
1616
3039
  .knobs-page>header .knobs-presets{margin:0;min-width:0;max-width:min(640px,46vw)}
1617
3040
  .knobs-page>header .knobs-presets-track{display:flex;flex-wrap:wrap}
1618
3041
  .knobs-page>header .knobs-preset-chip{flex:0 0 var(--k-preset-min,58px)}
1619
3042
  .knobs-page-tools{display:flex;align-items:center;justify-content:flex-end;min-width:0}
1620
- .knobs-page-tools .knobs-head-actions{margin-right:calc((var(--k-icon-size) - var(--k-icon-btn)) / 2 + var(--k-pad) + var(--k-inset) - var(--k-unit))}
1621
- .knobs-panel.knobs-page>header[data-narrow]{grid-template-columns:minmax(0,1fr) auto;row-gap:calc(var(--k-unit) * 2)}
3043
+ .knobs-page-tools .knobs-head-actions{margin-right:calc((var(--k-icon-size) - var(--k-icon-btn)) / 2 + var(--_k-pad) + var(--_k-inset) - var(--_k-unit))}
3044
+ .knobs-panel.knobs-page>header[data-narrow]{grid-template-columns:minmax(0,1fr) auto;row-gap:calc(var(--_k-unit) * 2)}
1622
3045
  .knobs-panel.knobs-page>header[data-narrow]>strong{grid-area:1/1}
1623
3046
  .knobs-panel.knobs-page>header[data-narrow] .knobs-page-tools{grid-area:1/2}
1624
3047
  .knobs-panel.knobs-page>header[data-narrow] .knobs-presets{grid-area:2/1/3/3;max-width:none}
1625
3048
  .knobs-page>header[data-narrow] .knobs-preset-chip{flex:1 0 var(--k-preset-min,58px)}
1626
3049
  @media(max-width:640px){
1627
- .knobs-panel.knobs-page{--k-page-pad:calc(var(--k-unit) * 4)}
1628
- .knobs-panel.knobs-page>header{grid-template-columns:minmax(0,1fr) auto;row-gap:calc(var(--k-unit) * 2)}
3050
+ .knobs-panel.knobs-page{--k-page-pad:calc(var(--_k-unit) * 4)}
3051
+ .knobs-panel.knobs-page>header{grid-template-columns:minmax(0,1fr) auto;row-gap:calc(var(--_k-unit) * 2)}
1629
3052
  .knobs-panel.knobs-page>header>strong{grid-area:1/1}
1630
3053
  .knobs-panel.knobs-page>header .knobs-page-tools{grid-area:1/2}
1631
3054
  .knobs-panel.knobs-page>header .knobs-presets{grid-area:2/1/3/3;max-width:none}
@@ -1633,27 +3056,27 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1633
3056
  }
1634
3057
  /* The jump strip (nav: true): a chip per section along the header's foot, the one in view
1635
3058
  underlined; it scrolls sideways when the chips don't fit. */
1636
- .knobs-page>header>.knobs-nav{grid-column:1/-1;margin:0 calc(var(--k-page-pad) * -1) calc(var(--k-unit) * -2.5);padding:0 calc(var(--k-page-pad) + var(--k-pad) + var(--k-inset) + 1px);gap:calc(var(--k-unit) * 5);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain}
3059
+ .knobs-page>header>.knobs-nav{grid-column:1/-1;margin:0 calc(var(--k-page-pad) * -1) calc(var(--_k-unit) * -2.5);padding:0 calc(var(--k-page-pad) + var(--_k-pad) + var(--_k-inset) + 1px);gap:calc(var(--_k-unit) * 5);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain}
1637
3060
  .knobs-page>header>.knobs-nav::-webkit-scrollbar{display:none}
1638
3061
  .knobs-page>header>.knobs-nav::after{display:none}
1639
- .knobs-panel.knobs-page>header>.knobs-nav .knobs-tab{display:inline-flex;align-items:center;width:auto;height:calc(var(--k-row) + var(--k-unit));padding:0;border-radius:0;font-size:var(--k-text-control);line-height:1.25;color:var(--k-label);background:transparent}
1640
- .knobs-panel.knobs-page>header>.knobs-nav .knobs-tab:is(:hover,:focus-visible,[aria-selected="true"]){color:var(--k-text);background:transparent}
1641
- .knobs-tab-count{margin-left:5px;font-size:var(--k-text-meta);font-weight:500;font-variant-numeric:tabular-nums;color:var(--k-modified)}
1642
- .knobs-panel.knobs-page .knobs-page-tools .knobs-custom-actions{display:flex;gap:var(--k-tray-pad);margin:0 calc(var(--k-unit) * 2) 0 0}
1643
- .knobs-panel.knobs-page .knobs-page-tools .knobs-custom-actions button{height:var(--k-icon-btn);min-height:0;padding:0 8px;background:transparent;border-radius:var(--k-round)}
1644
- .knobs-panel .knobs-filter{width:0;height:var(--kc-control-h);padding:0;margin:0;opacity:0;pointer-events:none;background:var(--k-seg-bg);border-radius:var(--k-radius-md);font-size:var(--k-text-control);color:var(--k-text);-webkit-appearance:none;appearance:none;
3062
+ .knobs-panel.knobs-page>header>.knobs-nav .knobs-tab{display:inline-flex;align-items:center;width:auto;height:calc(var(--_k-row) + var(--_k-unit));padding:0;border-radius:0;font-size:var(--_k-text-control);line-height:1.25;color:var(--_k-fg-2);background:transparent}
3063
+ .knobs-panel.knobs-page>header>.knobs-nav .knobs-tab:is(:hover,:focus-visible,[aria-selected="true"]){color:var(--_k-fg);background:transparent}
3064
+ .knobs-tab-count{margin-left:5px;font-size:var(--_k-text-meta);font-weight:500;font-variant-numeric:tabular-nums;color:var(--_k-modified)}
3065
+ .knobs-panel.knobs-page .knobs-page-tools .knobs-custom-actions{display:flex;gap:var(--_k-tray-pad);margin:0 calc(var(--_k-unit) * 2) 0 0}
3066
+ .knobs-panel.knobs-page .knobs-page-tools .knobs-custom-actions button{height:var(--k-icon-btn);min-height:0;padding:0 8px;background:transparent;border-radius:var(--_k-round)}
3067
+ .knobs-panel .knobs-filter{width:0;height:var(--_k-control-h);padding:0;margin:0;opacity:0;pointer-events:none;background:var(--_k-segmented-track);border-radius:var(--_k-radius-md);font-size:var(--_k-text-control);color:var(--_k-fg);-webkit-appearance:none;appearance:none;
1645
3068
  transition:width ${LEAD_T},padding ${LEAD_T},margin ${LEAD_T},opacity .18s}
1646
3069
  .knobs-panel .knobs-filter::-webkit-search-cancel-button{display:none}
1647
- .knobs-panel .knobs-filter::placeholder{color:var(--k-dim)}
1648
- .knobs-panel .knobs-filter[data-open]{width:min(200px,22vw);padding:0 10px;margin-right:calc(var(--k-unit) * 2);opacity:1;pointer-events:auto}
1649
- .knobs-panel.knobs-page>.knobs-popover{position:fixed;z-index:2147480003;top:calc(var(--k-head-h,56px) + var(--k-unit) * 2);right:var(--k-page-pad);width:min(360px,calc(100vw - 32px));max-height:calc(100dvh - var(--k-head-h,56px) - 32px);overflow:auto;margin:0;padding:var(--k-pad) var(--k-inset);
1650
- background:color-mix(in srgb,var(--k-bg) 94%,transparent);border-radius:var(--k-panel-radius);box-shadow:var(--k-shadow),inset 0 1px 0 var(--k-rim);-webkit-backdrop-filter:blur(24px) saturate(1.6);backdrop-filter:blur(24px) saturate(1.6)}
1651
- .knobs-panel.knobs-page>.knobs-status{position:fixed;z-index:2147480003;left:50%;bottom:calc(var(--k-unit) * 6);translate:-50% 0;max-width:min(480px,80vw);margin:0;padding:calc(var(--k-unit) * 2) calc(var(--k-unit) * 3.5);
1652
- background:var(--k-bg);border:1px solid var(--k-line);border-radius:var(--k-round);box-shadow:var(--k-shadow);color:var(--k-text)}
3070
+ .knobs-panel .knobs-filter::placeholder{color:var(--_k-fg-3)}
3071
+ .knobs-panel .knobs-filter[data-open]{width:min(200px,22vw);padding:0 10px;margin-right:calc(var(--_k-unit) * 2);opacity:1;pointer-events:auto}
3072
+ .knobs-panel.knobs-page>.knobs-popover{position:fixed;z-index:2147480003;top:calc(var(--k-head-h,56px) + var(--_k-unit) * 2);right:var(--k-page-pad);width:min(360px,calc(100vw - 32px));max-height:calc(100dvh - var(--k-head-h,56px) - 32px);overflow:auto;margin:0;padding:var(--_k-pad) var(--_k-inset);
3073
+ background:color-mix(in srgb,var(--_k-bg) 94%,transparent);border-radius:var(--_k-radius-panel);box-shadow:var(--_k-shadow-overlay),inset 0 1px 0 var(--_k-rim);-webkit-backdrop-filter:blur(24px) saturate(1.6);backdrop-filter:blur(24px) saturate(1.6)}
3074
+ .knobs-panel.knobs-page>.knobs-status{position:fixed;z-index:2147480003;left:50%;bottom:calc(var(--_k-unit) * 6);translate:-50% 0;max-width:min(480px,80vw);margin:0;padding:calc(var(--_k-unit) * 2) calc(var(--_k-unit) * 3.5);
3075
+ background:var(--_k-bg);border:1px solid var(--_k-border);border-radius:var(--_k-round);box-shadow:var(--_k-shadow-overlay);color:var(--_k-fg)}
1653
3076
  .knobs-sections{padding:0 var(--k-page-pad);overflow-x:clip;overflow-anchor:none}
1654
- .knobs-columns{display:grid;grid-template-columns:repeat(var(--k-cols,1),minmax(0,1fr));gap:var(--k-page-gap);align-items:start;padding-top:calc(var(--k-unit) * 3)}
3077
+ .knobs-columns{display:grid;grid-template-columns:repeat(var(--k-cols,1),minmax(0,1fr));gap:var(--k-page-gap);align-items:start;padding-top:calc(var(--_k-unit) * 3)}
1655
3078
  .knobs-column{display:flex;flex-direction:column;gap:var(--k-page-gap);min-width:0}
1656
- .knobs-section-head{margin:0 0 calc(var(--k-page-gap) * -.25);padding:0 calc(var(--k-pad) + var(--k-inset) + 1px);font:var(--k-title-weight) calc(var(--k-font-size) + 3px)/1.25 var(--k-font);letter-spacing:-.015em;color:var(--k-text);white-space:nowrap;
3079
+ .knobs-section-head{margin:0 0 calc(var(--k-page-gap) * -.25);padding:0 calc(var(--_k-pad) + var(--_k-inset) + 1px);font:var(--_k-weight-title) calc(var(--_k-font-size) + 3px)/1.25 var(--_k-font);letter-spacing:-.015em;color:var(--_k-fg);white-space:nowrap;
1657
3080
  display:grid;grid-template-columns:minmax(0,max-content) minmax(0,1fr) auto;align-items:center;column-gap:8px;isolation:isolate}
1658
3081
  .knobs-column>:not([hidden],[data-away])~.knobs-section-head{margin-top:calc(var(--k-page-gap) * .75)}
1659
3082
  .knobs-section-name{grid-area:1/1;min-width:0;overflow:hidden;text-overflow:ellipsis}
@@ -1662,35 +3085,35 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1662
3085
  .knobs-tile[data-away]{display:none}
1663
3086
  .knobs-section-head[data-foldable]{cursor:pointer;user-select:none}
1664
3087
  .knobs-section-head[data-folded]{margin-bottom:0}
1665
- .knobs-section-head[data-foldable]::before{content:"";position:absolute;z-index:-1;inset:-4px 0;border-radius:var(--k-radius-md);background:var(--k-surface);opacity:0;transition:opacity var(--k-hover-t)}
3088
+ .knobs-section-head[data-foldable]::before{content:"";position:absolute;z-index:-1;inset:-4px 0;border-radius:var(--_k-radius-md);background:var(--_k-fill);opacity:0;transition:opacity var(--k-hover-t)}
1666
3089
  .knobs-section-head[data-foldable]:focus-visible{outline:none}
1667
3090
  .knobs-section-head[data-foldable]:focus-visible::before{opacity:1}
1668
3091
  .knobs-section-head>.knobs-caret{grid-area:1/3;margin:0 calc((var(--k-icon-sm) - 20px) / 2 + 5px) 0 0;opacity:0;transition:transform ${LEAD_T},opacity .15s,color .15s}
1669
3092
  .knobs-section-head:is(:hover,:focus-visible,[data-folded])>.knobs-caret{opacity:1}
1670
- .knobs-section-head:hover>.knobs-caret{color:var(--k-label)}
3093
+ .knobs-section-head:hover>.knobs-caret{color:var(--_k-fg-2)}
1671
3094
  .knobs-section-head[aria-expanded="true"]>.knobs-caret{transform:rotate(90deg)}
1672
- .knobs-section-summary{display:none;grid-area:1/2;justify-self:end;min-width:0;overflow:hidden;text-overflow:ellipsis;font:500 var(--k-text-control)/1.25 var(--k-font);letter-spacing:0;color:var(--k-dim);font-variant-numeric:tabular-nums}
3095
+ .knobs-section-summary{display:none;grid-area:1/2;justify-self:end;min-width:0;overflow:hidden;text-overflow:ellipsis;font:500 var(--_k-text-control)/1.25 var(--_k-font);letter-spacing:0;color:var(--_k-fg-3);font-variant-numeric:tabular-nums}
1673
3096
  .knobs-section-head[data-folded]>.knobs-section-summary{display:block;animation:knobs-fade .2s var(--k-ease) both}
1674
- .knobs-section-desc,.knobs-group-desc{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--k-label-weight) var(--k-text-meta)/1.35 var(--k-font);letter-spacing:0;color:var(--k-dim);text-transform:none}
3097
+ .knobs-section-desc,.knobs-group-desc{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--_k-weight-label) var(--_k-text-meta)/1.35 var(--_k-font);letter-spacing:0;color:var(--_k-fg-3);text-transform:none}
1675
3098
  .knobs-section-desc{grid-area:2/1/3/4;margin-top:1px}
1676
3099
  .knobs-group-desc{padding:0 var(--k-group-inset)}
1677
3100
  .knobs-tile>.knobs-group-desc{margin:calc(2px - var(--k-head-gap)) 0 var(--k-head-gap)}
1678
3101
  .knobs-tile:is([data-foldable],[data-collapsible])>.knobs-group-desc{margin:2px 0 0}
1679
3102
  @keyframes knobs-fade{from{opacity:0}}
1680
- .knobs-tile{position:relative;min-width:0;padding:var(--k-pad);background:var(--k-bg);border:1px solid var(--k-line);border-radius:var(--k-panel-radius);box-shadow:inset 0 1px 0 var(--k-rim)}
3103
+ .knobs-tile{position:relative;min-width:0;padding:var(--_k-pad);background:var(--_k-bg);border:1px solid var(--_k-border);border-radius:var(--_k-radius-panel);box-shadow:inset 0 1px 0 var(--_k-rim)}
1681
3104
  .knobs-tile>.knobs-card{margin:0}
1682
3105
  .knobs-tile[data-foldable]>.knobs-group-head{margin-bottom:0}
1683
3106
  .knobs-tile[data-foldable]>.knobs-card{margin-top:var(--k-head-gap)}
1684
3107
  /* A card's header is compact: as tall as its 20px controls, then a gap and a half before its rows. */
1685
- .knobs-tile>.knobs-group-head{position:relative;margin:0 0 var(--k-head-gap);min-height:20px;color:var(--k-text);font-size:var(--k-text-title);font-weight:var(--k-title-weight);letter-spacing:-.01em;text-transform:none}
1686
- .knobs-panel.knobs-page{--k-head-gap:calc(var(--k-gap) * 1.5)}
3108
+ .knobs-tile>.knobs-group-head{position:relative;margin:0 0 var(--k-head-gap);min-height:20px;color:var(--_k-fg);font-size:var(--_k-text-title);font-weight:var(--_k-weight-title);letter-spacing:-.01em;text-transform:none}
3109
+ .knobs-panel.knobs-page{--k-head-gap:calc(var(--_k-gap) * 1.5)}
1687
3110
  /* The title wins the header's room: what's on the right (presets, a summary) gives way first. */
1688
3111
  .knobs-tile>.knobs-group-head>.knobs-group-title{flex:1 1 auto}
1689
3112
  .knobs-tile>.knobs-group-head>span:last-child{flex:0 1000 auto;min-width:0}
1690
3113
  .knobs-tile>.knobs-group-head :is(.knobs-group-reset,.knobs-group-die){flex:none}
1691
3114
  /* A folded card's header trades its controls (presets, reset, die) for a summary of the card. */
1692
- .knobs-group-ctl{display:flex;align-items:center;gap:var(--k-tray-pad);min-width:0}
1693
- .knobs-group-summary{display:none;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--k-dim);font-size:var(--k-text-control);font-weight:500;letter-spacing:0;font-variant-numeric:tabular-nums}
3115
+ .knobs-group-ctl{display:flex;align-items:center;gap:var(--_k-tray-pad);min-width:0}
3116
+ .knobs-group-summary{display:none;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--_k-fg-3);font-size:var(--_k-text-control);font-weight:500;letter-spacing:0;font-variant-numeric:tabular-nums}
1694
3117
  .knobs-tile[data-folded]>.knobs-group-head .knobs-group-summary:not(:empty){display:block}
1695
3118
  .knobs-tile[data-folded]>.knobs-group-head .knobs-group-ctl{display:none}
1696
3119
  .knobs-tile[data-fold-motion]>.knobs-group-head :is(.knobs-group-summary,.knobs-group-ctl){animation:knobs-fade .2s var(--k-ease) both}
@@ -1698,25 +3121,25 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1698
3121
  full), and what's highlighted on its own gets a dot in the gutter by its title. The veil and
1699
3122
  dot are written each frame on the panel spring (see page.ts). */
1700
3123
  .knobs-panel.knobs-page{--k-page-dim:.4}
1701
- .knobs-veil{position:absolute;inset:-1px;z-index:1;border-radius:inherit;background:var(--k-page);pointer-events:none}
1702
- .knobs-mark{position:absolute;top:50%;width:6px;height:6px;margin:-3px 0 0 -3px;border-radius:50%;background:var(--k-accent);pointer-events:none}
1703
- .knobs-tile>.knobs-mark{z-index:2;top:calc(var(--k-pad) + 10px);left:calc((var(--k-pad) + var(--k-inset) + 1px) / 2 - 1px)}
3124
+ .knobs-veil{position:absolute;inset:-1px;z-index:1;border-radius:inherit;background:var(--_k-bg-page);pointer-events:none}
3125
+ .knobs-mark{position:absolute;top:50%;width:6px;height:6px;margin:-3px 0 0 -3px;border-radius:50%;background:var(--_k-accent);pointer-events:none}
3126
+ .knobs-tile>.knobs-mark{z-index:2;top:calc(var(--_k-pad) + 10px);left:calc((var(--_k-pad) + var(--_k-inset) + 1px) / 2 - 1px)}
1704
3127
  .knobs-section-head{position:relative}
1705
- .knobs-section-head>.knobs-mark{left:calc((var(--k-pad) + var(--k-inset) + 1px) / 2)}
3128
+ .knobs-section-head>.knobs-mark{left:calc((var(--_k-pad) + var(--_k-inset) + 1px) / 2)}
1706
3129
  .knobs-group-title{display:grid;flex:1;min-width:0}
1707
3130
  .knobs-group-title>*{grid-area:1/1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:opacity .15s}
1708
3131
  .knobs-peek{opacity:0;pointer-events:none}
1709
3132
  .knobs-group-head[data-peek] .knobs-group-label{opacity:0}
1710
3133
  .knobs-group-head[data-peek] .knobs-peek{opacity:1}
1711
- .knobs-group-head .knobs-chips.knobs-seg{flex:none;height:20px;max-width:none;gap:0;margin-right:var(--k-unit)}
1712
- .knobs-group-head .knobs-chips button{width:18px;height:100%;padding:0;font-size:var(--k-text-meta);font-weight:500;font-variant-numeric:tabular-nums;border-radius:var(--k-radius-sm);background:transparent}
1713
- .knobs-group-head .knobs-chips button[aria-checked="true"]{color:var(--k-text)}
3134
+ .knobs-group-head .knobs-chips.knobs-seg{flex:none;height:20px;max-width:none;gap:0;margin-right:var(--_k-unit)}
3135
+ .knobs-group-head .knobs-chips button{width:18px;height:100%;padding:0;font-size:var(--_k-text-meta);font-weight:500;font-variant-numeric:tabular-nums;border-radius:var(--_k-radius-sm);background:transparent}
3136
+ .knobs-group-head .knobs-chips button[aria-checked="true"]{color:var(--_k-fg)}
1714
3137
  /* Named presets: their names as segments beside the title, or a compact menu of them. */
1715
- .knobs-group-presets{display:flex;align-items:center;flex:0 1 auto;min-width:0;margin-right:var(--k-unit)}
1716
- .knobs-group-presets .knobs-seg{flex:none;height:20px;max-width:none;padding:var(--k-tray-pad)}
1717
- .knobs-group-presets .knobs-seg button{height:100%;padding:0 6px;font-size:var(--k-text-meta);font-weight:500;background:transparent}
1718
- .knobs-panel .knobs-group-presets .knobs-select{height:20px;max-width:11em;gap:3px;padding:0 3px 0 7px;font-size:var(--k-text-meta);font-weight:500;letter-spacing:0;text-transform:none}
1719
- .knobs-group-presets .knobs-select[data-none]{color:var(--k-dim)}
3138
+ .knobs-group-presets{display:flex;align-items:center;flex:0 1 auto;min-width:0;margin-right:var(--_k-unit)}
3139
+ .knobs-group-presets .knobs-seg{flex:none;height:20px;max-width:none;padding:var(--_k-tray-pad)}
3140
+ .knobs-group-presets .knobs-seg button{height:100%;padding:0 6px;font-size:var(--_k-text-meta);font-weight:500;background:transparent}
3141
+ .knobs-panel .knobs-group-presets .knobs-select{height:20px;max-width:11em;gap:3px;padding:0 3px 0 7px;font-size:var(--_k-text-meta);font-weight:500;letter-spacing:0;text-transform:none}
3142
+ .knobs-group-presets .knobs-select[data-none]{color:var(--_k-fg-3)}
1720
3143
  .knobs-group-presets .knobs-select .knobs-icon{width:calc(var(--k-icon-sm) - 3px);height:calc(var(--k-icon-sm) - 3px)}
1721
3144
  .knobs-tile-body{display:flex;flex-direction:column}
1722
3145
  .knobs-tile-body>.knobs-card{margin:0}
@@ -1728,35 +3151,25 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
1728
3151
  .knobs-card>.knobs-item:focus-visible{outline:none}
1729
3152
  .knobs-card>.knobs-item:focus-visible::after{opacity:1}
1730
3153
  /* A collapsible custom card: its header toggles it, with a caret and, while folded, a summary. */
1731
- .knobs-live[data-collapsible]>.knobs-group-head{margin-bottom:0;cursor:pointer;border-radius:var(--k-radius-sm);transition:background var(--k-hover-t)}
1732
- .knobs-live[data-collapsible]>.knobs-group-head:focus-visible{background:var(--k-surface)}
3154
+ .knobs-live[data-collapsible]>.knobs-group-head{margin-bottom:0;cursor:pointer;border-radius:var(--_k-radius-sm);transition:background var(--k-hover-t)}
3155
+ .knobs-live[data-collapsible]>.knobs-group-head:focus-visible{background:var(--_k-fill)}
1733
3156
  .knobs-live[data-collapsible]>.knobs-tile-body{margin-top:var(--k-head-gap);transition:opacity var(--k-token-t)}
1734
3157
  .knobs-live[data-collapsed]>.knobs-tile-body{opacity:0}
1735
- .knobs-live>.knobs-tile-body[data-folding]{position:absolute;left:var(--k-pad);right:var(--k-pad);margin-top:0}
3158
+ .knobs-live>.knobs-tile-body[data-folding]{position:absolute;left:var(--_k-pad);right:var(--_k-pad);margin-top:0}
1736
3159
  .knobs-card-right{display:flex;align-items:center;gap:6px;min-width:0}
1737
3160
  .knobs-card-side{display:grid;justify-items:end;min-width:0}
1738
3161
  .knobs-card-side>*{grid-area:1/1;min-width:0;max-width:100%;transition:opacity var(--k-token-t)}
1739
- .knobs-card-summary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--k-dim);font-size:var(--k-text-control);font-weight:500;letter-spacing:0;opacity:0;pointer-events:none}
3162
+ .knobs-card-summary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--_k-fg-3);font-size:var(--_k-text-control);font-weight:500;letter-spacing:0;opacity:0;pointer-events:none}
1740
3163
  .knobs-live[data-collapsed] .knobs-card-summary{opacity:1;pointer-events:auto}
1741
3164
  .knobs-live[data-collapsed] .knobs-card-summary:not(:empty)~*{opacity:0;pointer-events:none}
1742
3165
  .knobs-card-right>.knobs-caret{margin-right:calc((var(--k-icon-sm) - 20px) / 2 + 5px)}
1743
- .knobs-live>.knobs-group-head:hover .knobs-caret{color:var(--k-label)}
3166
+ .knobs-live>.knobs-group-head:hover .knobs-caret{color:var(--_k-fg-2)}
1744
3167
  .knobs-live>.knobs-group-head[aria-expanded="true"] .knobs-caret{transform:rotate(90deg)}
1745
- .knobs-item-detail{flex:none;color:var(--k-dim);font-size:var(--k-text-control);font-variant-numeric:tabular-nums;white-space:nowrap}
1746
- `;
1747
- function injectPreset(doc, preset) {
1748
- let content = presetCss(preset), existing = doc.querySelector(`style[data-knobs-preset="${preset.name}"]`);
1749
- if (existing) {
1750
- if (existing.textContent !== content)
1751
- existing.textContent = content;
1752
- return;
1753
- }
1754
- let style = doc.createElement("style");
1755
- style.dataset.knobsPreset = preset.name, style.textContent = content, doc.head.append(style);
1756
- }
1757
- var keyboardQuietsHover = (css) => css.replaceAll(":hover", ":hover:where(:not([data-k-quiet]))"), withoutHas = (css) => css.replaceAll(":has(:focus-visible)", "[data-k-fv]").replaceAll(":has(.knobs-track:focus-visible)", '[data-k-fv="track"]').replaceAll(":has(.knobs-active)", "[data-k-active]");
3168
+ .knobs-item-detail{flex:none;color:var(--_k-fg-3);font-size:var(--_k-text-control);font-variant-numeric:tabular-nums;white-space:nowrap}
3169
+ `, keyboardQuietsHover = (css) => css.replaceAll(":hover", ":hover:where(:not([data-k-quiet]))"), withoutHas = (css) => css.replaceAll(":has(:focus-visible)", "[data-k-fv]").replaceAll(":has(.knobs-track:focus-visible)", '[data-k-fv="track"]').replaceAll(":has(.knobs-active)", "[data-k-active]"), panelCss = () => rolling_css_default + defaultsCss + keyboardQuietsHover(withoutHas(aliased(css2)));
1758
3170
  function injectStyles(doc) {
1759
- let content = rolling_css_default + DRIVERS + defaultsCss + keyboardQuietsHover(withoutHas(aliased(css))), existing = doc.querySelector("style[data-knobs-style]");
3171
+ injectTokens(doc);
3172
+ let content = panelCss(), existing = doc.querySelector("style[data-knobs-style]");
1760
3173
  if (existing) {
1761
3174
  if (existing.textContent !== content)
1762
3175
  existing.textContent = content;
@@ -2690,13 +4103,13 @@ function hintTokens(doc, groups) {
2690
4103
  return v;
2691
4104
  }
2692
4105
  return "";
2693
- }, panel = doc.querySelector(".knobs-panel"), piece = groups.find((g) => g.source && !g.source.paint)?.source?.root, pick = (k, fallback) => read(panel, [`--k-${k}`]) || read(piece, [`--ku-${k}`, `--k-${k}`]) || fallback;
4106
+ }, panel = doc.querySelector(".knobs-panel"), piece = groups.find((g) => g.source && !g.source.paint)?.source?.root, pick = (k, fallback) => read(panel, [`--_k-${k}`]) || read(piece, [`--_k-${k}`]) || fallback;
2694
4107
  return {
2695
4108
  "--kh-accent": pick("accent", "#fff"),
2696
4109
  "--kh-bg": pick("bg", "#1c1c1e"),
2697
4110
  "--kh-mono": pick("mono", "ui-monospace,Menlo,monospace"),
2698
- "--kh-radius": read(panel, ["--k-radius-sm"]) || "4px",
2699
- "--kh-size": read(panel, ["--k-text-cap"]) || "10px",
4111
+ "--kh-radius": read(panel, ["--_k-radius-sm"]) || "4px",
4112
+ "--kh-size": read(panel, ["--_k-text-cap"]) || "10px",
2700
4113
  "--kh-typed": read(panel, ["--k-hint-typed-opacity"]) || ".42",
2701
4114
  "--kh-lift": read(panel, ["--k-lift"]) || "1",
2702
4115
  "--kh-ease": read(panel, ["--k-ease"]) || "cubic-bezier(.2,.8,.2,1)"
@@ -2816,4 +4229,4 @@ function createLayer(doc) {
2816
4229
  };
2817
4230
  }
2818
4231
 
2819
- export { CHECK_POINTS, CHECK_PATH, iconPath, iconSvg, readSession, writeSession, rolling_css_default, presetCss, FILL, LEAD, trailScale, Edges, POP_MS, popScale, settleScale, VelocityTracker, clamp, Roll, rollTarget, numeral, entranceOffset, FLASH_MS, flash, flashOf, offRow, precisionRate, RULER, RULER_NEAR, RULER_FADE, rulerLevels, rulerAlpha, rulerDepth, THIN, THINNEST, thinOf, roundOf, stretchOf, stretchAt, giveRoom, detentScale, detentsOf, roundValues, unwarp, Notches, escapeTo, commandScope, scopeLabel, crumbTrail, escTarget, digitOption, digitHints, createCrumbs, DELAYED, injectPreset, injectStyles, resolveSound, sound, SOUND_PREF, soundPanel, changed, cue, createHintController, pageHints, toggleLayer };
4232
+ export { resolveLook, themeOf, applyLook, panelLook, CHECK_POINTS, CHECK_PATH, iconPath, iconSvg, readSession, writeSession, rolling_css_default, FILL, LEAD, trailScale, Edges, POP_MS, popScale, settleScale, VelocityTracker, clamp, Roll, rollTarget, numeral, entranceOffset, FLASH_MS, flash, flashOf, offRow, precisionRate, RULER, RULER_NEAR, RULER_FADE, rulerLevels, rulerAlpha, rulerDepth, THIN, THINNEST, thinOf, roundOf, stretchOf, stretchAt, giveRoom, detentScale, detentsOf, roundValues, unwarp, Notches, escapeTo, commandScope, scopeLabel, crumbTrail, escTarget, digitOption, digitHints, createCrumbs, TOKENS, knobs, aliased, injectTokens, DELAYED, injectStyles, resolveSound, sound, SOUND_PREF, soundPanel, changed, cue, createHintController, pageHints, toggleLayer };