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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +288 -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 +1 -1
  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/ui-react.js +2320 -676
  41. package/dist/ui-solid.js +2320 -676
  42. package/dist/ui.js +2552 -906
  43. package/package.json +1 -1
package/dist/ui-solid.js CHANGED
@@ -92,6 +92,30 @@ function springCss(value) {
92
92
  return { easing, duration: ms };
93
93
  }
94
94
 
95
+ // src/core/motion.ts
96
+ var SPRINGS, FADE, CLOSE, MOTION, reducedMotion = (win) => win?.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false, springLinear = (spring) => {
97
+ const { omega, zeta } = springMotion(spring);
98
+ return springEasing(omega, zeta);
99
+ }, names, linear, SPRING_TOKEN, DEFAULT_LINEAR, motionCss;
100
+ var init_motion = __esm(() => {
101
+ SPRINGS = {
102
+ instant: { duration: 0.1, bounce: 0 },
103
+ snappy: { duration: 0.25, bounce: 0 },
104
+ default: { duration: 0.3, bounce: 0 },
105
+ calm: { duration: 0.4, bounce: 0 },
106
+ smooth: { duration: 0.45, bounce: 0 }
107
+ };
108
+ FADE = { duration: 0.16, bounce: 0 };
109
+ CLOSE = { duration: 0.18, bounce: 0 };
110
+ MOTION = Object.fromEntries(Object.entries(SPRINGS).map(([name, spring]) => [name, springMotion(spring)]));
111
+ names = Object.keys(SPRINGS);
112
+ linear = Object.fromEntries(names.map((n) => [n, springLinear(SPRINGS[n])]));
113
+ SPRING_TOKEN = `${SPRINGS.default.duration} ${SPRINGS.default.bounce}`;
114
+ DEFAULT_LINEAR = linear.default;
115
+ motionCss = `:where(:root,:host){${names.map((n) => `--_k-motion-${n}:${linear[n].easing};--_k-motion-${n}-ms:${linear[n].ms}`).join(";")}}
116
+ @media(prefers-reduced-motion:reduce){:where(:root,:host){${names.map((n) => `--_k-motion-${n}-ms:0`).join(";")}}}`;
117
+ });
118
+
95
119
  // src/panel/rolling-css.ts
96
120
  var rolling_css_default = `.rn-root {
97
121
  display: inline-block;
@@ -195,11 +219,18 @@ var rolling_css_default = `.rn-root {
195
219
  function presetCss(preset) {
196
220
  if (!/^[\w-]+$/.test(preset.name))
197
221
  throw new Error(`Invalid preset name: ${preset.name}`);
198
- const at = `.knobs-panel[data-preset="${preset.name}"]`;
199
- const 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)}}}` : "";
200
- return `${at}{${block(preset.dark)}}${light}${(preset.css ?? "").replaceAll("&", at)}`;
222
+ const at = `.knobs-root[data-preset="${preset.name}"]`;
223
+ const light = preset.light ?? {};
224
+ const decls = Object.entries(preset.dark).map(([k, dark]) => {
225
+ const l = light[k];
226
+ return l === undefined || String(l) === String(dark) ? `${property(k)}:${dark}` : `${property(k)}:light-dark(${l},${dark})`;
227
+ });
228
+ for (const [k, l] of Object.entries(light))
229
+ if (!(k in preset.dark) && k !== "color-scheme")
230
+ decls.push(`${property(k)}:${l}`);
231
+ return `${at}{${decls.join(";")}}${(preset.css ?? "").replaceAll("&", at)}`;
201
232
  }
202
- var block = (tokens) => Object.entries(tokens).map(([k, v]) => `${k.startsWith("--") || k === "color-scheme" ? k : `--k-${k}`}:${v}`).join(";"), glide, problemsPreset;
233
+ var property = (k) => k.startsWith("--") ? k : `--k-${k}`, glide, problemsPreset;
203
234
  var init_theme = __esm(() => {
204
235
  glide = /* @__PURE__ */ springCss({ duration: 0.185, bounce: 0.14 });
205
236
  problemsPreset = {
@@ -279,44 +310,166 @@ var init_theme = __esm(() => {
279
310
  "toggle-thumb": "#fff",
280
311
  rim: "transparent",
281
312
  "group-color": "rgba(60,60,67,.66)",
282
- "group-divider": "rgba(0,0,0,.07)",
283
- "color-scheme": "light"
313
+ "group-divider": "rgba(0,0,0,.07)"
284
314
  }
285
315
  };
286
316
  });
287
317
 
318
+ // src/core/appearance.ts
319
+ function resolveLook(options = {}, base) {
320
+ const t = options.theme;
321
+ const mode = typeof t === "string" ? MODES[t] : undefined;
322
+ const theme = typeof t === "object" ? t : base?.theme;
323
+ const preset = options.preset ?? base?.preset;
324
+ return {
325
+ ...theme ? { theme } : {},
326
+ appearance: options.appearance ?? mode ?? base?.appearance ?? "inherit",
327
+ ...preset ? { preset } : {}
328
+ };
329
+ }
330
+ function themeOf(el) {
331
+ const name = el.closest("[data-knobs-theme]")?.dataset.knobsTheme;
332
+ return name ? themes.get(name) : undefined;
333
+ }
334
+ function upsertStyle(doc, key, value, content) {
335
+ const existing = doc.querySelector(`style[${key}="${value}"]`);
336
+ if (existing) {
337
+ if (existing.textContent !== content)
338
+ existing.textContent = content;
339
+ return;
340
+ }
341
+ const style = doc.createElement("style");
342
+ style.setAttribute(key, value);
343
+ style.textContent = content;
344
+ doc.head.append(style);
345
+ }
346
+ function injectTheme(doc, theme) {
347
+ themes.set(theme.name, theme);
348
+ upsertStyle(doc, "data-knobs-theme-css", theme.name, theme.css({ selector: themeSelector(theme.name) }));
349
+ }
350
+ function injectPreset(doc, preset) {
351
+ presets.set(preset.name, preset);
352
+ upsertStyle(doc, "data-knobs-preset", preset.name, presetCss(preset));
353
+ }
354
+ function applyLook(el, look) {
355
+ const doc = el.ownerDocument;
356
+ if (look.theme)
357
+ injectTheme(doc, look.theme);
358
+ if (look.preset)
359
+ injectPreset(doc, look.preset);
360
+ setAttr(el, "data-knobs-theme", look.theme?.name);
361
+ setAttr(el, "data-preset", look.preset?.name);
362
+ setAttr(el, "data-appearance", look.appearance === "inherit" ? undefined : look.appearance);
363
+ if (look.appearance === "inherit")
364
+ followPage(el);
365
+ else
366
+ clearInherited(el);
367
+ }
368
+ function resolveInherited(el) {
369
+ const parent = el.parentElement;
370
+ const win = el.ownerDocument.defaultView;
371
+ if (!parent || !win || el.hasAttribute("data-appearance"))
372
+ return;
373
+ if (parent.closest(".knobs-root"))
374
+ return clearInherited(el);
375
+ const scheme = win.getComputedStyle(parent).colorScheme.trim();
376
+ const dark = /\bdark\b/.test(scheme);
377
+ const light = /\blight\b/.test(scheme);
378
+ if (!dark && !light)
379
+ return clearInherited(el);
380
+ const isLight = dark && light ? win.matchMedia?.("(prefers-color-scheme: light)").matches ?? false : light;
381
+ el.style.setProperty("color-scheme", "inherit");
382
+ el.style.setProperty("--_k-light", isLight ? "1" : "0");
383
+ }
384
+ function followPage(el) {
385
+ const doc = el.ownerDocument;
386
+ const win = doc.defaultView;
387
+ if (!win)
388
+ return;
389
+ const run = () => resolveInherited(el);
390
+ if (el.isConnected)
391
+ run();
392
+ queueMicrotask(run);
393
+ win.requestAnimationFrame?.(run);
394
+ if (watched.has(doc))
395
+ return;
396
+ watched.add(doc);
397
+ const all = () => {
398
+ for (const root of doc.querySelectorAll(".knobs-root:not([data-appearance])"))
399
+ resolveInherited(root);
400
+ };
401
+ const observer = new MutationObserver(all);
402
+ const attributeFilter = ["class", "data-theme", "data-appearance"];
403
+ observer.observe(doc.documentElement, { attributes: true, attributeFilter });
404
+ if (doc.body)
405
+ observer.observe(doc.body, { attributes: true, attributeFilter });
406
+ win.matchMedia?.("(prefers-color-scheme: light)").addEventListener?.("change", all);
407
+ }
408
+ function lookAt(el) {
409
+ const win = el.ownerDocument.defaultView;
410
+ const light = win?.getComputedStyle(el).getPropertyValue("--_k-light").trim() === "1";
411
+ const theme = themeOf(el);
412
+ const name = el.closest("[data-preset]")?.dataset.preset;
413
+ const preset = name ? presets.get(name) : undefined;
414
+ return {
415
+ ...theme ? { theme } : {},
416
+ appearance: light ? "light" : "dark",
417
+ ...preset ? { preset } : {}
418
+ };
419
+ }
420
+ var MODES, themes, themeSelector = (name) => `:where(.knobs-root)[data-knobs-theme="${name}"]`, presets, setAttr = (el, name, value) => {
421
+ if (value === undefined)
422
+ el.removeAttribute(name);
423
+ else if (el.getAttribute(name) !== value)
424
+ el.setAttribute(name, value);
425
+ }, clearInherited = (el) => {
426
+ el.style.removeProperty("color-scheme");
427
+ el.style.removeProperty("--_k-light");
428
+ }, watched;
429
+ var init_appearance = __esm(() => {
430
+ init_theme();
431
+ MODES = {
432
+ dark: "dark",
433
+ light: "light",
434
+ auto: "system"
435
+ };
436
+ themes = new Map;
437
+ presets = new Map;
438
+ watched = new WeakSet;
439
+ });
440
+
288
441
  // src/ui/activity-css.ts
289
442
  var open, activityCss;
290
443
  var init_activity_css = __esm(() => {
291
- open = springEasing(2 * Math.PI / 0.22, 1);
444
+ init_motion();
445
+ open = springLinear(SPRINGS.snappy);
292
446
  activityCss = `
293
447
  :where(.knobs-activity,.knobs-activity *){box-sizing:border-box}
294
- :where(.knobs-activity){color-scheme:dark}
295
448
  .knobs-ui.knobs-activity{position:relative;display:block;height:100%;overflow:auto;overflow-anchor:none;outline:none;scrollbar-width:none;overscroll-behavior:contain;user-select:none;-webkit-user-select:none;
296
- font:var(--ku-font-weight) var(--ku-font-size)/1.35 var(--ku-font);color:var(--ku-text);text-align:left;letter-spacing:normal;-webkit-font-smoothing:antialiased;
297
- --ka-gutter:var(--k-activity-gutter,28px);--ka-row:var(--k-activity-row,var(--ku-row));--ka-row-child:var(--k-activity-row-child,calc(var(--ka-row) - 6px));
298
- --ka-line:var(--k-activity-line,var(--ku-line-hi));--ka-select:var(--k-activity-select,var(--ku-wash-hi));--ka-hover:var(--k-activity-hover,var(--ku-wash));
299
- --ka-you:var(--k-activity-you,light-dark(#007aff,#0a84ff));--ka-agent:var(--k-activity-agent,var(--ku-label));--ka-proposal:var(--k-activity-proposal,var(--ku-text));
300
- --ka-review:var(--k-activity-review,var(--ku-text));--ka-pr:var(--k-activity-pr,light-dark(#8944ab,#bf5af2));--ka-build:var(--k-activity-build,var(--ku-label));
301
- --ka-blocked:var(--k-activity-blocked,var(--ku-warn));--ka-shipped:var(--k-activity-shipped,light-dark(#248a3d,#30d158));--ka-open-ease:${open.easing};--ka-open-ms:${open.ms}ms}
449
+ font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);text-align:left;letter-spacing:normal;-webkit-font-smoothing:antialiased;
450
+ --ka-gutter:var(--k-activity-gutter,28px);--ka-row:var(--k-activity-row,var(--_k-row));--ka-row-child:var(--k-activity-row-child,calc(var(--ka-row) - 6px));
451
+ --ka-line:var(--_k-activity-rail);--ka-select:var(--k-activity-select,var(--_ku-wash-hi));--ka-hover:var(--k-activity-hover,var(--_ku-wash));
452
+ --ka-you:var(--k-activity-you,var(--_k-info));--ka-agent:var(--k-activity-agent,var(--_k-fg-2));--ka-proposal:var(--k-activity-proposal,var(--_k-fg));
453
+ --ka-review:var(--k-activity-review,var(--_k-fg));--ka-pr:var(--k-activity-pr,var(--_k-series-5));--ka-build:var(--k-activity-build,var(--_k-fg-2));
454
+ --ka-blocked:var(--k-activity-blocked,var(--_k-warn));--ka-shipped:var(--k-activity-shipped,var(--_k-ok));--ka-open-ease:${open.easing};--ka-open-ms:${open.ms}ms}
302
455
  .knobs-activity [hidden]{display:none!important}
303
456
  /* Clipped below: the content grows on a spring, so a new last row shows as the rail makes room. */
304
457
  .knobs-activity-space{position:relative;width:100%;overflow-x:visible;overflow-y:clip;pointer-events:none}
305
- .knobs-activity-line{position:absolute;top:0;left:calc(var(--ku-row-x) + var(--ka-gutter) / 2 - 1px);width:2px;height:100%;overflow:visible;pointer-events:none;z-index:1}
458
+ .knobs-activity-line{position:absolute;top:0;left:calc(var(--_ku-row-x) + var(--ka-gutter) / 2 - 1px);width:2px;height:100%;overflow:visible;pointer-events:none;z-index:1}
306
459
  .knobs-activity-line path{fill:none;stroke:var(--ka-line);stroke-width:1px}
307
460
  /* The selection's tint: a wash that glides between rows, shown only once keys move it. It leaves
308
461
  in 100 ms when the pointer is used, and comes back at once. */
309
- .knobs-activity-hl{position:absolute;left:var(--ku-row-x);right:var(--ku-row-x);top:0;height:0;border-radius:var(--ku-row-radius);background:var(--ka-select);opacity:0;
462
+ .knobs-activity-hl{position:absolute;left:var(--_ku-row-x);right:var(--_ku-row-x);top:0;height:0;border-radius:var(--_ku-row-radius);background:var(--ka-select);opacity:0;
310
463
  transition:opacity 100ms ease-out;pointer-events:none;will-change:transform}
311
464
  .knobs-activity[data-keys] .knobs-activity-hl{opacity:1;transition:none}
312
- .knobs-activity-row{position:absolute;left:var(--ku-row-x);right:var(--ku-row-x);top:0;display:flex;align-items:center;height:var(--ka-row);padding-right:calc(var(--ku-inset) - 4px);
313
- color:var(--ku-text);white-space:nowrap;cursor:default;will-change:transform;transform-origin:calc(var(--ka-gutter) / 2) 50%;pointer-events:auto;--ka-tint:var(--ka-agent)}
465
+ .knobs-activity-row{position:absolute;left:var(--_ku-row-x);right:var(--_ku-row-x);top:0;display:flex;align-items:center;height:var(--ka-row);padding-right:calc(var(--_k-inset) - 4px);
466
+ color:var(--_k-fg);white-space:nowrap;cursor:default;will-change:transform;transform-origin:calc(var(--ka-gutter) / 2) 50%;pointer-events:auto;--ka-tint:var(--ka-agent)}
314
467
  .knobs-activity-row[data-leaving]{pointer-events:none}
315
468
  .knobs-activity-row[data-depth="1"]{height:var(--ka-row-child)}
316
469
  .knobs-activity-row>*{position:relative}
317
470
  /* Hover: in at once, out over 100 ms; not while keys drive the selection. */
318
- .knobs-activity-row::before{content:"";position:absolute;inset:0;border-radius:var(--ku-row-radius);background:var(--ka-hover);opacity:0;transition:opacity calc(var(--k-hover-out,100) * 1ms) ease-out;pointer-events:none}
319
- .knobs-activity:not([data-keys]) .knobs-activity-row:not([data-leaving]):hover::before{opacity:1;transition-duration:calc(var(--k-hover-in,0) * 1ms)}
471
+ .knobs-activity-row::before{content:"";position:absolute;inset:0;border-radius:var(--_ku-row-radius);background:var(--ka-hover);opacity:0;transition:opacity calc(var(--_k-hover-out,100) * 1ms) ease-out;pointer-events:none}
472
+ .knobs-activity:not([data-keys]) .knobs-activity-row:not([data-leaving]):hover::before{opacity:1;transition-duration:calc(var(--_k-hover-in,0) * 1ms)}
320
473
  .knobs-activity-row[data-kind="you"]{--ka-tint:var(--ka-you)}
321
474
  .knobs-activity-row[data-kind="agent"]{--ka-tint:var(--ka-agent)}
322
475
  .knobs-activity-row[data-kind="proposal"]{--ka-tint:var(--ka-proposal)}
@@ -328,7 +481,7 @@ var init_activity_css = __esm(() => {
328
481
  /* The node: the kind's icon on the line (which stops clear of it), or a small dot inside a group. */
329
482
  .knobs-activity-node{flex:none;display:flex;align-items:center;justify-content:center;width:var(--ka-gutter);height:100%;color:var(--ka-tint)}
330
483
  .knobs-activity-node svg{display:block;width:14px;height:14px}
331
- .knobs-activity-glyph{display:flex;align-items:center;justify-content:center;width:14px;height:14px;font-size:calc(var(--ku-font-size) - 1px);line-height:1}
484
+ .knobs-activity-glyph{display:flex;align-items:center;justify-content:center;width:14px;height:14px;font-size:calc(var(--_k-font-size) - 1px);line-height:1}
332
485
  .knobs-activity-node::before{content:"";position:absolute;left:50%;top:50%;width:22px;height:22px;margin:-11px 0 0 -11px;border-radius:50%;background:color-mix(in srgb,var(--ka-tint) 15%,transparent);
333
486
  opacity:0;scale:.8;transition:opacity .16s ease-out,scale var(--ka-open-ms) var(--ka-open-ease)}
334
487
  .knobs-activity-row[aria-selected="true"] .knobs-activity-node::before{opacity:1;scale:1}
@@ -340,48 +493,48 @@ var init_activity_css = __esm(() => {
340
493
  .knobs-activity-row[data-depth="1"] .knobs-activity-node::before,.knobs-activity-row[data-depth="1"] .knobs-activity-node::after{width:13px;height:13px;margin:-6.5px 0 0 -6.5px}
341
494
  /* The words: who in the text colour, then the title, one line that fades where it's cut off. */
342
495
  .knobs-activity-main{flex:1;min-width:0;overflow:hidden;white-space:nowrap}
343
- .knobs-activity-actor{margin-right:6px;font-weight:var(--ku-label-weight);color:var(--ku-text)}
496
+ .knobs-activity-actor{margin-right:6px;font-weight:var(--_k-weight-label);color:var(--_k-fg)}
344
497
  .knobs-activity-actor:empty{display:none}
345
- .knobs-activity-title{color:var(--ku-label)}
346
- .knobs-activity-row[data-depth="1"] .knobs-activity-main{font-size:var(--ku-text-meta)}
347
- .knobs-activity-row[data-depth="1"] .knobs-activity-actor{font-weight:var(--ku-font-weight);color:var(--ku-label)}
348
- .knobs-activity-row[data-depth="1"] .knobs-activity-title{color:var(--ku-dim)}
349
- .knobs-activity-row[aria-selected="true"] .knobs-activity-title{color:var(--ku-text)}
498
+ .knobs-activity-title{color:var(--_k-fg-2)}
499
+ .knobs-activity-row[data-depth="1"] .knobs-activity-main{font-size:var(--_k-text-meta)}
500
+ .knobs-activity-row[data-depth="1"] .knobs-activity-actor{font-weight:var(--_k-weight);color:var(--_k-fg-2)}
501
+ .knobs-activity-row[data-depth="1"] .knobs-activity-title{color:var(--_k-fg-3)}
502
+ .knobs-activity-row[aria-selected="true"] .knobs-activity-title{color:var(--_k-fg)}
350
503
  .knobs-activity-row[data-dimmed] :is(.knobs-activity-main,.knobs-activity-meta){opacity:.55}
351
504
  .knobs-activity-row[data-dimmed] .knobs-activity-node{opacity:.6}
352
505
  /* Trailing: thumbnails, a duration chip, the group's chevron and the time. */
353
- .knobs-activity-meta{flex:none;display:flex;align-items:center;gap:6px;margin-left:8px;color:var(--ku-dim);font-size:var(--ku-text-meta);font-variant-numeric:tabular-nums}
506
+ .knobs-activity-meta{flex:none;display:flex;align-items:center;gap:6px;margin-left:8px;color:var(--_k-fg-3);font-size:var(--_k-text-meta);font-variant-numeric:tabular-nums}
354
507
  .knobs-activity-meta:empty{display:none}
355
508
  .knobs-activity-thumbs{display:flex;gap:3px}
356
- .knobs-activity-thumbs img{display:block;width:18px;height:18px;border-radius:4px;object-fit:cover;background:var(--ku-surface);box-shadow:inset 0 0 0 .5px var(--ku-line)}
509
+ .knobs-activity-thumbs img{display:block;width:18px;height:18px;border-radius:4px;object-fit:cover;background:var(--_k-fill);box-shadow:inset 0 0 0 .5px var(--_k-border)}
357
510
  .knobs-activity-row[data-depth="1"] .knobs-activity-thumbs img{width:15px;height:15px}
358
511
  :where(.knobs-ui) .knobs-activity-chip{all:revert;box-sizing:border-box;display:inline-flex;align-items:center;gap:4px;height:18px;padding:0 6px 0 5px;border:0;margin:0;border-radius:9px;
359
- background:var(--ku-surface);color:var(--ku-label);font:inherit;font-variant-numeric:tabular-nums;letter-spacing:inherit;outline:none;transition:background calc(var(--k-hover-out,100) * 1ms) ease-out}
512
+ background:var(--_k-fill);color:var(--_k-fg-2);font:inherit;font-variant-numeric:tabular-nums;letter-spacing:inherit;outline:none;transition:background calc(var(--_k-hover-out,100) * 1ms) ease-out}
360
513
  .knobs-activity-chip svg{width:8px;height:8px}
361
514
  button.knobs-activity-chip{cursor:pointer}
362
- button.knobs-activity-chip:hover{background:var(--ku-surface-hi);color:var(--ku-text);transition-duration:0s}
363
- .knobs-activity-caret{display:flex;width:12px;height:12px;color:var(--ku-dim);transition:rotate .18s var(--ku-ease)}
515
+ button.knobs-activity-chip:hover{background:var(--_k-fill-selected);color:var(--_k-fg);transition-duration:0s}
516
+ .knobs-activity-caret{display:flex;width:12px;height:12px;color:var(--_k-fg-3);transition:rotate .18s var(--_ku-ease)}
364
517
  .knobs-activity-caret svg{width:10px;height:10px;margin:1px}
365
518
  .knobs-activity-row[aria-expanded="true"] .knobs-activity-caret{rotate:90deg;transition:rotate var(--ka-open-ms) var(--ka-open-ease)}
366
519
  .knobs-activity-time{min-width:2ch;text-align:right;white-space:nowrap}
367
520
  .knobs-activity-time:empty{display:none}
368
- .knobs-activity-empty{padding:10px var(--ku-inset);color:var(--ku-dim)}
521
+ .knobs-activity-empty{padding:10px var(--_k-inset);color:var(--_k-fg-3)}
369
522
  @media(prefers-reduced-motion:reduce){.knobs-activity :where(*,::before,::after){transition:none!important;animation:none!important}}
370
523
  `;
371
524
  });
372
525
 
373
526
  // src/ui/bento-css.ts
374
527
  var bentoCss = `
375
- .knobs-ui.knobs-bento{--ku-bento-radius:var(--k-ui-bento-radius,max(0px,calc(var(--ku-radius) - 5px)));
376
- position:relative;width:100%;height:100%;overflow:hidden auto;outline:none;background:var(--k-ui-bento-bg,var(--ku-page));
528
+ .knobs-ui.knobs-bento{--_ku-bento-radius:var(--k-ui-bento-radius,max(0px,calc(var(--_k-radius) - 5px)));
529
+ position:relative;width:100%;height:100%;overflow:hidden auto;outline:none;background:var(--k-ui-bento-bg,var(--_k-bg-page));
377
530
  scrollbar-width:thin;scrollbar-gutter:stable;overscroll-behavior:contain;touch-action:pan-y;user-select:none;-webkit-user-select:none;
378
- font:var(--ku-font-weight) var(--ku-font-size)/1.35 var(--ku-font);color:var(--ku-text);letter-spacing:normal;text-align:left}
379
- .knobs-bento[data-frame="flat"]{--ku-bento-radius:var(--k-ui-bento-radius,0px)}
531
+ font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left}
532
+ .knobs-bento[data-frame="flat"]{--_ku-bento-radius:var(--k-ui-bento-radius,0px)}
380
533
  .knobs-bento[data-pending] .knobs-bento-space{visibility:hidden}
381
534
  :where(.knobs-bento-space,.knobs-bento-space *){box-sizing:border-box}
382
535
  .knobs-bento-space{position:relative;width:100%}
383
- .knobs-bento-tile{position:absolute;left:0;top:0;transform-origin:0 0;overflow:hidden;border-radius:var(--ku-bento-radius);
384
- background:var(--ku-surface);contain:strict;cursor:zoom-in}
536
+ .knobs-bento-tile{position:absolute;left:0;top:0;transform-origin:0 0;overflow:hidden;border-radius:var(--_ku-bento-radius);
537
+ background:var(--_k-fill);contain:strict;cursor:zoom-in}
385
538
  .knobs-bento-tile[data-focus]{z-index:2;cursor:zoom-out}
386
539
  .knobs-bento-tile[data-focus][data-live]{cursor:auto}
387
540
  .knobs-bento-img{display:block;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .18s cubic-bezier(.2,.8,.2,1);-webkit-user-drag:none}
@@ -389,49 +542,49 @@ var bentoCss = `
389
542
  .knobs-bento-tile[data-instant] .knobs-bento-img{transition:none}
390
543
  .knobs-bento-body{position:absolute;inset:0;pointer-events:none}
391
544
  .knobs-bento-tile[data-focus] .knobs-bento-body{pointer-events:auto}
392
- .knobs-bento-label{position:absolute;left:9px;right:9px;bottom:7px;color:#fff;font-size:var(--ku-text-meta);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
393
- text-shadow:0 0 6px rgba(0,0,0,.55),0 0 1px rgba(0,0,0,.5);opacity:0;pointer-events:none;transition:opacity calc(var(--ku-hover-out) * 1ms)}
545
+ .knobs-bento-label{position:absolute;left:9px;right:9px;bottom:7px;color:#fff;font-size:var(--_k-text-meta);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
546
+ text-shadow:0 0 6px rgba(0,0,0,.55),0 0 1px rgba(0,0,0,.5);opacity:0;pointer-events:none;transition:opacity calc(var(--_k-hover-out) * 1ms)}
394
547
  .knobs-bento:not([data-keyboard]) .knobs-bento-tile:hover .knobs-bento-label,
395
548
  .knobs-bento[data-keyboard]:focus .knobs-bento-tile[data-active] .knobs-bento-label,
396
- .knobs-bento-tile[data-focus] .knobs-bento-label{opacity:1;transition-duration:calc(var(--ku-hover-in) * 1ms)}
549
+ .knobs-bento-tile[data-focus] .knobs-bento-label{opacity:1;transition-duration:calc(var(--_k-hover-in) * 1ms)}
397
550
  /* A pick: a small dot in the accent, ringed in the page so it reads on any picture. */
398
- .knobs-bento-tile::after{content:"";position:absolute;top:8px;right:8px;width:8px;height:8px;border-radius:50%;background:var(--ku-accent);
399
- box-shadow:0 0 0 1.5px color-mix(in srgb,var(--ku-page) 70%,transparent);opacity:0;scale:.4;pointer-events:none;
400
- transition:opacity .11s cubic-bezier(.4,0,1,1),scale var(--ku-ease-ms) var(--ku-ease)}
401
- .knobs-bento-tile[aria-selected="true"]::after{opacity:1;scale:1;transition:opacity .15s cubic-bezier(.2,.8,.2,1),scale var(--ku-ease-ms) var(--ku-ease)}
402
- .knobs-bento-wash{position:absolute;left:0;top:0;width:100px;height:100px;transform-origin:0 0;z-index:3;pointer-events:none;border-radius:var(--ku-bento-radius);
403
- background:color-mix(in srgb,var(--ku-accent) 12%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ku-accent) 45%,transparent);
551
+ .knobs-bento-tile::after{content:"";position:absolute;top:8px;right:8px;width:8px;height:8px;border-radius:50%;background:var(--_k-accent);
552
+ box-shadow:0 0 0 1.5px color-mix(in srgb,var(--_k-bg-page) 70%,transparent);opacity:0;scale:.4;pointer-events:none;
553
+ transition:opacity .11s cubic-bezier(.4,0,1,1),scale var(--_ku-ease-ms) var(--_ku-ease)}
554
+ .knobs-bento-tile[aria-selected="true"]::after{opacity:1;scale:1;transition:opacity .15s cubic-bezier(.2,.8,.2,1),scale var(--_ku-ease-ms) var(--_ku-ease)}
555
+ .knobs-bento-wash{position:absolute;left:0;top:0;width:100px;height:100px;transform-origin:0 0;z-index:3;pointer-events:none;border-radius:var(--_ku-bento-radius);
556
+ background:color-mix(in srgb,var(--_k-accent) 12%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--_k-accent) 45%,transparent);
404
557
  opacity:0;transition:opacity .15s}
405
558
  .knobs-bento[data-keyboard]:focus:not([data-zoomed]) .knobs-bento-wash[data-on]{opacity:1}
406
- .knobs-bento-scrim{position:absolute;left:0;top:0;width:100%;z-index:1;background:var(--k-ui-scrim,var(--k-ui-bento-bg,var(--ku-page)));opacity:0;pointer-events:none;cursor:zoom-out}
559
+ .knobs-bento-scrim{position:absolute;left:0;top:0;width:100%;z-index:1;background:var(--k-ui-scrim,var(--k-ui-bento-bg,var(--_k-bg-page)));opacity:0;pointer-events:none;cursor:zoom-out}
407
560
  .knobs-bento[data-zoomed] .knobs-bento-scrim{pointer-events:auto}
408
- .knobs-bento-head{position:absolute;left:0;top:0;display:flex;align-items:flex-end;padding:0 0 6px 2px;color:var(--ku-label);font-weight:var(--ku-label-weight);
409
- font-size:var(--ku-text-meta);white-space:nowrap;pointer-events:none}
561
+ .knobs-bento-head{position:absolute;left:0;top:0;display:flex;align-items:flex-end;padding:0 0 6px 2px;color:var(--_k-fg-2);font-weight:var(--_k-weight-label);
562
+ font-size:var(--_k-text-meta);white-space:nowrap;pointer-events:none}
410
563
  `;
411
564
 
412
565
  // src/ui/compare-css.ts
413
566
  var compareCss = `
414
567
  :where(.knobs-compare,.knobs-compare *,.knobs-cmp-strip,.knobs-cmp-strip *){box-sizing:border-box}
415
- .knobs-ui.knobs-compare{--ku-cmp-diff:var(--k-compare-diff,#7dcf9c);--ku-cmp-line:var(--k-compare-line,#fff);
416
- --ku-cmp-stage:var(--k-compare-stage,var(--ku-surface));
568
+ .knobs-ui.knobs-compare{--_ku-cmp-diff:var(--k-compare-diff,var(--_k-ok));--_ku-cmp-line:var(--_k-compare-divider);
569
+ --_ku-cmp-stage:var(--_k-compare-stage);
417
570
  display:flex;flex-direction:column;gap:6px;width:100%;height:100%;min-height:160px;outline:none;user-select:none;-webkit-user-select:none;
418
- font:var(--ku-font-weight) var(--ku-font-size)/1.35 var(--ku-font);color:var(--ku-text);letter-spacing:normal;text-align:left}
571
+ font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left}
419
572
  :where(.knobs-ui) :is(.knobs-cmp-mode,.knobs-cmp-toggle){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;margin:0;padding:0;outline:none;box-shadow:none}
420
573
  .knobs-cmp-bar{flex:none;display:flex;align-items:center;gap:2px;height:24px;padding:0 2px}
421
574
  .knobs-cmp-modes{display:flex;align-items:center;gap:2px}
422
- .knobs-ui .knobs-cmp-mode,.knobs-ui .knobs-cmp-toggle{height:22px;padding:0 7px;border-radius:max(0px,calc(var(--ku-radius) - 2px));color:var(--ku-dim);cursor:pointer;white-space:nowrap;
575
+ .knobs-ui .knobs-cmp-mode,.knobs-ui .knobs-cmp-toggle{height:22px;padding:0 7px;border-radius:max(0px,calc(var(--_k-radius) - 2px));color:var(--_k-fg-3);cursor:pointer;white-space:nowrap;
423
576
  transition:color .15s,background .15s}
424
- .knobs-ui .knobs-cmp-mode:is(:hover,:focus-visible),.knobs-ui .knobs-cmp-toggle:is(:hover,:focus-visible){color:var(--ku-text);background:var(--ku-wash)}
425
- .knobs-ui .knobs-cmp-mode[aria-checked="true"],.knobs-ui .knobs-cmp-toggle[aria-pressed="true"]{color:var(--ku-text);font-weight:var(--ku-label-weight)}
577
+ .knobs-ui .knobs-cmp-mode:is(:hover,:focus-visible),.knobs-ui .knobs-cmp-toggle:is(:hover,:focus-visible){color:var(--_k-fg);background:var(--_ku-wash)}
578
+ .knobs-ui .knobs-cmp-mode[aria-checked="true"],.knobs-ui .knobs-cmp-toggle[aria-pressed="true"]{color:var(--_k-fg);font-weight:var(--_k-weight-label)}
426
579
  .knobs-cmp-fill{flex:1}
427
580
  .knobs-cmp-toggle[hidden]{display:none}
428
581
  /* One surface: on a card (a walkthrough's step, a split's pane, anything .knobs-surface) or marked
429
582
  data-nested, the stage drops its fill and the sides sit on that card. */
430
- :where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip) .knobs-ui.knobs-compare,.knobs-ui.knobs-compare[data-nested]{--ku-cmp-stage:var(--k-compare-stage,transparent)}
583
+ :where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip) .knobs-ui.knobs-compare,.knobs-ui.knobs-compare[data-nested]{--_ku-cmp-stage:var(--k-compare-stage,transparent)}
431
584
  /* In a page's flow (a container with no height), it takes the height its sides need. */
432
585
  .knobs-ui.knobs-compare[data-auto]{height:auto}
433
586
  .knobs-compare[data-auto] .knobs-cmp-stage{flex:none;min-height:0}
434
- .knobs-cmp-stage{position:relative;flex:1;min-height:96px;overflow:hidden;border-radius:var(--ku-panel-radius);background:var(--ku-cmp-stage);touch-action:pan-y;outline:none}
587
+ .knobs-cmp-stage{position:relative;flex:1;min-height:96px;overflow:hidden;border-radius:var(--_k-radius-panel);background:var(--_ku-cmp-stage);touch-action:pan-y;outline:none}
435
588
  .knobs-compare[data-frame="flat"] .knobs-cmp-stage{border-radius:0}
436
589
  .knobs-compare[data-mode="wipe"] .knobs-cmp-stage{cursor:ew-resize}
437
590
  /* Unzoomed, a finger still scrolls the page up and down; zoomed, the stage takes every gesture. */
@@ -443,37 +596,37 @@ var compareCss = `
443
596
  .knobs-cmp-media{position:absolute;left:0;top:0;display:block;max-width:none;margin:0;padding:0;border:0;object-fit:fill;transform-origin:0 0;pointer-events:none;will-change:transform}
444
597
  .knobs-compare[data-renderer="gpu"] .knobs-cmp-media{opacity:0}
445
598
  /* Glass: what's behind shows through, blurred, on the knobs tokens. */
446
- .knobs-cmp-label,.knobs-cmp-zoom{background:color-mix(in srgb,var(--ku-bg) 52%,transparent);-webkit-backdrop-filter:blur(14px) saturate(1.6);backdrop-filter:blur(14px) saturate(1.6);
447
- box-shadow:inset 0 0 0 .5px var(--ku-line),inset 0 1px 0 var(--ku-rim),0 2px 10px rgba(0,0,0,.18)}
448
- .knobs-cmp-label{position:absolute;left:0;top:0;padding:1px 7px;border-radius:999px;font-size:var(--ku-text-meta);line-height:16px;color:var(--ku-label);white-space:nowrap;pointer-events:none;will-change:transform;transition:color .15s}
449
- .knobs-cmp-label[data-lit]{color:var(--ku-text)}
450
- .knobs-cmp-label[data-dim]{color:var(--ku-dim)}
599
+ .knobs-cmp-label,.knobs-cmp-zoom{background:color-mix(in srgb,var(--_k-bg) 52%,transparent);-webkit-backdrop-filter:blur(14px) saturate(1.6);backdrop-filter:blur(14px) saturate(1.6);
600
+ box-shadow:inset 0 0 0 .5px var(--_k-border),inset 0 1px 0 var(--_k-rim),0 2px 10px rgba(0,0,0,calc(.18 * var(--_k-shadow-k,1)))}
601
+ .knobs-cmp-label{position:absolute;left:0;top:0;padding:1px 7px;border-radius:999px;font-size:var(--_k-text-meta);line-height:16px;color:var(--_k-fg-2);white-space:nowrap;pointer-events:none;will-change:transform;transition:color .15s}
602
+ .knobs-cmp-label[data-lit]{color:var(--_k-fg)}
603
+ .knobs-cmp-label[data-dim]{color:var(--_k-fg-3)}
451
604
  /* The wipe: a hairline down the line with a grip at its middle; a wider strip takes the hand and
452
605
  the keys (a slider). It fades with the mode. */
453
606
  .knobs-cmp-handle{cursor:ew-resize;position:absolute;left:-12px;top:0;width:24px;height:0;opacity:0;pointer-events:none;outline:none;will-change:transform;transition:opacity .18s cubic-bezier(.4,0,1,1)}
454
607
  .knobs-cmp-handle[data-on]{opacity:1;pointer-events:auto;transition:opacity .22s cubic-bezier(.2,.8,.2,1)}
455
- .knobs-cmp-handle::before{content:"";position:absolute;top:0;bottom:0;left:11.5px;width:1px;background:var(--ku-cmp-line);box-shadow:0 0 0 .5px rgba(0,0,0,.28),0 0 6px rgba(0,0,0,.25)}
456
- .knobs-cmp-handle::after{content:"";position:absolute;top:50%;left:9px;width:6px;height:28px;margin-top:-14px;border-radius:3px;background:var(--ku-cmp-line);
457
- box-shadow:0 1px 3px rgba(0,0,0,.35),0 0 0 .5px rgba(0,0,0,.2);transition:scale .18s var(--ku-ease),box-shadow .15s}
608
+ .knobs-cmp-handle::before{content:"";position:absolute;top:0;bottom:0;left:11.5px;width:1px;background:var(--_ku-cmp-line);box-shadow:0 0 0 .5px rgba(0,0,0,.28),0 0 6px rgba(0,0,0,.25)}
609
+ .knobs-cmp-handle::after{content:"";position:absolute;top:50%;left:9px;width:6px;height:28px;margin-top:-14px;border-radius:3px;background:var(--_ku-cmp-line);
610
+ box-shadow:0 1px 3px rgba(0,0,0,.35),0 0 0 .5px rgba(0,0,0,.2);transition:scale .18s var(--_ku-ease),box-shadow .15s}
458
611
  .knobs-compare[data-dragging] .knobs-cmp-handle::after{scale:1.12}
459
- .knobs-cmp-handle:focus-visible::after,.knobs-compare[data-keyboard] .knobs-cmp-handle:focus::after{box-shadow:0 1px 3px rgba(0,0,0,.35),0 0 0 3px color-mix(in srgb,var(--ku-accent) 40%,transparent)}
612
+ .knobs-cmp-handle:focus-visible::after,.knobs-compare[data-keyboard] .knobs-cmp-handle:focus::after{box-shadow:0 1px 3px rgba(0,0,0,.35),0 0 0 3px color-mix(in srgb,var(--_k-accent) 40%,transparent)}
460
613
  /* The split's hairline, down the middle side by side. */
461
- .knobs-cmp-split{position:absolute;left:0;top:0;width:1px;height:0;margin-left:-.5px;background:color-mix(in srgb,var(--ku-bg) 72%,transparent);pointer-events:none;will-change:transform,opacity}
614
+ .knobs-cmp-split{position:absolute;left:0;top:0;width:1px;height:0;margin-left:-.5px;background:color-mix(in srgb,var(--_k-bg) 72%,transparent);pointer-events:none;will-change:transform,opacity}
462
615
  /* Zoomed: how far, and a way back, in the stage's corner; it fades in and out, nothing shifts. */
463
616
  .knobs-cmp-zoom{position:absolute;right:8px;bottom:8px;display:flex;align-items:center;gap:4px;height:26px;padding:0 3px 0 10px;border-radius:999px;
464
- color:var(--ku-text);font-size:var(--ku-text-meta);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap;
617
+ color:var(--_k-fg);font-size:var(--_k-text-meta);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap;
465
618
  opacity:0;scale:.96;pointer-events:none;transition:opacity .16s cubic-bezier(.4,0,1,1),scale .16s cubic-bezier(.4,0,1,1)}
466
619
  .knobs-cmp-zoom[data-on]{opacity:1;scale:1;pointer-events:auto;transition:opacity .2s cubic-bezier(.2,.8,.2,1),scale .2s cubic-bezier(.2,.8,.2,1)}
467
620
  :where(.knobs-ui) .knobs-cmp-zoom-reset{all:revert;box-sizing:border-box;font:inherit;letter-spacing:inherit;margin:0;border:0;outline:none;box-shadow:none;
468
- height:20px;padding:0 8px;border-radius:999px;background:transparent;color:var(--ku-label);cursor:pointer;transition:color .15s,background .15s}
469
- :where(.knobs-ui) .knobs-cmp-zoom-reset:is(:hover,:focus-visible){color:var(--ku-text);background:color-mix(in srgb,var(--ku-text) 12%,transparent)}
470
- .knobs-cmp-note{position:absolute;left:50%;top:50%;translate:-50% -50%;color:var(--ku-dim);font-size:var(--ku-text-meta);pointer-events:none}
621
+ height:20px;padding:0 8px;border-radius:999px;background:transparent;color:var(--_k-fg-2);cursor:pointer;transition:color .15s,background .15s}
622
+ :where(.knobs-ui) .knobs-cmp-zoom-reset:is(:hover,:focus-visible){color:var(--_k-fg);background:color-mix(in srgb,var(--_k-fg) 12%,transparent)}
623
+ .knobs-cmp-note{position:absolute;left:50%;top:50%;translate:-50% -50%;color:var(--_k-fg-3);font-size:var(--_k-text-meta);pointer-events:none}
471
624
  .knobs-cmp-note:empty{display:none}
472
625
  .knobs-cmp-strip-host{flex:none;height:60px;min-height:0}
473
626
  .knobs-cmp-timeline-host{flex:none;height:56px;min-height:0}
474
627
  /* The frame strip: Before over After per column, a difference bar under them, a dot where it peaks. */
475
- .knobs-ui.knobs-cmp-strip{--ku-cmp-diff:var(--k-compare-diff,#7dcf9c);position:relative;width:100%;height:100%;min-height:40px;overflow:hidden;cursor:col-resize;touch-action:none;
476
- font:var(--ku-font-weight) var(--ku-font-size)/1.35 var(--ku-font);color:var(--ku-text)}
628
+ .knobs-ui.knobs-cmp-strip{--_ku-cmp-diff:var(--k-compare-diff,var(--_k-ok));position:relative;width:100%;height:100%;min-height:40px;overflow:hidden;cursor:col-resize;touch-action:none;
629
+ font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg)}
477
630
  .knobs-cmp-strip>canvas{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none}
478
631
  @media(prefers-reduced-motion:reduce){:is(.knobs-compare,.knobs-cmp-strip) :where(*,::before,::after){transition-duration:.12s!important}}
479
632
  `;
@@ -482,135 +635,136 @@ var compareCss = `
482
635
  var overlayCss = `
483
636
  .knobs-layers{position:fixed;inset:0;z-index:2147480005;pointer-events:none}
484
637
  .knobs-layers>.knobs-layer,.knobs-ui.knobs-toast{position:fixed;left:0;top:0;box-sizing:border-box;pointer-events:auto;outline:none;
485
- font:var(--ku-font-weight) var(--ku-font-size)/1.4 var(--ku-font);color:var(--ku-text);letter-spacing:normal;text-align:left;text-transform:none;
638
+ font:var(--_k-weight) var(--_k-font-size)/1.4 var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left;text-transform:none;
486
639
  -webkit-font-smoothing:antialiased;will-change:transform,opacity,filter}
487
640
  /* The overlays' own elements stop a host's element rules; what you put in a popover is yours. */
488
641
  :where(.knobs-layers,.knobs-toast) :is(.knobs-kbd,.knobs-mitem,.knobs-menu-sep,.knobs-palette-input,.knobs-palette-label>mark,.knobs-confirm-title,.knobs-confirm-body,.knobs-confirm-btn,.knobs-toast-action){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;
489
642
  background:transparent;border:0;margin:0;padding:0;outline:none;box-shadow:none}
490
643
  .knobs-layers .knobs-layer *{box-sizing:border-box}
491
644
  /* A floating surface: frosted, a hairline rim, a soft shadow. */
492
- .knobs-layers>:is(.knobs-popover-layer,.knobs-palette,.knobs-confirm,.knobs-menu-layer){background:color-mix(in srgb,var(--ku-bg) 88%,transparent);
493
- -webkit-backdrop-filter:blur(28px) saturate(1.7);backdrop-filter:blur(28px) saturate(1.7);border-radius:var(--ku-panel-radius);
494
- box-shadow:0 0 0 .5px var(--ku-line-hi),inset 0 1px 0 var(--ku-rim),0 12px 40px rgba(0,0,0,.36),0 2px 8px rgba(0,0,0,.18)}
645
+ .knobs-layers>:is(.knobs-popover-layer,.knobs-palette,.knobs-confirm,.knobs-menu-layer){background:color-mix(in srgb,var(--_k-bg) 88%,transparent);
646
+ -webkit-backdrop-filter:blur(28px) saturate(1.7);backdrop-filter:blur(28px) saturate(1.7);border-radius:var(--_k-radius-panel);
647
+ box-shadow:0 0 0 .5px var(--_k-border-strong),inset 0 1px 0 var(--_k-rim),0 12px 40px rgba(0,0,0,calc(.36 * var(--_k-shadow-k,1))),0 2px 8px rgba(0,0,0,calc(.18 * var(--_k-shadow-k,1)))}
495
648
  .knobs-layers>.knobs-popover-layer{min-width:120px;max-width:min(420px,calc(100vw - 16px));padding:6px}
496
- .knobs-popover-layer .knobs-popover-text{padding:4px 6px;color:var(--ku-label)}
649
+ .knobs-popover-layer .knobs-popover-text{padding:4px 6px;color:var(--_k-fg-2)}
497
650
 
498
651
  /* Menus: rows of the panel's control height, a soft wash on the active one (never an outline),
499
652
  concentric corners inside the surface. */
500
653
  .knobs-layers>.knobs-menu-layer{display:flex;flex-direction:column;min-width:184px;max-width:min(340px,calc(100vw - 16px));max-height:calc(100vh - 16px);overflow:auto;padding:5px;
501
654
  scrollbar-width:thin;overscroll-behavior:contain;user-select:none;-webkit-user-select:none}
502
- .knobs-menu-layer .knobs-mitem{position:relative;display:flex;align-items:center;gap:8px;flex:none;height:max(22px,calc(var(--ku-row) - 6px));padding:0 8px;
503
- border-radius:max(0px,calc(var(--ku-panel-radius) - 5px));color:var(--ku-text);cursor:default;white-space:nowrap}
504
- .knobs-menu-layer .knobs-mitem[data-active],.knobs-menu-layer .knobs-mitem[data-open]{background:var(--ku-wash-hi)}
505
- .knobs-menu-layer .knobs-mitem[data-destructive]{color:var(--ku-critical)}
506
- .knobs-menu-layer .knobs-mitem[data-destructive][data-active]{background:color-mix(in srgb,var(--ku-critical) 16%,transparent)}
655
+ .knobs-menu-layer .knobs-mitem{position:relative;display:flex;align-items:center;gap:8px;flex:none;height:max(22px,calc(var(--_k-row) - 6px));padding:0 8px;
656
+ border-radius:max(0px,calc(var(--_k-radius-panel) - 5px));color:var(--_k-fg);cursor:default;white-space:nowrap}
657
+ .knobs-menu-layer .knobs-mitem[data-active],.knobs-menu-layer .knobs-mitem[data-open]{background:var(--_ku-wash-hi)}
658
+ .knobs-menu-layer .knobs-mitem[data-destructive]{color:var(--_k-danger)}
659
+ .knobs-menu-layer .knobs-mitem[data-destructive][data-active]{background:color-mix(in srgb,var(--_k-danger) 16%,transparent)}
507
660
  .knobs-menu-layer .knobs-mitem[aria-disabled="true"]{opacity:.38}
508
- .knobs-menu-layer .knobs-menu-lead{flex:none;display:flex;align-items:center;justify-content:center;width:14px;margin-left:-2px;color:var(--ku-label);font-size:calc(var(--ku-font-size) - 1px)}
661
+ .knobs-menu-layer .knobs-menu-lead{flex:none;display:flex;align-items:center;justify-content:center;width:14px;margin-left:-2px;color:var(--_k-fg-2);font-size:calc(var(--_k-font-size) - 1px)}
509
662
  .knobs-menu-layer .knobs-mitem[data-destructive] .knobs-menu-lead,.knobs-menu-layer .knobs-mitem[aria-checked="true"] .knobs-menu-lead{color:inherit}
510
663
  .knobs-menu-layer .knobs-menu-lead svg{width:13px;height:13px}
511
664
  .knobs-menu-layer .knobs-menu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis}
512
- .knobs-menu-layer .knobs-menu-hint{flex:none;color:var(--ku-dim)}
665
+ .knobs-menu-layer .knobs-menu-hint{flex:none;color:var(--_k-fg-3)}
513
666
  .knobs-menu-layer .knobs-menu-keys{display:inline-flex;gap:2px;flex:none;margin-left:12px}
514
- .knobs-menu-layer .knobs-mitem[data-active] .knobs-kbd{background:color-mix(in srgb,var(--ku-text) 14%,transparent);color:var(--ku-text)}
515
- .knobs-menu-layer .knobs-menu-caret{flex:none;display:flex;margin-left:8px;margin-right:-3px;color:var(--ku-dim)}
667
+ .knobs-menu-layer .knobs-mitem[data-active] .knobs-kbd{background:color-mix(in srgb,var(--_k-fg) 14%,transparent);color:var(--_k-fg)}
668
+ .knobs-menu-layer .knobs-menu-caret{flex:none;display:flex;margin-left:8px;margin-right:-3px;color:var(--_k-fg-3)}
516
669
  .knobs-menu-layer .knobs-menu-caret svg{width:10px;height:10px}
517
- .knobs-menu-layer .knobs-menu-sep{flex:none;height:1px;margin:4px 8px;background:var(--ku-line)}
670
+ .knobs-menu-layer .knobs-menu-sep{flex:none;height:1px;margin:4px 8px;background:var(--_k-border)}
518
671
 
519
672
  .knobs-layers>.knobs-tooltip{display:inline-flex;align-items:center;gap:7px;max-width:300px;padding:4px 8px;pointer-events:none;white-space:nowrap;
520
- font-size:calc(var(--ku-font-size) - .5px);background:var(--ku-bg);color:var(--ku-text);border-radius:min(var(--ku-radius),6px);
521
- box-shadow:0 0 0 .5px var(--ku-line-hi),0 4px 14px rgba(0,0,0,.3)}
673
+ font-size:calc(var(--_k-font-size) - .5px);background:var(--_k-bg);color:var(--_k-fg);border-radius:min(var(--_k-radius),6px);
674
+ box-shadow:0 0 0 .5px var(--_k-border-strong),0 4px 14px rgba(0,0,0,calc(.3 * var(--_k-shadow-k,1)))}
522
675
  .knobs-tooltip .knobs-tooltip-text{overflow:hidden;text-overflow:ellipsis}
523
676
  .knobs-layer :is(.knobs-tooltip-keys,.knobs-palette-keys){display:inline-flex;gap:2px;flex:none}
524
677
  .knobs-layer .knobs-tooltip-keys[hidden]{display:none}
525
678
  .knobs-layer .knobs-kbd{display:inline-flex;align-items:center;justify-content:center;min-width:17px;height:17px;padding:0 4px;
526
- border-radius:min(var(--ku-radius),4px);background:var(--ku-surface-hi);color:var(--ku-label);font:500 calc(var(--ku-font-size) - 1.5px)/1 var(--ku-font)}
679
+ border-radius:min(var(--_k-radius),4px);background:var(--_k-fill-selected);color:var(--_k-fg-2);font:500 calc(var(--_k-font-size) - 1.5px)/1 var(--_k-font)}
527
680
 
528
681
  .knobs-layers>.knobs-palette{left:50%;top:max(48px,15vh);translate:-50% 0;transform-origin:50% 0;display:flex;flex-direction:column;
529
682
  width:min(580px,calc(100vw - 32px));max-height:min(460px,72vh);overflow:hidden}
530
- .knobs-palette .knobs-palette-field{display:flex;align-items:center;gap:10px;flex:none;height:46px;padding:0 16px;border-bottom:1px solid var(--ku-line);color:var(--ku-dim)}
683
+ .knobs-palette .knobs-palette-field{display:flex;align-items:center;gap:10px;flex:none;height:46px;padding:0 16px;border-bottom:1px solid var(--_k-border);color:var(--_k-fg-3)}
531
684
  .knobs-palette .knobs-palette-field svg{width:15px;height:15px;flex:none}
532
- .knobs-palette .knobs-palette-input{flex:1;min-width:0;height:100%;font-size:calc(var(--ku-font-size) + 3px);color:var(--ku-text);caret-color:var(--ku-accent)}
533
- .knobs-palette .knobs-palette-input::placeholder{color:var(--ku-dim)}
685
+ .knobs-palette .knobs-palette-input{flex:1;min-width:0;height:100%;font-size:calc(var(--_k-font-size) + 3px);color:var(--_k-fg);caret-color:var(--_k-accent)}
686
+ .knobs-palette .knobs-palette-input::placeholder{color:var(--_k-fg-3)}
534
687
  .knobs-palette .knobs-palette-list{position:relative;flex:1;min-height:0;overflow:auto;padding:6px;scrollbar-width:thin;overscroll-behavior:contain}
535
- .knobs-palette .knobs-palette-hl{position:absolute;left:6px;right:6px;top:0;border-radius:max(0px,calc(var(--ku-panel-radius) - 6px));background:var(--ku-wash-hi);opacity:0;pointer-events:none;
536
- transition:transform var(--ku-ease-ms) var(--ku-ease),height var(--ku-ease-ms) var(--ku-ease),opacity .12s}
537
- .knobs-palette .knobs-palette-section{padding:10px 10px 4px;color:var(--ku-dim);font-size:calc(var(--ku-font-size) - 1px);font-weight:var(--ku-label-weight);user-select:none}
688
+ .knobs-palette .knobs-palette-hl{position:absolute;left:6px;right:6px;top:0;border-radius:max(0px,calc(var(--_k-radius-panel) - 6px));background:var(--_ku-wash-hi);opacity:0;pointer-events:none;
689
+ transition:transform var(--_ku-ease-ms) var(--_ku-ease),height var(--_ku-ease-ms) var(--_ku-ease),opacity .12s}
690
+ .knobs-palette .knobs-palette-section{padding:10px 10px 4px;color:var(--_k-fg-3);font-size:calc(var(--_k-font-size) - 1px);font-weight:var(--_k-weight-label);user-select:none}
538
691
  .knobs-palette .knobs-palette-section:first-of-type{padding-top:4px}
539
- .knobs-palette .knobs-palette-item{position:relative;display:flex;align-items:center;gap:8px;height:max(32px,var(--ku-row));padding:0 10px;
540
- color:var(--ku-label);cursor:default;user-select:none}
541
- .knobs-palette .knobs-palette-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ku-text)}
692
+ .knobs-palette .knobs-palette-item{position:relative;display:flex;align-items:center;gap:8px;height:max(32px,var(--_k-row));padding:0 10px;
693
+ color:var(--_k-fg-2);cursor:default;user-select:none}
694
+ .knobs-palette .knobs-palette-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--_k-fg)}
542
695
  /* Searching, the label dims and its matched letters light up. */
543
- .knobs-palette[data-query] .knobs-palette-label{color:var(--ku-label)}
544
- .knobs-palette .knobs-palette-label mark{color:var(--ku-accent);font-weight:var(--ku-title-weight)}
545
- .knobs-palette[data-query] .knobs-palette-item[data-active] .knobs-palette-label{color:var(--ku-text)}
546
- .knobs-palette .knobs-palette-hint{flex:none;color:var(--ku-dim)}
696
+ .knobs-palette[data-query] .knobs-palette-label{color:var(--_k-fg-2)}
697
+ .knobs-palette .knobs-palette-label mark{color:var(--_k-accent);font-weight:var(--_k-weight-title)}
698
+ .knobs-palette[data-query] .knobs-palette-item[data-active] .knobs-palette-label{color:var(--_k-fg)}
699
+ .knobs-palette .knobs-palette-hint{flex:none;color:var(--_k-fg-3)}
547
700
  .knobs-palette .knobs-palette-fill{flex:1}
548
- .knobs-palette .knobs-palette-tag{flex:none;color:var(--ku-dim);font-size:calc(var(--ku-font-size) - 1px);white-space:nowrap}
701
+ .knobs-palette .knobs-palette-tag{flex:none;color:var(--_k-fg-3);font-size:calc(var(--_k-font-size) - 1px);white-space:nowrap}
549
702
  .knobs-palette .knobs-palette-item[aria-disabled="true"]{opacity:.4}
550
- .knobs-palette .knobs-palette-empty{padding:18px 10px;color:var(--ku-dim);text-align:center}
703
+ .knobs-palette .knobs-palette-empty{padding:18px 10px;color:var(--_k-fg-3);text-align:center}
551
704
 
552
- .knobs-layers>.knobs-scrim{inset:0;width:100%;height:100%;background:rgba(0,0,0,.3)}
705
+ .knobs-layers>.knobs-scrim{inset:0;width:100%;height:100%;background:var(--_k-scrim)}
553
706
  .knobs-layers>.knobs-confirm{left:50%;top:42%;translate:-50% -50%;width:min(340px,calc(100vw - 32px));padding:18px 18px 14px}
554
- .knobs-confirm .knobs-confirm-title{margin:0 0 6px;font-size:calc(var(--ku-font-size) + 1.5px);font-weight:var(--ku-title-weight);color:var(--ku-text);line-height:1.3}
555
- .knobs-confirm .knobs-confirm-body{margin:0;color:var(--ku-label);line-height:1.45}
707
+ .knobs-confirm .knobs-confirm-title{margin:0 0 6px;font-size:calc(var(--_k-font-size) + 1.5px);font-weight:var(--_k-weight-title);color:var(--_k-fg);line-height:1.3}
708
+ .knobs-confirm .knobs-confirm-body{margin:0;color:var(--_k-fg-2);line-height:1.45}
556
709
  .knobs-confirm .knobs-confirm-buttons{display:flex;justify-content:flex-end;gap:8px;margin-top:18px}
557
- .knobs-confirm .knobs-confirm-btn{height:28px;padding:0 14px;border-radius:min(var(--ku-radius),7px);background:var(--ku-surface-hi);color:var(--ku-text);
558
- font-weight:var(--ku-label-weight);cursor:pointer;transition:background .15s,filter .15s}
559
- .knobs-confirm .knobs-confirm-cancel:is(:hover,:focus-visible){background:color-mix(in srgb,var(--ku-text) 18%,transparent)}
560
- .knobs-confirm .knobs-confirm-ok{background:var(--ku-accent);color:var(--ku-bg)}
561
- .knobs-confirm .knobs-confirm-ok[data-destructive]{background:var(--ku-critical);color:#fff}
710
+ .knobs-confirm .knobs-confirm-btn{height:28px;padding:0 14px;border-radius:min(var(--_k-radius),7px);background:var(--_k-fill-selected);color:var(--_k-fg);
711
+ font-weight:var(--_k-weight-label);cursor:pointer;transition:background .15s,filter .15s}
712
+ .knobs-confirm .knobs-confirm-cancel:is(:hover,:focus-visible){background:color-mix(in srgb,var(--_k-fg) 18%,transparent)}
713
+ .knobs-confirm .knobs-confirm-ok{background:var(--_k-accent);color:var(--_k-bg)}
714
+ .knobs-confirm .knobs-confirm-ok[data-destructive]{background:var(--_k-danger);color:#fff}
562
715
  .knobs-confirm .knobs-confirm-ok:is(:hover,:focus-visible){filter:brightness(1.14)}
563
716
 
564
717
  .knobs-ui.knobs-toast{left:50%;top:auto;bottom:24px;z-index:2147480005;translate:-50% 0;display:inline-flex;align-items:center;gap:10px;
565
- max-width:min(480px,80vw);padding:8px 16px;background:var(--ku-bg);color:var(--ku-text);border-radius:calc(var(--ku-radius) * 999);
566
- box-shadow:0 0 0 .5px var(--ku-line-hi),0 8px 28px rgba(0,0,0,.32)}
718
+ max-width:min(480px,80vw);padding:8px 16px;background:var(--_k-bg);color:var(--_k-fg);border-radius:calc(var(--_k-radius) * 999);
719
+ box-shadow:0 0 0 .5px var(--_k-border-strong),0 8px 28px rgba(0,0,0,calc(.32 * var(--_k-shadow-k,1)))}
567
720
  .knobs-toast .knobs-toast-text{overflow-wrap:anywhere}
568
- .knobs-toast[data-tone="warn"]::before,.knobs-toast[data-tone="error"]::before{content:"";flex:none;width:7px;height:7px;border-radius:50%;background:var(--ku-warn)}
569
- .knobs-toast[data-tone="error"]::before{background:var(--ku-critical)}
570
- .knobs-toast .knobs-toast-action{flex:none;color:var(--ku-accent);font-weight:var(--ku-title-weight);cursor:pointer}
721
+ .knobs-toast[data-tone="warn"]::before,.knobs-toast[data-tone="error"]::before{content:"";flex:none;width:7px;height:7px;border-radius:50%;background:var(--_k-warn)}
722
+ .knobs-toast[data-tone="error"]::before{background:var(--_k-danger)}
723
+ .knobs-toast .knobs-toast-action{flex:none;color:var(--_k-accent);font-weight:var(--_k-weight-title);cursor:pointer}
571
724
  .knobs-toast .knobs-toast-action[hidden]{display:none}
572
725
  `;
573
726
 
574
727
  // src/ui/picker-css.ts
575
728
  var snappy, pickerCss;
576
729
  var init_picker_css = __esm(() => {
577
- snappy = springEasing(2 * Math.PI / 0.25, 1);
730
+ init_motion();
731
+ snappy = springLinear(SPRINGS.snappy);
578
732
  pickerCss = `
579
733
  :where(.knobs-picker,.knobs-picker-option,.knobs-picker-head,.knobs-picker-head *,.knobs-picker-card,.knobs-picker-body){box-sizing:border-box}
580
734
  .knobs-ui.knobs-picker{position:relative;display:flex;flex-direction:column;gap:2px;padding:0;outline:none;
581
- font:var(--ku-font-weight) var(--ku-font-size)/1.35 var(--ku-font);color:var(--ku-text);text-align:left;letter-spacing:normal;-webkit-font-smoothing:antialiased;
582
- --kp-card:var(--k-picker-card,var(--ku-surface));--kp-radius:var(--k-picker-radius,var(--ku-panel-radius));--kp-snappy:${snappy.easing};--kp-snappy-ms:${snappy.ms}ms}
735
+ font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);text-align:left;letter-spacing:normal;-webkit-font-smoothing:antialiased;
736
+ --kp-card:var(--_k-picker-card);--kp-radius:var(--k-picker-radius,var(--_k-radius-panel));--kp-snappy:${snappy.easing};--kp-snappy-ms:${snappy.ms}ms}
583
737
  .knobs-picker [hidden]{display:none!important}
584
738
  /* The selection: one card behind the selected option and its parameters, gliding between them. */
585
- .knobs-picker-card{position:absolute;left:0;right:0;top:0;height:0;border-radius:var(--kp-radius);background:var(--kp-card);box-shadow:inset 0 0 0 1px var(--ku-line);pointer-events:none}
739
+ .knobs-picker-card{position:absolute;left:0;right:0;top:0;height:0;border-radius:var(--kp-radius);background:var(--kp-card);box-shadow:inset 0 0 0 1px var(--_k-border);pointer-events:none}
586
740
  .knobs-picker[data-frame="flat"] .knobs-picker-card{box-shadow:none}
587
741
  .knobs-picker-option{position:relative;flex:none}
588
- :where(.knobs-ui) .knobs-picker-head{all:revert;box-sizing:border-box;position:relative;display:flex;align-items:center;gap:8px;width:100%;height:var(--ku-row);padding:0 calc(var(--ku-inset) - 2px) 0 calc(var(--ku-inset) - 4px);
589
- border:0;margin:0;background:transparent;color:var(--ku-label);font:inherit;letter-spacing:inherit;text-align:left;cursor:default;outline:none;user-select:none;-webkit-user-select:none}
742
+ :where(.knobs-ui) .knobs-picker-head{all:revert;box-sizing:border-box;position:relative;display:flex;align-items:center;gap:8px;width:100%;height:var(--_k-row);padding:0 calc(var(--_k-inset) - 2px) 0 calc(var(--_k-inset) - 4px);
743
+ border:0;margin:0;background:transparent;color:var(--_k-fg-2);font:inherit;letter-spacing:inherit;text-align:left;cursor:default;outline:none;user-select:none;-webkit-user-select:none}
590
744
  /* Hover: in at once, out over 100 ms. Keyboard focus: the same wash, a little firmer. */
591
- .knobs-picker-head::before{content:"";position:absolute;inset:0;border-radius:var(--kp-radius);background:var(--ku-wash);opacity:0;transition:opacity calc(var(--k-hover-out,100) * 1ms) ease-out;pointer-events:none}
592
- .knobs-picker-option:not([data-selected]) .knobs-picker-head:hover::before{opacity:1;transition-duration:calc(var(--k-hover-in,0) * 1ms)}
593
- .knobs-picker-head:focus-visible::before{opacity:1;background:var(--ku-wash-hi);transition-duration:0s}
745
+ .knobs-picker-head::before{content:"";position:absolute;inset:0;border-radius:var(--kp-radius);background:var(--_ku-wash);opacity:0;transition:opacity calc(var(--_k-hover-out,100) * 1ms) ease-out;pointer-events:none}
746
+ .knobs-picker-option:not([data-selected]) .knobs-picker-head:hover::before{opacity:1;transition-duration:calc(var(--_k-hover-in,0) * 1ms)}
747
+ .knobs-picker-head:focus-visible::before{opacity:1;background:var(--_ku-wash-hi);transition-duration:0s}
594
748
  .knobs-picker-head>*{position:relative}
595
- .knobs-picker-option[data-selected] .knobs-picker-head{color:var(--ku-text)}
749
+ .knobs-picker-option[data-selected] .knobs-picker-head{color:var(--_k-fg)}
596
750
  /* Every row is numbered (only 1–9 are keys): tabular digits in a column two digits wide, so the
597
751
  names line up past the ninth. */
598
- .knobs-picker-key{flex:none;display:inline-flex;align-items:center;justify-content:center;width:max(17px,calc(2ch + 6px));height:17px;padding:0;border-radius:5px;background:var(--ku-surface);
599
- color:var(--ku-dim);font:var(--ku-label-weight) calc(var(--ku-font-size) - 1.5px)/1 var(--ku-font);font-variant-numeric:tabular-nums;transition:background .15s,color .15s}
752
+ .knobs-picker-key{flex:none;display:inline-flex;align-items:center;justify-content:center;width:max(17px,calc(2ch + 6px));height:17px;padding:0;border-radius:5px;background:var(--_k-fill);
753
+ color:var(--_k-fg-3);font:var(--_k-weight-label) calc(var(--_k-font-size) - 1.5px)/1 var(--_k-font);font-variant-numeric:tabular-nums;transition:background .15s,color .15s}
600
754
  .knobs-picker-key:empty{visibility:hidden}
601
755
  /* An option's picture: cover-fit, the rows' corner language and a hairline drawn over it. Its
602
756
  space is kept while it loads (nothing drawn), it fades in once loaded, and one that fails
603
757
  gives its space back on the same ease. */
604
- .knobs-picker-thumb{flex:none;display:block;width:var(--k-picker-thumb,min(24px,calc(var(--ku-row) - 10px)));aspect-ratio:1;margin:0;border-radius:max(3px,calc(var(--ku-radius) - 2px));
605
- object-fit:cover;background:none;outline:1px solid var(--ku-line);outline-offset:-1px;opacity:0;
758
+ .knobs-picker-thumb{flex:none;display:block;width:var(--k-picker-thumb,min(24px,calc(var(--_k-row) - 10px)));aspect-ratio:1;margin:0;border-radius:max(3px,calc(var(--_k-radius) - 2px));
759
+ object-fit:cover;background:none;outline:1px solid var(--_k-border);outline-offset:-1px;opacity:0;
606
760
  transition:opacity .2s ease-out,width .18s ease-out,margin .18s ease-out}
607
761
  .knobs-picker-thumb[data-state="loaded"]{opacity:1}
608
762
  .knobs-picker-thumb[data-instant]{transition:none}
609
763
  .knobs-picker-thumb[data-state="failed"]{width:0;margin-right:-8px;outline-color:transparent}
610
- .knobs-picker-option[data-selected] .knobs-picker-key{background:var(--ku-surface-hi);color:var(--ku-text)}
611
- .knobs-picker-name{flex:1;min-width:0;overflow:hidden;white-space:nowrap;font-weight:var(--ku-label-weight)}
612
- .knobs-picker-suggested{flex:none;color:var(--ku-dim);font-size:var(--ku-text-meta)}
613
- .knobs-picker-check{flex:none;display:flex;width:14px;height:14px;color:var(--ku-accent);opacity:0;scale:.6;filter:blur(2px);
764
+ .knobs-picker-option[data-selected] .knobs-picker-key{background:var(--_k-fill-selected);color:var(--_k-fg)}
765
+ .knobs-picker-name{flex:1;min-width:0;overflow:hidden;white-space:nowrap;font-weight:var(--_k-weight-label)}
766
+ .knobs-picker-suggested{flex:none;color:var(--_k-fg-3);font-size:var(--_k-text-meta)}
767
+ .knobs-picker-check{flex:none;display:flex;width:14px;height:14px;color:var(--_k-accent);opacity:0;scale:.6;filter:blur(2px);
614
768
  transition:opacity .11s ease-in,scale .11s ease-in,filter .11s ease-in}
615
769
  .knobs-picker-check svg{display:block;width:14px;height:14px}
616
770
  .knobs-picker-option[data-chosen] .knobs-picker-check{opacity:1;scale:1;filter:none;transition:opacity .15s ease-out,scale var(--kp-snappy-ms) var(--kp-snappy),filter .15s ease-out}
@@ -622,7 +776,7 @@ var init_picker_css = __esm(() => {
622
776
  .knobs-picker-inner{padding:var(--k-picker-pad,0 8px 8px)}
623
777
  .knobs-picker-inner:empty{padding:0}
624
778
  .knobs-picker-inner .knobs-panel.knobs-inline{--k-chrome:0;padding:0}
625
- .knobs-picker-empty{padding:8px var(--ku-inset);color:var(--ku-dim)}
779
+ .knobs-picker-empty{padding:8px var(--_k-inset);color:var(--_k-fg-3)}
626
780
  @media(prefers-reduced-motion:reduce){.knobs-picker :where(*,::before,::after){transition-duration:.15s!important;scale:none!important;filter:none!important}}
627
781
  `;
628
782
  });
@@ -633,25 +787,25 @@ var readoutCss = `
633
787
  :where(.knobs-ui) :is(.knobs-rd-chip,.knobs-rd-copy,.knobs-rd-jump,.knobs-rd-find,.knobs-rd-match){all:revert;box-sizing:border-box;
634
788
  font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;border-radius:0;margin:0;padding:0;min-width:0;box-shadow:none;outline:none}
635
789
  .knobs-ui.knobs-rd,.knobs-rd *{box-sizing:border-box}
636
- .knobs-ui.knobs-rd{display:flex;align-items:center;gap:8px;min-width:0;color:var(--ku-text);letter-spacing:normal}
637
- .knobs-rd .knobs-rd-v{font:var(--ku-font-weight) var(--ku-value-size)/1.25 var(--ku-value-font);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap}
638
- .knobs-rd .knobs-rd-mono{font:400 var(--ku-text-meta)/1.25 var(--ku-mono);font-variant-numeric:tabular-nums;white-space:pre}
639
- .knobs-rd .knobs-rd-meta{font:var(--ku-font-weight) var(--ku-text-meta)/1.25 var(--ku-font);white-space:nowrap}
790
+ .knobs-ui.knobs-rd{display:flex;align-items:center;gap:8px;min-width:0;color:var(--_k-fg);letter-spacing:normal}
791
+ .knobs-rd .knobs-rd-v{font:var(--_k-weight) var(--_k-value-size)/1.25 var(--_k-value-font);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap}
792
+ .knobs-rd .knobs-rd-mono{font:400 var(--_k-text-meta)/1.25 var(--_k-mono);font-variant-numeric:tabular-nums;white-space:pre}
793
+ .knobs-rd .knobs-rd-meta{font:var(--_k-weight) var(--_k-text-meta)/1.25 var(--_k-font);white-space:nowrap}
640
794
  .knobs-rd .knobs-rd-value{display:inline-flex;justify-content:flex-end;align-items:baseline;flex:none;margin-left:auto;contain:layout paint style}
641
- .knobs-rd .knobs-rd-num{color:var(--ku-text);text-align:right;transition:color .15s}
642
- .knobs-rd .knobs-rd-unit{margin-left:var(--k-unit-gap,.28em);color:var(--ku-dim)}
795
+ .knobs-rd .knobs-rd-num{color:var(--_k-fg);text-align:right;transition:color .15s}
796
+ .knobs-rd .knobs-rd-unit{margin-left:var(--k-unit-gap,.28em);color:var(--_k-fg-3)}
643
797
  .knobs-rd .knobs-rd-unit[hidden]{display:none}
644
798
  .knobs-rd.knobs-rd-watch{flex:1 1 auto;justify-content:flex-end}
645
799
  .knobs-rd.knobs-rd-spark,.knobs-rd.knobs-rd-meter{flex:0 1 64%;margin-left:auto}
646
- .knobs-rd .knobs-rd-plot{display:block;flex:1 1 0;min-width:24px;height:max(12px,calc(var(--ku-control-h) - 2px))}
800
+ .knobs-rd .knobs-rd-plot{display:block;flex:1 1 0;min-width:24px;height:max(12px,calc(var(--_k-control-h) - 2px))}
647
801
  .knobs-rd.knobs-rd-meter>.knobs-rd-plot{height:8px}
648
- .knobs-rd.knobs-rd-spark[data-hover] .knobs-rd-num{color:var(--ku-label)}
649
- .knobs-rd .knobs-rd-cap,.knobs-rd .knobs-rd-head>span:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ku-label);font-weight:var(--ku-label-weight)}
802
+ .knobs-rd.knobs-rd-spark[data-hover] .knobs-rd-num{color:var(--_k-fg-2)}
803
+ .knobs-rd .knobs-rd-cap,.knobs-rd .knobs-rd-head>span:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--_k-fg-2);font-weight:var(--_k-weight-label)}
650
804
 
651
805
  /* Blocks: a head line (the label and what goes with it) over a body. In a panel the row grows to fit. */
652
806
  .knobs-panel .knobs-row.knobs-rd-rowblock{display:block;height:auto}
653
807
  .knobs-rd.knobs-rd-block{display:flex;flex-direction:column;align-items:stretch;gap:2px;width:100%}
654
- .knobs-rd .knobs-rd-head{display:flex;align-items:center;gap:0 10px;min-height:var(--ku-row);min-width:0}
808
+ .knobs-rd .knobs-rd-head{display:flex;align-items:center;gap:0 10px;min-height:var(--_k-row);min-width:0}
655
809
  /* The title keeps its words; the legend or tools beside it give way (see fitHead). */
656
810
  .knobs-rd .knobs-rd-head>span:first-child{flex:0 0 auto;max-width:100%}
657
811
  .knobs-rd .knobs-rd-legend{display:flex;align-items:center;gap:12px;margin-left:auto;min-width:0;overflow:hidden}
@@ -659,16 +813,16 @@ var readoutCss = `
659
813
  .knobs-rd .knobs-rd-tools>.knobs-rd-find{flex:1 1 56px;min-width:56px;max-width:84px}
660
814
  .knobs-rd .knobs-rd-head[data-short] .knobs-rd-legend .knobs-rd-unit{display:none}
661
815
  .knobs-rd .knobs-rd-head[data-wrap]{flex-wrap:wrap;padding-bottom:4px}
662
- .knobs-rd .knobs-rd-head[data-wrap]>span:first-child{display:flex;align-items:center;min-height:var(--ku-row)}
816
+ .knobs-rd .knobs-rd-head[data-wrap]>span:first-child{display:flex;align-items:center;min-height:var(--_k-row)}
663
817
  .knobs-rd .knobs-rd-head[data-wrap]>:is(.knobs-rd-legend,.knobs-rd-tools){flex:1 0 100%;margin-left:0}
664
818
  .knobs-rd .knobs-rd-head[data-wrap]>.knobs-rd-tools{flex-wrap:wrap;row-gap:4px}
665
819
  .knobs-rd .knobs-rd-key{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
666
820
  .knobs-rd .knobs-rd-swatch{flex:none;width:8px;height:2px;border-radius:1px}
667
- .knobs-rd .knobs-rd-name{color:var(--ku-label)}
821
+ .knobs-rd .knobs-rd-name{color:var(--_k-fg-2)}
668
822
  .knobs-rd .knobs-rd-key>.knobs-rd-value{margin-left:2px}
669
823
  .knobs-rd .knobs-rd-plotbox{position:relative;outline:none;margin-bottom:6px}
670
824
  .knobs-rd .knobs-rd-plotbox>.knobs-rd-plot{position:absolute;inset:0;width:100%;height:100%;min-width:0}
671
- .knobs-rd .knobs-rd-tick,.knobs-rd .knobs-rd-mark{position:absolute;color:var(--ku-dim);pointer-events:none;line-height:14px;height:14px}
825
+ .knobs-rd .knobs-rd-tick,.knobs-rd .knobs-rd-mark{position:absolute;color:var(--_k-fg-3);pointer-events:none;line-height:14px;height:14px}
672
826
  .knobs-rd .knobs-rd-tick{left:0}
673
827
  .knobs-rd .knobs-rd-tick[data-at="top"]{top:-2px}
674
828
  .knobs-rd .knobs-rd-tick[data-at="bottom"]{bottom:0}
@@ -677,36 +831,36 @@ var readoutCss = `
677
831
 
678
832
  .knobs-rd .knobs-rd-grid{display:grid;column-gap:14px;align-items:center;outline:none;margin-bottom:4px}
679
833
  .knobs-rd .knobs-rd-tr{display:contents}
680
- .knobs-rd .knobs-rd-tr>*{height:calc(var(--ku-row) * .72);line-height:calc(var(--ku-row) * .72);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
681
- .knobs-rd .knobs-rd-thead>*{height:var(--ku-row);line-height:var(--ku-row)}
682
- .knobs-rd .knobs-rd-th{color:var(--ku-dim);text-align:right}
683
- .knobs-rd .knobs-rd-td{color:var(--ku-text)}
684
- .knobs-rd .knobs-rd-td:first-child{color:var(--ku-label)}
834
+ .knobs-rd .knobs-rd-tr>*{height:calc(var(--_k-row) * .72);line-height:calc(var(--_k-row) * .72);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
835
+ .knobs-rd .knobs-rd-thead>*{height:var(--_k-row);line-height:var(--_k-row)}
836
+ .knobs-rd .knobs-rd-th{color:var(--_k-fg-3);text-align:right}
837
+ .knobs-rd .knobs-rd-td{color:var(--_k-fg)}
838
+ .knobs-rd .knobs-rd-td:first-child{color:var(--_k-fg-2)}
685
839
  .knobs-rd .knobs-rd-td[data-num]{text-align:right}
686
840
 
687
841
  .knobs-rd.knobs-rd-log{--rd-lh:18px}
688
842
  .knobs-rd .knobs-rd-chips{display:inline-flex;align-items:center;gap:2px;margin-right:auto}
689
- .knobs-ui .knobs-rd-chip,.knobs-ui .knobs-rd-copy{height:calc(var(--ku-control-h) - 2px);padding:0 7px;border-radius:min(var(--ku-radius),5px);color:var(--ku-label);cursor:pointer;transition:background .15s,color .15s}
690
- .knobs-ui .knobs-rd-chip:hover,.knobs-ui .knobs-rd-copy:hover{background:var(--ku-wash);color:var(--ku-text)}
691
- .knobs-ui .knobs-rd-chip[aria-checked="true"]{background:var(--ku-wash-hi);color:var(--ku-text)}
692
- .knobs-ui .knobs-rd-find{width:84px;height:calc(var(--ku-control-h) - 2px);padding:0 7px;border-radius:min(var(--ku-radius),5px);
693
- background:color-mix(in srgb,var(--ku-surface-hi) 60%,transparent);color:var(--ku-text);caret-color:var(--ku-accent)}
694
- .knobs-rd .knobs-rd-find::placeholder{color:var(--ku-dim)}
843
+ .knobs-ui .knobs-rd-chip,.knobs-ui .knobs-rd-copy{height:calc(var(--_k-control-h) - 2px);padding:0 7px;border-radius:min(var(--_k-radius),5px);color:var(--_k-fg-2);cursor:pointer;transition:background .15s,color .15s}
844
+ .knobs-ui .knobs-rd-chip:hover,.knobs-ui .knobs-rd-copy:hover{background:var(--_ku-wash);color:var(--_k-fg)}
845
+ .knobs-ui .knobs-rd-chip[aria-checked="true"]{background:var(--_ku-wash-hi);color:var(--_k-fg)}
846
+ .knobs-ui .knobs-rd-find{width:84px;height:calc(var(--_k-control-h) - 2px);padding:0 7px;border-radius:min(var(--_k-radius),5px);
847
+ background:color-mix(in srgb,var(--_k-fill-selected) 60%,transparent);color:var(--_k-fg);caret-color:var(--_k-accent)}
848
+ .knobs-rd .knobs-rd-find::placeholder{color:var(--_k-fg-3)}
695
849
  .knobs-rd .knobs-rd-find::-webkit-search-cancel-button{display:none}
696
850
  .knobs-rd .knobs-rd-logbody{position:relative;margin-bottom:6px}
697
851
  .knobs-rd .knobs-rd-scroll{position:relative;overflow-x:hidden;overflow-y:auto;height:calc(var(--knobs-rd-lines,8) * var(--rd-lh));outline:none;
698
- background:color-mix(in srgb,var(--ku-surface-hi) 45%,transparent);border-radius:min(var(--ku-radius),6px);scrollbar-width:thin;overscroll-behavior:contain}
852
+ background:color-mix(in srgb,var(--_k-fill-selected) 45%,transparent);border-radius:min(var(--_k-radius),6px);scrollbar-width:thin;overscroll-behavior:contain}
699
853
  .knobs-rd .knobs-rd-space{position:relative;width:100%}
700
854
  .knobs-rd .knobs-rd-line{position:absolute;left:0;right:0;top:0;display:flex;gap:10px;height:var(--rd-lh);line-height:var(--rd-lh);padding:0 8px;contain:layout style;will-change:transform}
701
855
  .knobs-rd .knobs-rd-line[hidden]{display:none}
702
- .knobs-rd .knobs-rd-time{flex:none;color:var(--ku-dim)}
703
- .knobs-rd .knobs-rd-text{min-width:0;overflow:hidden;text-overflow:ellipsis;color:var(--ku-text)}
704
- .knobs-rd .knobs-rd-line[data-level="warn"]>.knobs-rd-text{color:var(--ku-warn)}
705
- .knobs-rd .knobs-rd-line[data-level="error"]>.knobs-rd-text{color:var(--ku-critical)}
706
- .knobs-rd .knobs-rd-line[data-level="debug"]>.knobs-rd-text{color:var(--ku-dim)}
707
- .knobs-ui .knobs-rd-match{color:var(--ku-accent)}
708
- .knobs-ui .knobs-rd-jump{position:absolute;left:50%;bottom:6px;height:20px;padding:0 10px;border-radius:calc(var(--ku-radius) * 999);
709
- background:var(--ku-accent);color:var(--ku-bg);opacity:0;transform:translate(-50%,6px);cursor:pointer;white-space:nowrap}
856
+ .knobs-rd .knobs-rd-time{flex:none;color:var(--_k-fg-3)}
857
+ .knobs-rd .knobs-rd-text{min-width:0;overflow:hidden;text-overflow:ellipsis;color:var(--_k-fg)}
858
+ .knobs-rd .knobs-rd-line[data-level="warn"]>.knobs-rd-text{color:var(--_k-warn)}
859
+ .knobs-rd .knobs-rd-line[data-level="error"]>.knobs-rd-text{color:var(--_k-danger)}
860
+ .knobs-rd .knobs-rd-line[data-level="debug"]>.knobs-rd-text{color:var(--_k-fg-3)}
861
+ .knobs-ui .knobs-rd-match{color:var(--_k-accent)}
862
+ .knobs-ui .knobs-rd-jump{position:absolute;left:50%;bottom:6px;height:20px;padding:0 10px;border-radius:calc(var(--_k-radius) * 999);
863
+ background:var(--_k-accent);color:var(--_k-bg);opacity:0;transform:translate(-50%,6px);cursor:pointer;white-space:nowrap}
710
864
 
711
865
  /* Under the GPU overlay the readouts' DOM stays for focus, hit-testing and screen readers; the
712
866
  overlay draws them. Their filter field sits above it. */
@@ -716,6 +870,1515 @@ var readoutCss = `
716
870
  @media(prefers-reduced-motion:reduce){.knobs-rd :where(*){transition:none!important}}
717
871
  `;
718
872
 
873
+ // src/tokens/color.ts
874
+ function linearToOklch([r, g, b, a]) {
875
+ const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
876
+ const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
877
+ const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
878
+ const L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s;
879
+ const A = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;
880
+ const B = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;
881
+ const c = Math.hypot(A, B);
882
+ const h = c < 0.0000001 ? 0 : (Math.atan2(B, A) * 180 / Math.PI + 360) % 360;
883
+ return { l: L, c, h, alpha: a };
884
+ }
885
+ function oklchToLinear({ l: L, c, h, alpha = 1 }) {
886
+ const hr = h * Math.PI / 180;
887
+ const A = c * Math.cos(hr);
888
+ const B = c * Math.sin(hr);
889
+ const l = (L + 0.3963377774 * A + 0.2158037573 * B) ** 3;
890
+ const m = (L - 0.1055613458 * A - 0.0638541728 * B) ** 3;
891
+ const s = (L - 0.0894841775 * A - 1.291485548 * B) ** 3;
892
+ return [
893
+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
894
+ -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
895
+ -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,
896
+ alpha
897
+ ];
898
+ }
899
+ function oklchToLinearInGamut(color) {
900
+ let rgb = oklchToLinear(color);
901
+ if (inGamut(rgb))
902
+ return clampRgba(rgb);
903
+ let lo = 0;
904
+ let hi = color.c;
905
+ for (let i = 0;i < 24; i++) {
906
+ const mid = (lo + hi) / 2;
907
+ rgb = oklchToLinear({ ...color, c: mid });
908
+ if (inGamut(rgb))
909
+ lo = mid;
910
+ else
911
+ hi = mid;
912
+ }
913
+ return clampRgba(oklchToLinear({ ...color, c: lo }));
914
+ }
915
+ function parseColor(input) {
916
+ const s = input.trim().toLowerCase();
917
+ if (s === "transparent")
918
+ return [0, 0, 0, 0];
919
+ if (s.startsWith("#")) {
920
+ let hex = s.slice(1);
921
+ if (hex.length === 3 || hex.length === 4)
922
+ hex = [...hex].map((ch) => ch + ch).join("");
923
+ if (!/^[0-9a-f]{6}([0-9a-f]{2})?$/.test(hex))
924
+ throw new Error(`Invalid colour: ${input}`);
925
+ const n = (i) => Number.parseInt(hex.slice(i, i + 2), 16) / 255;
926
+ return [toLinear(n(0)), toLinear(n(2)), toLinear(n(4)), hex.length === 8 ? n(6) : 1];
927
+ }
928
+ const fn = /^(oklch|rgba?)\(([^)]*)\)$/.exec(s);
929
+ if (!fn)
930
+ throw new Error(`Unsupported colour: ${input}`);
931
+ const parts = fn[2].split(/[\s,/]+/).filter(Boolean);
932
+ const num = (p, scale) => p === undefined ? 1 : p.endsWith("%") ? Number.parseFloat(p) / 100 : Number.parseFloat(p) / scale;
933
+ if (fn[1] === "oklch") {
934
+ const l = num(parts[0], 1);
935
+ return oklchToLinearInGamut({
936
+ l,
937
+ c: Number.parseFloat(parts[1]),
938
+ h: Number.parseFloat(parts[2]),
939
+ alpha: num(parts[3], 1)
940
+ });
941
+ }
942
+ return [
943
+ toLinear(num(parts[0], 255)),
944
+ toLinear(num(parts[1], 255)),
945
+ toLinear(num(parts[2], 255)),
946
+ num(parts[3], 1)
947
+ ];
948
+ }
949
+ function formatHex([r, g, b, a]) {
950
+ const rgb = `#${byte(toGamma(r))}${byte(toGamma(g))}${byte(toGamma(b))}`;
951
+ return a >= 0.9995 ? rgb : rgb + byte(a);
952
+ }
953
+ function withAlpha(input, alpha) {
954
+ const [r, g, b, a] = parseColor(input);
955
+ return formatHex([r, g, b, a * alpha]);
956
+ }
957
+ function over(top, bottom) {
958
+ const t = parseColor(top);
959
+ const b = parseColor(bottom);
960
+ const a = t[3];
961
+ const mix = (i) => toLinear(toGamma(t[i]) * a + toGamma(b[i]) * (1 - a));
962
+ return formatHex([mix(0), mix(1), mix(2), 1]);
963
+ }
964
+ function apcaY(input) {
965
+ const [r, g, b] = parseColor(input).map(toGamma);
966
+ return 0.2126729 * r ** 2.4 + 0.7151522 * g ** 2.4 + 0.072175 * b ** 2.4;
967
+ }
968
+ function apca(text, background) {
969
+ const bgOpaque = parseColor(background)[3] < 1 ? over(background, "#000") : background;
970
+ const fg = parseColor(text)[3] < 1 ? over(text, bgOpaque) : text;
971
+ const soft = (y) => y > 0.022 ? y : y + (0.022 - y) ** 1.414;
972
+ const yt = soft(apcaY(fg));
973
+ const yb = soft(apcaY(bgOpaque));
974
+ if (Math.abs(yb - yt) < 0.0005)
975
+ return 0;
976
+ if (yb > yt) {
977
+ const sapc = (yb ** 0.56 - yt ** 0.57) * 1.14;
978
+ return sapc < 0.1 ? 0 : (sapc - 0.027) * 100;
979
+ }
980
+ const sapc = (yb ** 0.65 - yt ** 0.62) * 1.14;
981
+ return sapc > -0.1 ? 0 : -(sapc + 0.027) * 100;
982
+ }
983
+ 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 ** (1 / 2.4) - 0.055, inGamut = ([r, g, b]) => [r, g, b].every((x) => x >= -0.00001 && x <= 1 + 0.00001), clampRgba = ([r, g, b, a]) => [clamp01(r), clamp01(g), clamp01(b), clamp01(a)], toOklch = (input) => linearToOklch(parseColor(input)), byte = (c) => Math.round(clamp01(c) * 255).toString(16).padStart(2, "0"), oklchToHex = (color) => formatHex(oklchToLinearInGamut(color)), normalize = (input) => formatHex(parseColor(input));
984
+
985
+ // src/tokens/schema.ts
986
+ var 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, TOKEN_BY_NAME, cssName = (t) => `${t.tier === "private" ? "--_k-" : "--k-"}${t.name}`, PROPERTY_TO_NAME, tokenForProperty = (property) => PROPERTY_TO_NAME.get(property), DEPRECATED;
987
+ var init_schema = __esm(() => {
988
+ theme = { from: "theme" };
989
+ TOKENS = [
990
+ {
991
+ name: "accent",
992
+ tier: "input",
993
+ type: "color",
994
+ group: "Accent",
995
+ source: theme,
996
+ doc: "The one accent: primary actions, handles, focus. Hover, soft and selection derive from it in CSS.",
997
+ deprecated: ["--ku-accent"]
998
+ },
999
+ {
1000
+ name: "contrast",
1001
+ tier: "input",
1002
+ type: "number",
1003
+ group: "Inputs",
1004
+ source: theme,
1005
+ doc: "Contrast multiplier for fills and alpha borders (1 = default; the theme's 0–100 dial maps 50 → 1)."
1006
+ },
1007
+ {
1008
+ name: "radius",
1009
+ tier: "input",
1010
+ type: "length",
1011
+ group: "Shape",
1012
+ source: theme,
1013
+ doc: "Control corner radius. 0 squares everything, including capsules. Scales with density.",
1014
+ deprecated: ["--ku-radius"],
1015
+ resolve: "round(calc($ * (1 + (var(--_k-density) - 1) * 1.5)),2px)"
1016
+ },
1017
+ {
1018
+ name: "density",
1019
+ tier: "input",
1020
+ type: "number",
1021
+ group: "Size",
1022
+ source: theme,
1023
+ doc: "Size multiplier: compact .875, default 1, comfortable 1.1875."
1024
+ },
1025
+ {
1026
+ name: "font",
1027
+ tier: "input",
1028
+ type: "font",
1029
+ group: "Type",
1030
+ source: theme,
1031
+ doc: "UI font stack.",
1032
+ deprecated: ["--ku-font"]
1033
+ },
1034
+ {
1035
+ name: "mono",
1036
+ tier: "input",
1037
+ type: "font",
1038
+ group: "Type",
1039
+ source: theme,
1040
+ doc: "Monospace font stack.",
1041
+ deprecated: ["--ku-mono"]
1042
+ },
1043
+ {
1044
+ name: "bg-page",
1045
+ tier: "semantic",
1046
+ type: "color",
1047
+ group: "Surfaces",
1048
+ source: theme,
1049
+ doc: "The page behind panels; workspace backdrops.",
1050
+ deprecated: ["--k-page", "--ku-page"]
1051
+ },
1052
+ {
1053
+ name: "bg-inset",
1054
+ tier: "semantic",
1055
+ type: "color",
1056
+ group: "Surfaces",
1057
+ source: theme,
1058
+ doc: "Wells sunk into a panel: tracks, inputs, segmented backgrounds."
1059
+ },
1060
+ {
1061
+ name: "bg",
1062
+ tier: "semantic",
1063
+ type: "color",
1064
+ group: "Surfaces",
1065
+ source: theme,
1066
+ doc: "The panel surface.",
1067
+ deprecated: ["--ku-bg"]
1068
+ },
1069
+ {
1070
+ name: "bg-raised",
1071
+ tier: "semantic",
1072
+ type: "color",
1073
+ group: "Surfaces",
1074
+ source: theme,
1075
+ doc: "Raised within a panel: the active segment, cards on a panel."
1076
+ },
1077
+ {
1078
+ name: "bg-overlay",
1079
+ tier: "semantic",
1080
+ type: "color",
1081
+ group: "Surfaces",
1082
+ source: theme,
1083
+ doc: "Floating surfaces: menus, popovers, tooltips."
1084
+ },
1085
+ {
1086
+ name: "fill",
1087
+ tier: "semantic",
1088
+ type: "color",
1089
+ group: "Fills",
1090
+ source: css(alpha(5.5)),
1091
+ doc: "Resting fill for controls.",
1092
+ deprecated: ["--k-surface", "--ku-surface"]
1093
+ },
1094
+ {
1095
+ name: "fill-hover",
1096
+ tier: "semantic",
1097
+ type: "color",
1098
+ group: "Fills",
1099
+ source: css(alpha(8)),
1100
+ doc: "Hovered fill."
1101
+ },
1102
+ {
1103
+ name: "fill-selected",
1104
+ tier: "semantic",
1105
+ type: "color",
1106
+ group: "Fills",
1107
+ source: css(alpha(11)),
1108
+ doc: "Pressed or selected fill.",
1109
+ deprecated: ["--k-surface-hi", "--ku-surface-hi"]
1110
+ },
1111
+ {
1112
+ name: "fg",
1113
+ tier: "semantic",
1114
+ type: "color",
1115
+ group: "Foreground",
1116
+ source: theme,
1117
+ doc: "Primary text and icons (≥ Lc 90 on bg).",
1118
+ deprecated: ["--k-text", "--ku-text"]
1119
+ },
1120
+ {
1121
+ name: "fg-2",
1122
+ tier: "semantic",
1123
+ type: "color",
1124
+ group: "Foreground",
1125
+ source: theme,
1126
+ doc: "Secondary text: labels (≥ Lc 75).",
1127
+ deprecated: ["--k-label", "--ku-label"]
1128
+ },
1129
+ {
1130
+ name: "fg-3",
1131
+ tier: "semantic",
1132
+ type: "color",
1133
+ group: "Foreground",
1134
+ source: theme,
1135
+ doc: "Tertiary text: metadata, units, captions (≥ Lc 45).",
1136
+ deprecated: ["--k-dim", "--ku-dim"]
1137
+ },
1138
+ {
1139
+ name: "fg-4",
1140
+ tier: "semantic",
1141
+ type: "color",
1142
+ group: "Foreground",
1143
+ source: theme,
1144
+ doc: "Placeholder and disabled text (≥ Lc 30)."
1145
+ },
1146
+ {
1147
+ name: "border-subtle",
1148
+ tier: "semantic",
1149
+ type: "color",
1150
+ group: "Borders",
1151
+ source: css(alpha(6)),
1152
+ doc: "Hairline edges and dividers (below Lc 15 by design).",
1153
+ deprecated: ["--k-edge"]
1154
+ },
1155
+ {
1156
+ name: "border",
1157
+ tier: "semantic",
1158
+ type: "color",
1159
+ group: "Borders",
1160
+ source: css(alpha(10)),
1161
+ doc: "Default borders.",
1162
+ deprecated: ["--k-line", "--ku-line"]
1163
+ },
1164
+ {
1165
+ name: "border-strong",
1166
+ tier: "semantic",
1167
+ type: "color",
1168
+ group: "Borders",
1169
+ source: theme,
1170
+ doc: "Interactive edges (≥ Lc 15; solid).",
1171
+ deprecated: ["--k-line-hi", "--ku-line-hi"]
1172
+ },
1173
+ {
1174
+ name: "accent-hover",
1175
+ tier: "semantic",
1176
+ type: "color",
1177
+ group: "Accent",
1178
+ source: css("color-mix(in oklch,var(--k-accent) 90%,var(--k-bg))"),
1179
+ doc: "Hovered accent."
1180
+ },
1181
+ {
1182
+ name: "accent-soft",
1183
+ tier: "semantic",
1184
+ type: "color",
1185
+ group: "Accent",
1186
+ source: css("color-mix(in oklch,var(--k-accent) 15%,transparent)"),
1187
+ doc: "Accent tint behind accent content."
1188
+ },
1189
+ {
1190
+ name: "accent-fg",
1191
+ tier: "semantic",
1192
+ type: "color",
1193
+ group: "Accent",
1194
+ source: theme,
1195
+ doc: "Accent as text on bg (≥ Lc 60)."
1196
+ },
1197
+ {
1198
+ name: "on-accent",
1199
+ tier: "semantic",
1200
+ type: "color",
1201
+ group: "Accent",
1202
+ source: theme,
1203
+ doc: "Content placed on a solid accent."
1204
+ },
1205
+ { name: "ok", tier: "semantic", type: "color", group: "Status", source: theme, doc: "Success." },
1206
+ {
1207
+ name: "warn",
1208
+ tier: "semantic",
1209
+ type: "color",
1210
+ group: "Status",
1211
+ source: theme,
1212
+ doc: "Warning.",
1213
+ deprecated: ["--ku-warn"]
1214
+ },
1215
+ {
1216
+ name: "danger",
1217
+ tier: "semantic",
1218
+ type: "color",
1219
+ group: "Status",
1220
+ source: theme,
1221
+ doc: "Error, destructive. Put text on danger-soft rather than bare bg.",
1222
+ deprecated: ["--k-critical", "--ku-critical"]
1223
+ },
1224
+ {
1225
+ name: "info",
1226
+ tier: "semantic",
1227
+ type: "color",
1228
+ group: "Status",
1229
+ source: theme,
1230
+ doc: "Informational."
1231
+ },
1232
+ {
1233
+ name: "ok-soft",
1234
+ tier: "semantic",
1235
+ type: "color",
1236
+ group: "Status",
1237
+ source: css("color-mix(in oklch,var(--k-ok) 15%,transparent)"),
1238
+ doc: "Success tint."
1239
+ },
1240
+ {
1241
+ name: "warn-soft",
1242
+ tier: "semantic",
1243
+ type: "color",
1244
+ group: "Status",
1245
+ source: css("color-mix(in oklch,var(--k-warn) 15%,transparent)"),
1246
+ doc: "Warning tint."
1247
+ },
1248
+ {
1249
+ name: "danger-soft",
1250
+ tier: "semantic",
1251
+ type: "color",
1252
+ group: "Status",
1253
+ source: css("color-mix(in oklch,var(--k-danger) 15%,transparent)"),
1254
+ doc: "Danger tint."
1255
+ },
1256
+ {
1257
+ name: "info-soft",
1258
+ tier: "semantic",
1259
+ type: "color",
1260
+ group: "Status",
1261
+ source: css("color-mix(in oklch,var(--k-info) 15%,transparent)"),
1262
+ doc: "Info tint."
1263
+ },
1264
+ {
1265
+ name: "focus",
1266
+ tier: "semantic",
1267
+ type: "color",
1268
+ group: "Interaction",
1269
+ source: css("var(--k-accent)"),
1270
+ doc: "Focus ring colour (drawn as a 2px bg gap, then 2px of focus)."
1271
+ },
1272
+ {
1273
+ name: "selection",
1274
+ tier: "semantic",
1275
+ type: "color",
1276
+ group: "Interaction",
1277
+ source: css("color-mix(in oklch,var(--k-accent) 24%,transparent)"),
1278
+ doc: "Selected rows and ranges.",
1279
+ deprecated: ["--k-ui-select", "--ku-select"]
1280
+ },
1281
+ {
1282
+ name: "scrim",
1283
+ tier: "semantic",
1284
+ type: "color",
1285
+ group: "Interaction",
1286
+ source: theme,
1287
+ doc: "Dimming behind modal layers."
1288
+ },
1289
+ {
1290
+ name: "diff-add",
1291
+ tier: "semantic",
1292
+ type: "color",
1293
+ group: "Data",
1294
+ source: css("var(--k-ok)"),
1295
+ doc: "Added lines; line and word tints derive privately (12% / 38%)."
1296
+ },
1297
+ {
1298
+ name: "diff-del",
1299
+ tier: "semantic",
1300
+ type: "color",
1301
+ group: "Data",
1302
+ source: css("var(--k-danger)"),
1303
+ doc: "Deleted lines."
1304
+ },
1305
+ {
1306
+ name: "diff-mod",
1307
+ tier: "semantic",
1308
+ type: "color",
1309
+ group: "Data",
1310
+ source: css("var(--k-warn)"),
1311
+ doc: "Modified lines."
1312
+ },
1313
+ {
1314
+ name: "series-1",
1315
+ tier: "semantic",
1316
+ type: "color",
1317
+ group: "Data",
1318
+ source: theme,
1319
+ doc: "Chart series 1."
1320
+ },
1321
+ {
1322
+ name: "series-2",
1323
+ tier: "semantic",
1324
+ type: "color",
1325
+ group: "Data",
1326
+ source: theme,
1327
+ doc: "Chart series 2."
1328
+ },
1329
+ {
1330
+ name: "series-3",
1331
+ tier: "semantic",
1332
+ type: "color",
1333
+ group: "Data",
1334
+ source: theme,
1335
+ doc: "Chart series 3."
1336
+ },
1337
+ {
1338
+ name: "series-4",
1339
+ tier: "semantic",
1340
+ type: "color",
1341
+ group: "Data",
1342
+ source: theme,
1343
+ doc: "Chart series 4."
1344
+ },
1345
+ {
1346
+ name: "series-5",
1347
+ tier: "semantic",
1348
+ type: "color",
1349
+ group: "Data",
1350
+ source: theme,
1351
+ doc: "Chart series 5."
1352
+ },
1353
+ {
1354
+ name: "series-6",
1355
+ tier: "semantic",
1356
+ type: "color",
1357
+ group: "Data",
1358
+ source: theme,
1359
+ doc: "Chart series 6."
1360
+ },
1361
+ {
1362
+ name: "radius-panel",
1363
+ tier: "semantic",
1364
+ type: "length",
1365
+ group: "Shape",
1366
+ source: css("calc(var(--k-radius) + var(--k-unit))"),
1367
+ doc: "Panel and card radius, concentric with controls.",
1368
+ deprecated: ["--k-panel-radius", "--ku-panel-radius"]
1369
+ },
1370
+ {
1371
+ name: "round",
1372
+ tier: "semantic",
1373
+ type: "length",
1374
+ group: "Shape",
1375
+ source: css("calc(var(--k-radius) * 999)"),
1376
+ doc: "Capsule radius that squares when --k-radius is 0. Use instead of 999px."
1377
+ },
1378
+ {
1379
+ name: "unit",
1380
+ tier: "semantic",
1381
+ type: "length",
1382
+ group: "Size",
1383
+ source: value("4px"),
1384
+ doc: "The spacing unit."
1385
+ },
1386
+ {
1387
+ name: "row",
1388
+ tier: "semantic",
1389
+ type: "length",
1390
+ group: "Size",
1391
+ source: css("round(calc(32px * var(--k-density)),2px)"),
1392
+ doc: "Row height.",
1393
+ deprecated: ["--ku-row"]
1394
+ },
1395
+ {
1396
+ name: "width",
1397
+ tier: "semantic",
1398
+ type: "length",
1399
+ group: "Size",
1400
+ source: value("288px"),
1401
+ doc: "Panel width."
1402
+ },
1403
+ {
1404
+ name: "font-size",
1405
+ tier: "semantic",
1406
+ type: "length",
1407
+ group: "Type",
1408
+ source: css("round(calc(12px * (1 + (var(--k-density) - 1) * .5)),1px)"),
1409
+ doc: "Body size; a 5-step scale derives privately.",
1410
+ deprecated: ["--ku-font-size"]
1411
+ },
1412
+ {
1413
+ name: "value-font",
1414
+ tier: "semantic",
1415
+ type: "font",
1416
+ group: "Type",
1417
+ source: css("var(--k-font)"),
1418
+ doc: "Font for readouts and values (labPreset: mono).",
1419
+ deprecated: ["--ku-value-font"]
1420
+ },
1421
+ {
1422
+ name: "shadow-raised",
1423
+ tier: "semantic",
1424
+ type: "shadow",
1425
+ group: "Material",
1426
+ source: theme,
1427
+ doc: "Small lift for raised controls.",
1428
+ deprecated: ["--k-lift-shadow"]
1429
+ },
1430
+ {
1431
+ name: "shadow-overlay",
1432
+ tier: "semantic",
1433
+ type: "shadow",
1434
+ group: "Material",
1435
+ source: theme,
1436
+ doc: "Floating panels, menus, popovers.",
1437
+ deprecated: ["--k-shadow", "--ku-shadow"]
1438
+ },
1439
+ {
1440
+ name: "glass",
1441
+ tier: "semantic",
1442
+ type: "number",
1443
+ group: "Material",
1444
+ source: theme,
1445
+ doc: "Backdrop glass amount (0 = opaque)."
1446
+ },
1447
+ {
1448
+ name: "glow",
1449
+ tier: "semantic",
1450
+ type: "number",
1451
+ group: "Material",
1452
+ source: theme,
1453
+ doc: "Specular glow amount."
1454
+ },
1455
+ {
1456
+ name: "rim",
1457
+ tier: "semantic",
1458
+ type: "color",
1459
+ group: "Material",
1460
+ source: theme,
1461
+ doc: "Top-edge highlight hairline.",
1462
+ deprecated: ["--ku-rim"]
1463
+ },
1464
+ {
1465
+ name: "spring",
1466
+ tier: "semantic",
1467
+ type: "spring",
1468
+ group: "Motion",
1469
+ source: value("0.3 0"),
1470
+ doc: "Default spring as `duration bounce` (the motion module's `default`)."
1471
+ },
1472
+ {
1473
+ name: "hover-in",
1474
+ tier: "semantic",
1475
+ type: "number",
1476
+ group: "Motion",
1477
+ source: value("0"),
1478
+ doc: "Hover wash fade-in, unitless milliseconds.",
1479
+ deprecated: ["--ku-hover-in"]
1480
+ },
1481
+ {
1482
+ name: "hover-out",
1483
+ tier: "semantic",
1484
+ type: "number",
1485
+ group: "Motion",
1486
+ source: value("120"),
1487
+ doc: "Hover wash fade-out, unitless milliseconds.",
1488
+ deprecated: ["--ku-hover-out"]
1489
+ },
1490
+ {
1491
+ name: "z",
1492
+ tier: "semantic",
1493
+ type: "integer",
1494
+ group: "Motion",
1495
+ source: value("2147480000"),
1496
+ doc: "Base of knobs' stacking ladder; layers add small offsets."
1497
+ },
1498
+ {
1499
+ name: "slider-track",
1500
+ tier: "hook",
1501
+ type: "color",
1502
+ group: "Hooks",
1503
+ source: css("var(--k-fill)"),
1504
+ doc: "Slider track."
1505
+ },
1506
+ {
1507
+ name: "slider-fill",
1508
+ tier: "hook",
1509
+ type: "color",
1510
+ group: "Hooks",
1511
+ source: css("color-mix(in oklch,var(--k-accent) 20%,var(--k-fill-selected))"),
1512
+ doc: "Slider value fill.",
1513
+ deprecated: ["--k-fill-rest"]
1514
+ },
1515
+ {
1516
+ name: "slider-handle",
1517
+ tier: "hook",
1518
+ type: "color",
1519
+ group: "Hooks",
1520
+ source: css("var(--k-accent)"),
1521
+ doc: "Slider handle and range thumbs.",
1522
+ deprecated: ["--k-handle"]
1523
+ },
1524
+ {
1525
+ name: "toggle-thumb-off",
1526
+ tier: "hook",
1527
+ type: "color",
1528
+ group: "Hooks",
1529
+ source: css("#ffffff"),
1530
+ doc: "A switch's thumb while off, and the ring around colour and gradient thumbs.",
1531
+ deprecated: ["--k-thumb"]
1532
+ },
1533
+ {
1534
+ name: "toggle-track",
1535
+ tier: "hook",
1536
+ type: "color",
1537
+ group: "Hooks",
1538
+ source: css("var(--k-fill-selected)"),
1539
+ doc: "Toggle track, off."
1540
+ },
1541
+ {
1542
+ name: "toggle-track-on",
1543
+ tier: "hook",
1544
+ type: "color",
1545
+ group: "Hooks",
1546
+ source: css("var(--k-accent)"),
1547
+ doc: "Toggle track, on."
1548
+ },
1549
+ {
1550
+ name: "toggle-thumb",
1551
+ tier: "hook",
1552
+ type: "color",
1553
+ group: "Hooks",
1554
+ source: css("var(--k-on-accent)"),
1555
+ doc: "Toggle thumb."
1556
+ },
1557
+ {
1558
+ name: "segmented-track",
1559
+ tier: "hook",
1560
+ type: "color",
1561
+ group: "Hooks",
1562
+ source: css("var(--k-bg-inset)"),
1563
+ doc: "Segmented control background.",
1564
+ deprecated: ["--k-seg-bg", "--ku-seg-bg"]
1565
+ },
1566
+ {
1567
+ name: "segmented-active",
1568
+ tier: "hook",
1569
+ type: "color",
1570
+ group: "Hooks",
1571
+ source: css("var(--k-bg-raised)"),
1572
+ doc: "Active segment.",
1573
+ deprecated: ["--k-seg-active"]
1574
+ },
1575
+ {
1576
+ name: "timeline-playhead",
1577
+ tier: "hook",
1578
+ type: "color",
1579
+ group: "Hooks",
1580
+ source: css("var(--k-accent)"),
1581
+ doc: "Timeline playhead."
1582
+ },
1583
+ {
1584
+ name: "split-gutter",
1585
+ tier: "hook",
1586
+ type: "color",
1587
+ group: "Hooks",
1588
+ source: css("var(--k-border-subtle)"),
1589
+ doc: "Split pane divider.",
1590
+ deprecated: ["--k-ui-divider", "--ku-divider"]
1591
+ },
1592
+ {
1593
+ name: "compare-divider",
1594
+ tier: "hook",
1595
+ type: "color",
1596
+ group: "Hooks",
1597
+ source: css("var(--k-fg)"),
1598
+ doc: "Before/after divider line.",
1599
+ deprecated: ["--k-compare-line"]
1600
+ },
1601
+ {
1602
+ name: "compare-stage",
1603
+ tier: "hook",
1604
+ type: "color",
1605
+ group: "Hooks",
1606
+ source: css("var(--k-fill)"),
1607
+ doc: "Compare stage background."
1608
+ },
1609
+ {
1610
+ name: "activity-rail",
1611
+ tier: "hook",
1612
+ type: "color",
1613
+ group: "Hooks",
1614
+ source: css("var(--k-border-strong)"),
1615
+ doc: "Activity rail line.",
1616
+ deprecated: ["--k-activity-line"]
1617
+ },
1618
+ {
1619
+ name: "picker-card",
1620
+ tier: "hook",
1621
+ type: "color",
1622
+ group: "Hooks",
1623
+ source: css("var(--k-fill)"),
1624
+ doc: "Picker card."
1625
+ },
1626
+ {
1627
+ name: "pane-bg",
1628
+ tier: "hook",
1629
+ type: "color",
1630
+ group: "Hooks",
1631
+ source: css("var(--k-bg)"),
1632
+ doc: "knobs/ui pane card.",
1633
+ deprecated: ["--k-ui-pane", "--ku-pane-bg"]
1634
+ },
1635
+ {
1636
+ name: "button-bg",
1637
+ tier: "hook",
1638
+ type: "color",
1639
+ group: "Hooks",
1640
+ source: css("var(--k-fill)"),
1641
+ doc: "Button fill."
1642
+ },
1643
+ {
1644
+ name: "button-border",
1645
+ tier: "hook",
1646
+ type: "color",
1647
+ group: "Hooks",
1648
+ source: css("transparent"),
1649
+ doc: "Button border.",
1650
+ deprecated: ["--k-button-line"]
1651
+ },
1652
+ {
1653
+ name: "button-fg",
1654
+ tier: "hook",
1655
+ type: "color",
1656
+ group: "Hooks",
1657
+ source: css("var(--k-fg)"),
1658
+ doc: "Button text.",
1659
+ deprecated: ["--k-button-color"]
1660
+ },
1661
+ {
1662
+ name: "row-hover",
1663
+ tier: "hook",
1664
+ type: "color",
1665
+ group: "Hooks",
1666
+ source: css("color-mix(in oklch,var(--k-fill) 50%,transparent)"),
1667
+ doc: "Row hover wash."
1668
+ },
1669
+ {
1670
+ name: "group-label",
1671
+ tier: "hook",
1672
+ type: "color",
1673
+ group: "Hooks",
1674
+ source: css("var(--k-fg-3)"),
1675
+ doc: "Folder and group headings.",
1676
+ deprecated: ["--k-group-ink", "--k-group-color"]
1677
+ },
1678
+ {
1679
+ name: "modified",
1680
+ tier: "hook",
1681
+ type: "color",
1682
+ group: "Hooks",
1683
+ source: css("var(--k-fg-3)"),
1684
+ doc: "Marker for values changed from their default."
1685
+ },
1686
+ {
1687
+ name: "tray-pad",
1688
+ tier: "private",
1689
+ type: "length",
1690
+ group: "Private",
1691
+ source: css("calc(var(--k-unit) * .5)"),
1692
+ doc: "Padding inside a tray around its controls.",
1693
+ deprecated: ["--k-tray-pad"]
1694
+ },
1695
+ {
1696
+ name: "pad",
1697
+ tier: "private",
1698
+ type: "length",
1699
+ group: "Private",
1700
+ source: css("round(calc(10px * var(--k-density)),2px)"),
1701
+ doc: "Panel padding.",
1702
+ deprecated: ["--k-pad"]
1703
+ },
1704
+ {
1705
+ name: "inset",
1706
+ tier: "private",
1707
+ type: "length",
1708
+ group: "Private",
1709
+ source: css("var(--_k-pad)"),
1710
+ doc: "Row content inset.",
1711
+ deprecated: ["--k-inset", "--ku-inset"]
1712
+ },
1713
+ {
1714
+ name: "gap",
1715
+ tier: "private",
1716
+ type: "length",
1717
+ group: "Private",
1718
+ source: css("round(calc(var(--k-unit) * (1 + (var(--k-density) - 1) * 2.5)),1px)"),
1719
+ doc: "Gap between rows.",
1720
+ deprecated: ["--k-gap"]
1721
+ },
1722
+ {
1723
+ name: "radius-md",
1724
+ tier: "private",
1725
+ type: "length",
1726
+ group: "Private",
1727
+ source: css("max(0px,calc(var(--k-radius) - var(--_k-tray-pad)))"),
1728
+ doc: "Concentric radius one tray in.",
1729
+ deprecated: ["--k-radius-md"]
1730
+ },
1731
+ {
1732
+ name: "radius-sm",
1733
+ tier: "private",
1734
+ type: "length",
1735
+ group: "Private",
1736
+ source: css("max(0px,calc(var(--k-radius) - var(--_k-tray-pad) * 2))"),
1737
+ doc: "Concentric radius two trays in.",
1738
+ deprecated: ["--k-radius-sm"]
1739
+ },
1740
+ {
1741
+ name: "control-h",
1742
+ tier: "private",
1743
+ type: "length",
1744
+ group: "Private",
1745
+ source: css("calc(var(--k-row) - var(--k-unit) * 2)"),
1746
+ doc: "Control height inside a row.",
1747
+ deprecated: ["--k-control-h", "--ku-control-h"]
1748
+ },
1749
+ {
1750
+ name: "value-size",
1751
+ tier: "private",
1752
+ type: "length",
1753
+ group: "Private",
1754
+ source: css("calc(var(--k-font-size) - .5px)"),
1755
+ doc: "Readout size.",
1756
+ deprecated: ["--k-value-size", "--ku-value-size"]
1757
+ },
1758
+ {
1759
+ name: "text-title",
1760
+ tier: "private",
1761
+ type: "length",
1762
+ group: "Private",
1763
+ source: css("calc(var(--k-font-size) + 1px)"),
1764
+ doc: "Type scale: titles.",
1765
+ deprecated: ["--k-text-title"]
1766
+ },
1767
+ {
1768
+ name: "text-body",
1769
+ tier: "private",
1770
+ type: "length",
1771
+ group: "Private",
1772
+ source: css("var(--k-font-size)"),
1773
+ doc: "Type scale: body.",
1774
+ deprecated: ["--k-text-body"]
1775
+ },
1776
+ {
1777
+ name: "text-control",
1778
+ tier: "private",
1779
+ type: "length",
1780
+ group: "Private",
1781
+ source: css("calc(var(--k-font-size) - .5px)"),
1782
+ doc: "Type scale: controls.",
1783
+ deprecated: ["--k-text-control"]
1784
+ },
1785
+ {
1786
+ name: "text-meta",
1787
+ tier: "private",
1788
+ type: "length",
1789
+ group: "Private",
1790
+ source: css("calc(var(--k-font-size) - 1px)"),
1791
+ doc: "Type scale: metadata.",
1792
+ deprecated: ["--k-text-meta", "--ku-text-meta"]
1793
+ },
1794
+ {
1795
+ name: "text-cap",
1796
+ tier: "private",
1797
+ type: "length",
1798
+ group: "Private",
1799
+ source: css("calc(var(--k-font-size) - 2px)"),
1800
+ doc: "Type scale: caps and captions.",
1801
+ deprecated: ["--k-text-cap"]
1802
+ },
1803
+ {
1804
+ name: "weight",
1805
+ tier: "private",
1806
+ type: "number",
1807
+ group: "Private",
1808
+ source: value("400"),
1809
+ doc: "Body weight.",
1810
+ deprecated: ["--k-font-weight", "--ku-font-weight"]
1811
+ },
1812
+ {
1813
+ name: "weight-label",
1814
+ tier: "private",
1815
+ type: "number",
1816
+ group: "Private",
1817
+ source: value("500"),
1818
+ doc: "Label weight.",
1819
+ deprecated: ["--k-label-weight", "--ku-label-weight"]
1820
+ },
1821
+ {
1822
+ name: "weight-title",
1823
+ tier: "private",
1824
+ type: "number",
1825
+ group: "Private",
1826
+ source: value("600"),
1827
+ doc: "Title weight.",
1828
+ deprecated: ["--k-title-weight", "--ku-title-weight"]
1829
+ },
1830
+ {
1831
+ name: "focus-ring",
1832
+ tier: "private",
1833
+ type: "shadow",
1834
+ group: "Private",
1835
+ source: css("0 0 0 2px var(--k-bg),0 0 0 4px var(--k-focus)"),
1836
+ doc: "Two-layer focus ring: a bg gap, then the focus colour."
1837
+ },
1838
+ {
1839
+ name: "diff-add-line",
1840
+ tier: "private",
1841
+ type: "color",
1842
+ group: "Private",
1843
+ source: css("color-mix(in oklch,var(--k-diff-add) 12%,transparent)"),
1844
+ doc: "Added line tint."
1845
+ },
1846
+ {
1847
+ name: "diff-add-word",
1848
+ tier: "private",
1849
+ type: "color",
1850
+ group: "Private",
1851
+ source: css("color-mix(in oklch,var(--k-diff-add) 38%,transparent)"),
1852
+ doc: "Added word tint."
1853
+ },
1854
+ {
1855
+ name: "diff-del-line",
1856
+ tier: "private",
1857
+ type: "color",
1858
+ group: "Private",
1859
+ source: css("color-mix(in oklch,var(--k-diff-del) 12%,transparent)"),
1860
+ doc: "Deleted line tint."
1861
+ },
1862
+ {
1863
+ name: "diff-del-word",
1864
+ tier: "private",
1865
+ type: "color",
1866
+ group: "Private",
1867
+ source: css("color-mix(in oklch,var(--k-diff-del) 38%,transparent)"),
1868
+ doc: "Deleted word tint."
1869
+ },
1870
+ {
1871
+ name: "diff-mod-line",
1872
+ tier: "private",
1873
+ type: "color",
1874
+ group: "Private",
1875
+ source: css("color-mix(in oklch,var(--k-diff-mod) 12%,transparent)"),
1876
+ doc: "Modified line tint."
1877
+ },
1878
+ {
1879
+ name: "diff-mod-word",
1880
+ tier: "private",
1881
+ type: "color",
1882
+ group: "Private",
1883
+ source: css("color-mix(in oklch,var(--k-diff-mod) 38%,transparent)"),
1884
+ doc: "Modified word tint."
1885
+ }
1886
+ ];
1887
+ TOKEN_BY_NAME = new Map(TOKENS.map((t) => [t.name, t]));
1888
+ PROPERTY_TO_NAME = new Map(TOKENS.map((t) => [cssName(t), t.name]));
1889
+ DEPRECATED = new Map(TOKENS.flatMap((t) => (t.deprecated ?? []).map((old) => [old, cssName(t)])));
1890
+ });
1891
+
1892
+ // src/tokens/css.ts
1893
+ function pair(def, dark, light) {
1894
+ if (dark === undefined && light === undefined)
1895
+ return;
1896
+ if (dark === undefined || light === undefined || dark === light || def.type !== "color")
1897
+ return dark ?? light;
1898
+ return `light-dark(${light},${dark})`;
1899
+ }
1900
+ function declaredValue(theme, def) {
1901
+ const name = def.name;
1902
+ const dark = theme.declared.dark[name];
1903
+ const light = theme.declared.light[name];
1904
+ if (def.type === "color" && dark === undefined !== (light === undefined))
1905
+ return pair(def, dark ?? theme.dark[name], light ?? theme.light[name]);
1906
+ return pair(def, dark, light);
1907
+ }
1908
+ function resolver(def) {
1909
+ const reads = [...def.deprecated ?? []];
1910
+ if (def.tier !== "private")
1911
+ reads.push(cssName(def));
1912
+ const source = def.source;
1913
+ const fallback = "css" in source ? privately(source.css) : ("value" in source) && def.tier === "private" ? source.value : undefined;
1914
+ let out = fallback ?? "";
1915
+ for (let i = reads.length - 1;i >= 0; i--)
1916
+ out = out === "" ? `var(${reads[i]})` : `var(${reads[i]},${out})`;
1917
+ return def.resolve ? privately(def.resolve).replaceAll("$", out) : out;
1918
+ }
1919
+ function tokensCss(theme) {
1920
+ const root = [];
1921
+ const resolved = [];
1922
+ for (const def of TOKENS) {
1923
+ const source = def.source;
1924
+ const own = declaredValue(theme, def) ?? ("from" in source ? "" : ("value" in source) && def.tier !== "private" ? source.value : undefined);
1925
+ if (own !== undefined && def.tier !== "private")
1926
+ root.push(`${cssName(def)}:${own}`);
1927
+ resolved.push(`--_k-${def.name}:${resolver(def)}`);
1928
+ }
1929
+ return `@layer knobs.tokens{
1930
+ :where(:root,:host){${root.join(";")}}
1931
+ :where(.knobs-root){${resolved.join(";")}}
1932
+ ${APPEARANCE_CSS}
1933
+ }`;
1934
+ }
1935
+ function themeCss(theme, selector) {
1936
+ const decls = [];
1937
+ for (const def of TOKENS) {
1938
+ const own = declaredValue(theme, def);
1939
+ if (own !== undefined)
1940
+ decls.push(`${cssName(def)}:${own}`);
1941
+ }
1942
+ return `@layer knobs.tokens{${selector}{${decls.join(";")}}}`;
1943
+ }
1944
+ var SCHEMES, APPEARANCE_CSS, privately = (css) => css.replace(/var\(--k-([a-z0-9-]+)/g, (m, name) => tokenForProperty(`--k-${name}`) ? `var(--_k-${name}` : m);
1945
+ var init_css = __esm(() => {
1946
+ init_schema();
1947
+ SCHEMES = [
1948
+ [":where(.knobs-root)", "light dark"],
1949
+ [
1950
+ ':where(.dark,.dark-theme,[data-theme="dark"],[data-appearance="dark"],[data-knobs-theme="dark"]) :where(.knobs-root)',
1951
+ "dark"
1952
+ ],
1953
+ [
1954
+ ':where(.light,.light-theme,[data-theme="light"],[data-appearance="light"],[data-knobs-theme="light"]) :where(.knobs-root)',
1955
+ "light"
1956
+ ],
1957
+ [":where(.knobs-root) :where(.knobs-root:not([data-appearance]))", "inherit"],
1958
+ [':where(.knobs-root[data-appearance="dark"])', "dark"],
1959
+ [':where(.knobs-root[data-appearance="light"])', "light"],
1960
+ [':where(.knobs-root[data-appearance="system"])', "light dark"],
1961
+ [':where(.knobs-root[data-appearance="inherit"])', "inherit"]
1962
+ ];
1963
+ APPEARANCE_CSS = SCHEMES.map(([selector, scheme]) => {
1964
+ const light = scheme === "light" ? "1" : scheme === "inherit" ? "inherit" : "0";
1965
+ const rule = `${selector}{color-scheme:${scheme};--_k-light:${light}}`;
1966
+ return scheme === "light dark" ? `${rule}
1967
+ @media(prefers-color-scheme:light){${selector}{--_k-light:1}}` : rule;
1968
+ }).join(`
1969
+ `);
1970
+ });
1971
+
1972
+ // src/tokens/evaluate.ts
1973
+ function splitTop(s) {
1974
+ const out = [];
1975
+ let depth = 0;
1976
+ let start = 0;
1977
+ for (let i = 0;i < s.length; i++) {
1978
+ const ch = s[i];
1979
+ if (ch === "(")
1980
+ depth++;
1981
+ else if (ch === ")")
1982
+ depth--;
1983
+ else if (ch === "," && depth === 0) {
1984
+ out.push(s.slice(start, i).trim());
1985
+ start = i + 1;
1986
+ }
1987
+ }
1988
+ out.push(s.slice(start).trim());
1989
+ return out;
1990
+ }
1991
+ function evaluate(input, lookup) {
1992
+ const s = input.trim();
1993
+ const v = call(s, "var");
1994
+ if (v !== undefined) {
1995
+ const [name, ...fallback] = splitTop(v);
1996
+ const value = lookup(name);
1997
+ if (value !== undefined)
1998
+ return evaluate(value, lookup);
1999
+ if (fallback.length)
2000
+ return evaluate(fallback.join(","), lookup);
2001
+ throw new Error(`Unresolved ${name}`);
2002
+ }
2003
+ const mix = call(s, "color-mix");
2004
+ if (mix !== undefined)
2005
+ return colorMix(mix, lookup);
2006
+ return normalize(s);
2007
+ }
2008
+ function percent(s, lookup) {
2009
+ const c = call(s, "calc");
2010
+ if (c === undefined)
2011
+ return Number.parseFloat(s) / 100;
2012
+ const [a, b] = c.split("*").map((x) => x.trim());
2013
+ const num = (x) => {
2014
+ const inner = call(x, "var");
2015
+ if (inner !== undefined)
2016
+ return Number.parseFloat(lookup(splitTop(inner)[0]) ?? Number.NaN.toString());
2017
+ return x.endsWith("%") ? Number.parseFloat(x) / 100 : Number.parseFloat(x);
2018
+ };
2019
+ const out = num(a) * num(b);
2020
+ if (!Number.isFinite(out))
2021
+ throw new Error(`Bad percentage: ${s}`);
2022
+ return out;
2023
+ }
2024
+ function stop(s, lookup) {
2025
+ const m = /^(.*?)\s+((?:calc\(.*\))|(?:[\d.]+%))$/.exec(s);
2026
+ if (!m)
2027
+ return { color: evaluate(s, lookup) };
2028
+ return { color: evaluate(m[1], lookup), p: percent(m[2], lookup) };
2029
+ }
2030
+ function colorMix(args, lookup) {
2031
+ const [space, a, b] = splitTop(args);
2032
+ if (space !== "in oklch")
2033
+ throw new Error(`Only color-mix(in oklch, …) is supported, got ${space}`);
2034
+ const x = stop(a, lookup);
2035
+ const y = stop(b, lookup);
2036
+ let p1 = x.p ?? (y.p === undefined ? 0.5 : 1 - y.p);
2037
+ let p2 = y.p ?? 1 - p1;
2038
+ const sum = p1 + p2;
2039
+ const scale = sum < 1 ? sum : 1;
2040
+ p1 /= sum;
2041
+ p2 /= sum;
2042
+ const ca = linearToOklch(parseColor(x.color));
2043
+ const cb = linearToOklch(parseColor(y.color));
2044
+ const a1 = ca.alpha ?? 1;
2045
+ const a2 = cb.alpha ?? 1;
2046
+ const alpha = a1 * p1 + a2 * p2;
2047
+ if (alpha <= 0)
2048
+ return "#00000000";
2049
+ const powerless = (c, alpha) => c.c < 0.0002 || alpha === 0;
2050
+ const h1 = powerless(ca, a1) ? cb.h : ca.h;
2051
+ const h2 = powerless(cb, a2) ? h1 : cb.h;
2052
+ let dh = h2 - h1;
2053
+ if (dh > 180)
2054
+ dh -= 360;
2055
+ if (dh < -180)
2056
+ dh += 360;
2057
+ const pre = (u, v) => (u * a1 * p1 + v * a2 * p2) / alpha;
2058
+ const rgb = oklchToLinear({
2059
+ l: pre(ca.l, cb.l),
2060
+ c: pre(ca.c, cb.c),
2061
+ h: (h1 + dh * p2 + 360) % 360
2062
+ });
2063
+ return formatHex([rgb[0], rgb[1], rgb[2], alpha * scale]);
2064
+ }
2065
+ var call = (s, fn) => s.startsWith(`${fn}(`) && s.endsWith(")") ? s.slice(fn.length + 1, -1) : undefined;
2066
+ var init_evaluate = () => {};
2067
+
2068
+ // src/themes/define.ts
2069
+ function fontStack(family, fallback) {
2070
+ if (family.includes(","))
2071
+ return family;
2072
+ const quoted = /\s/.test(family) && !/^["']/.test(family) ? `"${family}"` : family;
2073
+ return family === fallback ? family : `${quoted},${fallback}`;
2074
+ }
2075
+ function mergeInputs(parent, spec) {
2076
+ return {
2077
+ gray: { ...parent.gray, ...spec.gray },
2078
+ accent: spec.accent ?? parent.accent,
2079
+ contrast: spec.contrast ?? parent.contrast,
2080
+ radius: spec.radius ?? parent.radius,
2081
+ density: spec.density ?? parent.density,
2082
+ material: spec.material ?? parent.material,
2083
+ font: {
2084
+ sans: spec.font?.sans ? fontStack(spec.font.sans, DEFAULT_SANS) : parent.font.sans,
2085
+ mono: spec.font?.mono ? fontStack(spec.font.mono, DEFAULT_MONO) : parent.font.mono
2086
+ },
2087
+ tokens: {
2088
+ dark: { ...parent.tokens.dark, ...spec.tokens?.dark },
2089
+ light: { ...parent.tokens.light, ...spec.tokens?.light }
2090
+ }
2091
+ };
2092
+ }
2093
+ function meet(l, floor, bg, away, make) {
2094
+ let x = l;
2095
+ while (apca(make(x), bg) < floor + 0.5 && x >= 0 && x <= 100)
2096
+ x += away * 0.25;
2097
+ return make(Math.min(100, Math.max(0, x)));
2098
+ }
2099
+ function solve(target, bg, away, make) {
2100
+ let near = toOklch(bg).l * 100;
2101
+ let far = away > 0 ? 100 : 0;
2102
+ if (apca(make(far), bg) <= target)
2103
+ return far;
2104
+ for (let i = 0;i < 30; i++) {
2105
+ const mid = (near + far) / 2;
2106
+ if (apca(make(mid), bg) < target)
2107
+ near = mid;
2108
+ else
2109
+ far = mid;
2110
+ }
2111
+ return far;
2112
+ }
2113
+ function accentPair(inputs) {
2114
+ if (typeof inputs.accent !== "string")
2115
+ return { ...inputs.accent };
2116
+ const dark = inputs.accent;
2117
+ const o = toOklch(dark);
2118
+ const 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 });
2119
+ return { dark, light };
2120
+ }
2121
+ function generate(inputs, appearance, accent) {
2122
+ const m = contrastMultiplier(inputs.contrast);
2123
+ const { hue, chroma } = inputs.gray;
2124
+ const neutral = (l, tint) => oklchToHex({ l: l / 100, c: chroma * tint, h: hue });
2125
+ const user = inputs.tokens[appearance];
2126
+ const out = {};
2127
+ const surfaces = SURFACES[appearance];
2128
+ for (const [role, l] of Object.entries(surfaces)) {
2129
+ const spread = surfaces.bg + (l - surfaces.bg) * m;
2130
+ out[role] = user[role] ?? neutral(Math.min(100, Math.max(0, spread)), TINT.surface[appearance]);
2131
+ }
2132
+ const bg = out.bg;
2133
+ const away = appearance === "dark" ? 1 : -1;
2134
+ const inkSpread = 1 + (m - 1) * 0.4;
2135
+ for (const [role, target] of Object.entries(INKS[appearance])) {
2136
+ const tint = role === "fg" ? TINT.fg : role === "border-strong" ? TINT.border : TINT.ink;
2137
+ const make = (x) => neutral(x, tint);
2138
+ const l = solve(target * inkSpread, bg, away, make);
2139
+ out[role] = meet(l, APCA_BUDGET[role], bg, away, make);
2140
+ }
2141
+ out.accent = accent;
2142
+ const a = toOklch(accent);
2143
+ out["accent-fg"] = meet(a.l * 100, APCA_BUDGET["accent-fg"], bg, away, (x) => oklchToHex({ l: x / 100, c: a.c, h: a.h }));
2144
+ out["on-accent"] = apca("#111111", accent) >= apca("#ffffff", accent) ? "#111111" : "#ffffff";
2145
+ for (const [role, [l, c, h]] of Object.entries(STATUS[appearance]))
2146
+ out[role] = oklchToHex({ l: l / 100, c, h });
2147
+ const s = SERIES[appearance];
2148
+ const start = a.c >= 0.04 ? a.h - SERIES_HUES[0] : 0;
2149
+ SERIES_HUES.forEach((h, i) => {
2150
+ out[`series-${i + 1}`] = oklchToHex({ l: s.l / 100, c: s.c, h: (h + start + 360) % 360 });
2151
+ });
2152
+ out.scrim = appearance === "dark" ? "#00000099" : "#00000040";
2153
+ out.contrast = String(Math.round(m * 1000) / 1000);
2154
+ out.radius = `${inputs.radius}px`;
2155
+ out.density = String(DENSITY[inputs.density]);
2156
+ out.font = inputs.font.sans;
2157
+ out.mono = inputs.font.mono;
2158
+ const material = inputs.material;
2159
+ out.glass = material === "glass" ? "0.6" : "0";
2160
+ out.glow = material === "glass" ? "0.5" : "0";
2161
+ out.rim = material === "flat" ? "transparent" : appearance === "dark" ? "#ffffff1a" : "#ffffff99";
2162
+ if (material === "flat") {
2163
+ out["border-subtle"] = over(withAlpha(out.fg, 0.06 * m), bg);
2164
+ out.border = over(withAlpha(out.fg, 0.1 * m), bg);
2165
+ }
2166
+ return out;
2167
+ }
2168
+ function shadows(material, borderStrong) {
2169
+ if (material === "flat")
2170
+ return {
2171
+ "shadow-raised": "none",
2172
+ "shadow-overlay": `0 0 0 1px light-dark(${borderStrong.light},${borderStrong.dark})`
2173
+ };
2174
+ return {
2175
+ "shadow-raised": "0 1px 2px light-dark(#0000001f,#00000029)",
2176
+ "shadow-overlay": "0 12px 36px light-dark(#00000024,#00000085),0 1px 2px light-dark(#00000014,#0000004d)"
2177
+ };
2178
+ }
2179
+ function resolve(declared) {
2180
+ const raw = (name) => {
2181
+ const def = TOKEN_BY_NAME.get(name);
2182
+ const own = declared[name];
2183
+ if (own !== undefined)
2184
+ return own;
2185
+ const source = def.source;
2186
+ if ("css" in source)
2187
+ return source.css;
2188
+ if ("value" in source)
2189
+ return source.value;
2190
+ throw new Error(`Theme does not supply ${name}`);
2191
+ };
2192
+ const lookup = (property) => {
2193
+ const name = tokenForProperty(property);
2194
+ return name ? raw(name) : undefined;
2195
+ };
2196
+ const out = {};
2197
+ for (const t of TOKENS)
2198
+ out[t.name] = t.type === "color" ? evaluate(raw(t.name), lookup) : raw(t.name);
2199
+ return out;
2200
+ }
2201
+ function gpuOf(resolved) {
2202
+ const out = {};
2203
+ for (const t of TOKENS)
2204
+ if (t.type === "color")
2205
+ out[t.name] = parseColor(resolved[t.name]);
2206
+ return out;
2207
+ }
2208
+ function validate(name, inputs) {
2209
+ if (!/^[\w-]+$/.test(name))
2210
+ throw new Error(`Invalid theme name: ${name}`);
2211
+ if (name === "dark" || name === "light")
2212
+ throw new Error(`Reserved theme name: ${name}`);
2213
+ for (const appearance of ["dark", "light"])
2214
+ for (const key of Object.keys(inputs.tokens[appearance]))
2215
+ if (!TOKEN_BY_NAME.has(key))
2216
+ throw new Error(`Unknown token in theme ${name}: ${key}`);
2217
+ }
2218
+ function defineTheme(spec) {
2219
+ const inputs = mergeInputs(spec.extends?.inputs ?? BASE, spec);
2220
+ validate(spec.name, inputs);
2221
+ const accent = accentPair(inputs);
2222
+ const generated = {
2223
+ dark: generate(inputs, "dark", accent.dark),
2224
+ light: generate(inputs, "light", accent.light)
2225
+ };
2226
+ const material = shadows(inputs.material, {
2227
+ dark: inputs.tokens.dark["border-strong"] ?? generated.dark["border-strong"],
2228
+ light: inputs.tokens.light["border-strong"] ?? generated.light["border-strong"]
2229
+ });
2230
+ const declared = {
2231
+ dark: { ...generated.dark, ...material, ...inputs.tokens.dark },
2232
+ light: { ...generated.light, ...material, ...inputs.tokens.light }
2233
+ };
2234
+ for (const [key, dark] of Object.entries(declared.dark)) {
2235
+ const def = TOKEN_BY_NAME.get(key);
2236
+ const light = declared.light[key];
2237
+ if (def.type !== "color" && light !== undefined && light !== dark)
2238
+ throw new Error(`Theme ${spec.name}: only colours may differ by appearance (${key})`);
2239
+ }
2240
+ const dark = resolve(declared.dark);
2241
+ const light = resolve(declared.light);
2242
+ const theme = {
2243
+ name: spec.name,
2244
+ inputs,
2245
+ dark,
2246
+ light,
2247
+ declared,
2248
+ gpu: { dark: gpuOf(dark), light: gpuOf(light) },
2249
+ css: (options) => options?.selector ? themeCss(theme, options.selector) : tokensCss(theme)
2250
+ };
2251
+ return theme;
2252
+ }
2253
+ var DEFAULT_SANS = 'system-ui,-apple-system,"SF Pro Text",sans-serif', DEFAULT_MONO = '"SF Mono",SFMono-Regular,ui-monospace,Menlo,monospace', BASE, DENSITY, SURFACES, INKS, APCA_BUDGET, TINT, STATUS, SERIES_HUES, SERIES, contrastMultiplier = (contrast) => 0.5 + Math.min(100, Math.max(0, contrast)) / 100;
2254
+ var init_define = __esm(() => {
2255
+ init_css();
2256
+ init_evaluate();
2257
+ init_schema();
2258
+ BASE = {
2259
+ gray: { hue: 0, chroma: 0 },
2260
+ accent: "#ffffff",
2261
+ contrast: 50,
2262
+ radius: 8,
2263
+ density: "default",
2264
+ material: "solid",
2265
+ font: { sans: DEFAULT_SANS, mono: DEFAULT_MONO },
2266
+ tokens: { dark: {}, light: {} }
2267
+ };
2268
+ DENSITY = { compact: 0.875, default: 1, comfortable: 1.1875 };
2269
+ SURFACES = {
2270
+ dark: { "bg-page": 14.5, "bg-inset": 19.6, bg: 22.6, "bg-raised": 25.7, "bg-overlay": 28.1 },
2271
+ light: { "bg-page": 92.6, "bg-inset": 94.6, bg: 97.1, "bg-raised": 100, "bg-overlay": 100 }
2272
+ };
2273
+ INKS = {
2274
+ dark: { fg: 99.7, "fg-2": 76.7, "fg-3": 48.4, "fg-4": 31.9, "border-strong": 15.8 },
2275
+ light: { fg: 98.35, "fg-2": 78, "fg-3": 50, "fg-4": 34, "border-strong": 17 }
2276
+ };
2277
+ APCA_BUDGET = {
2278
+ fg: 90,
2279
+ "fg-2": 75,
2280
+ "fg-3": 45,
2281
+ "fg-4": 30,
2282
+ "accent-fg": 60,
2283
+ "border-strong": 15
2284
+ };
2285
+ TINT = { surface: { dark: 0.5, light: 0.7 }, fg: 1.35, ink: 1.5, border: 1.25 };
2286
+ STATUS = {
2287
+ dark: {
2288
+ ok: [78, 0.15, 155],
2289
+ warn: [83, 0.14, 80],
2290
+ danger: [70, 0.18, 25],
2291
+ info: [75, 0.13, 240]
2292
+ },
2293
+ light: {
2294
+ ok: [52, 0.14, 150],
2295
+ warn: [60, 0.14, 65],
2296
+ danger: [55, 0.2, 27],
2297
+ info: [53, 0.15, 245]
2298
+ }
2299
+ };
2300
+ SERIES_HUES = [250, 155, 75, 25, 305, 195];
2301
+ SERIES = { dark: { l: 74, c: 0.12 }, light: { l: 56, c: 0.14 } };
2302
+ });
2303
+
2304
+ // src/themes/knobs.ts
2305
+ var knobs;
2306
+ var init_knobs = __esm(() => {
2307
+ init_define();
2308
+ knobs = defineTheme({
2309
+ name: "knobs",
2310
+ gray: { hue: 285, chroma: 0.004 },
2311
+ accent: { dark: "#ffffff", light: "#1c1c1e" },
2312
+ contrast: 50,
2313
+ radius: 8,
2314
+ density: "default",
2315
+ material: "glass"
2316
+ });
2317
+ });
2318
+
2319
+ // src/core/glide.ts
2320
+ var COLOR_TOKENS, LENGTH_TOKENS, NUMBER_TOKENS, ANIMATED, TOKEN_TRANSITIONS, 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(`
2321
+ `), GLIDING = ".knobs-panel,.knobs-chip,.knobs-notice,.knobs-ui", DRIVERS, aliased = (css) => css.replace(new RegExp(`var\\(--_k-(${ANIMATED.join("|")})\\)`, "g"), "var(--kv-$1)").replace(/var\(--k-blur\)/g, "var(--kv-blur)");
2322
+ var init_glide = __esm(() => {
2323
+ COLOR_TOKENS = [
2324
+ "bg",
2325
+ "fill",
2326
+ "fill-selected",
2327
+ "border",
2328
+ "border-strong",
2329
+ "fg",
2330
+ "fg-2",
2331
+ "fg-3",
2332
+ "accent",
2333
+ "modified",
2334
+ "segmented-track",
2335
+ "segmented-active",
2336
+ "toggle-track",
2337
+ "toggle-thumb",
2338
+ "toggle-thumb-off",
2339
+ "slider-handle",
2340
+ "rim",
2341
+ "border-subtle",
2342
+ "bg-page"
2343
+ ];
2344
+ LENGTH_TOKENS = ["pad", "inset", "row", "gap", "radius", "radius-panel", "font-size"];
2345
+ NUMBER_TOKENS = ["weight-label", "blur", "glow", "glass", "glass-tone"];
2346
+ ANIMATED = [...COLOR_TOKENS, ...LENGTH_TOKENS, ...NUMBER_TOKENS, "width"];
2347
+ TOKEN_TRANSITIONS = ANIMATED.map((t) => `--kt-${t} var(--k-token-t)`).join(",");
2348
+ DRIVERS = `${register(COLOR_TOKENS, "<color>", "transparent")}
2349
+ ${register(LENGTH_TOKENS, "<length>", "0px")}
2350
+ ${register(NUMBER_TOKENS, "<number>", "0")}
2351
+ ${register(["width"], "<length-percentage>", "288px")}
2352
+ :where(${GLIDING}){${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)}
2353
+ :where(.knobs-ui){transition:${TOKEN_TRANSITIONS}}
2354
+ :root[data-knobs-scrub] :where(.knobs-chip,.knobs-ui){--k-token-t:0s}
2355
+ @media(prefers-reduced-motion:reduce){:where(.knobs-chip,.knobs-ui){--k-token-t:0s}}`;
2356
+ });
2357
+
2358
+ // src/core/root.ts
2359
+ function injectTokens(doc) {
2360
+ if (doc.querySelector("style[data-knobs-tokens]"))
2361
+ return;
2362
+ const style = doc.createElement("style");
2363
+ style.dataset.knobsTokens = "";
2364
+ style.textContent = rootCss;
2365
+ doc.head.append(style);
2366
+ }
2367
+ var ROOT_CLASS = "knobs-root", extras, spring, rootCss;
2368
+ var init_root = __esm(() => {
2369
+ init_knobs();
2370
+ init_css();
2371
+ init_glide();
2372
+ init_motion();
2373
+ 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))}`;
2374
+ spring = `:where(:root,:host){--k-fill-ease:${DEFAULT_LINEAR.easing};--k-fill-ms:${DEFAULT_LINEAR.ms}}`;
2375
+ rootCss = `${tokensCss(knobs)}
2376
+ ${extras}
2377
+ ${spring}
2378
+ ${DRIVERS}
2379
+ ${motionCss}`;
2380
+ });
2381
+
719
2382
  // src/core/keys.ts
720
2383
  function normalizeCombo(combo) {
721
2384
  const trimmed = combo.trim();
@@ -834,36 +2497,18 @@ var init_keys = __esm(() => {
834
2497
 
835
2498
  // src/ui/look.ts
836
2499
  function injectUiStyles(doc) {
2500
+ injectTokens(doc);
837
2501
  if (doc.querySelector("style[data-knobs-ui]"))
838
2502
  return;
839
2503
  const style = doc.createElement("style");
840
2504
  style.dataset.knobsUi = "";
841
- style.textContent = css + readoutCss + overlayCss + bentoCss + activityCss + pickerCss + compareCss + rolling_css_default;
2505
+ style.textContent = uiCss();
842
2506
  doc.head.append(style);
843
2507
  }
844
- function injectUiPreset(doc, preset) {
845
- const content = presetCss({ ...preset, css: undefined }).replaceAll(".knobs-panel", ".knobs-ui");
846
- const existing = doc.querySelector(`style[data-knobs-ui-preset="${preset.name}"]`);
847
- if (existing) {
848
- if (existing.textContent !== content)
849
- existing.textContent = content;
850
- return;
851
- }
852
- const style = doc.createElement("style");
853
- style.dataset.knobsUiPreset = preset.name;
854
- style.textContent = content;
855
- doc.head.append(style);
856
- }
857
- function applyLook(root, look) {
858
- const doc = root.ownerDocument;
859
- injectUiStyles(doc);
860
- root.classList.add("knobs-ui");
861
- if (look.preset) {
862
- injectUiPreset(doc, look.preset);
863
- root.dataset.preset = look.preset.name;
864
- }
865
- if (look.theme)
866
- root.dataset.theme = look.theme;
2508
+ function applyLook2(root, look) {
2509
+ injectUiStyles(root.ownerDocument);
2510
+ root.classList.add("knobs-root", "knobs-ui");
2511
+ applyLook(root, resolveLook(look));
867
2512
  syncFrame(root);
868
2513
  }
869
2514
  function syncFrame(root) {
@@ -905,109 +2550,44 @@ function frameLoop(win, step) {
905
2550
  }
906
2551
  };
907
2552
  }
908
- var ease, TOKENS, LIGHT, lightBlock, css, lookDefaults, reducedMotion = (win) => win?.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false, tune = (s, m) => {
909
- s.omega = m.omega;
910
- s.zeta = m.zeta;
911
- return s;
912
- }, svg = (body, box = 16) => `<svg viewBox="0 0 ${box} ${box}" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`, ICONS;
913
- var init_look = __esm(() => {
914
- init_theme();
915
- init_activity_css();
916
- init_picker_css();
917
- init_keys();
918
- ease = springEasing(26, 1);
919
- TOKENS = {
920
- bg: "#1c1c1e",
921
- surface: "rgba(255,255,255,.055)",
922
- "surface-hi": "rgba(255,255,255,.11)",
923
- line: "rgba(255,255,255,.1)",
924
- "line-hi": "rgba(255,255,255,.18)",
925
- text: "rgba(255,255,255,.92)",
926
- label: "rgba(255,255,255,.64)",
927
- dim: "rgba(255,255,255,.42)",
928
- accent: "#fff",
929
- font: 'system-ui,-apple-system,"SF Pro Text",sans-serif',
930
- mono: '"SF Mono",SFMono-Regular,ui-monospace,Menlo,monospace',
931
- "font-size": "12px",
932
- "font-weight": "400",
933
- "label-weight": "500",
934
- "title-weight": "600",
935
- row: "32px",
936
- inset: "10px",
937
- radius: "8px",
938
- "hover-in": "150",
939
- "hover-out": "150",
940
- warn: "#ff9f0a",
941
- critical: "#ff453a",
942
- rim: "rgba(255,255,255,.09)",
943
- page: "#101012",
944
- "seg-bg": "rgba(0,0,0,.26)",
945
- shadow: "0 12px 36px rgba(0,0,0,.52),0 1px 2px rgba(0,0,0,.3)"
946
- };
947
- LIGHT = {
948
- bg: "#f5f5f7",
949
- surface: "rgba(0,0,0,.05)",
950
- "surface-hi": "rgba(0,0,0,.095)",
951
- line: "rgba(0,0,0,.1)",
952
- "line-hi": "rgba(0,0,0,.2)",
953
- text: "rgba(0,0,0,.88)",
954
- label: "rgba(60,60,67,.68)",
955
- dim: "rgba(60,60,67,.5)",
956
- accent: "#1c1c1e",
957
- warn: "#c56a00",
958
- critical: "#e0352b",
959
- rim: "rgba(255,255,255,.75)",
960
- page: "#e6e6eb",
961
- "seg-bg": "rgba(0,0,0,.065)",
962
- shadow: "0 10px 32px rgba(0,0,0,.14),0 1px 3px rgba(0,0,0,.08)"
963
- };
964
- lightBlock = `${Object.entries(LIGHT).map(([k, v]) => `--k-${k}:${v}`).join(";")};color-scheme:light`;
965
- css = `
966
- :where(.knobs-ui){${Object.entries(TOKENS).map(([k, v]) => `--ku-${k}:var(--k-${k},${v})`).join(";")};
967
- --ku-control-h:var(--k-control-h,calc(var(--ku-row) - 8px));
968
- --ku-value-font:var(--k-value-font,var(--ku-font));
969
- --ku-value-size:var(--kc-value-size,calc(var(--ku-font-size) - .5px));
970
- --ku-text-meta:var(--k-text-meta,calc(var(--ku-font-size) - 1px));
971
- --ku-hit:var(--k-ui-hit,9px);
972
- --ku-rail:var(--k-ui-rail,var(--ku-row));
973
- --ku-indent:var(--k-ui-indent,14px);
974
- --ku-select:var(--k-ui-select,color-mix(in srgb,var(--ku-accent) 13%,transparent));
975
- --ku-select-focus:var(--k-ui-select-focus,color-mix(in srgb,var(--ku-accent) 19%,transparent));
976
- --ku-wash:var(--k-ui-wash,color-mix(in srgb,var(--ku-surface) 70%,transparent));
977
- --ku-wash-hi:var(--k-ui-wash-hi,var(--ku-surface-hi));
978
- --ku-ease:${ease.easing};--ku-ease-ms:${ease.ms}ms;
2553
+ var css2 = `
2554
+ :where(.knobs-ui){
2555
+ --_ku-hit:var(--k-ui-hit,9px);
2556
+ --_ku-rail:var(--k-ui-rail,var(--_k-row));
2557
+ --_ku-indent:var(--k-ui-indent,14px);
2558
+ --_ku-select:var(--k-ui-select,var(--k-selection,color-mix(in srgb,var(--_k-accent) 13%,transparent)));
2559
+ --_ku-select-focus:var(--k-ui-select-focus,color-mix(in srgb,var(--_k-accent) 19%,transparent));
2560
+ --_ku-wash:var(--k-ui-wash,color-mix(in srgb,var(--_k-fill) 70%,transparent));
2561
+ --_ku-wash-hi:var(--k-ui-wash-hi,var(--_k-fill-selected));
2562
+ --_ku-ease:var(--_k-motion-snappy);--_ku-ease-ms:calc(var(--_k-motion-snappy-ms) * 1ms);
979
2563
  /* The card frame (knobs' own look): every leaf pane a rounded card on the page, half a gap
980
2564
  inside its slot, so panes sit a gap apart with the dividers' grips between them; tree rows
981
2565
  inset as soft rounded washes. --k-frame: flat (labPreset) puts panes edge to edge on
982
2566
  hairlines, square, as a dense editor's columns. */
983
- --ku-panel-radius:var(--k-panel-radius,calc(var(--ku-radius) + 4px));
984
- --ku-gap:var(--k-ui-gap,6px);
985
- --ku-pane-m:calc(var(--ku-gap) / 2);
986
- --ku-pane-bg:var(--k-ui-pane,var(--ku-bg));
987
- --ku-pane-radius:var(--ku-panel-radius);
988
- --ku-pane-ring:inset 0 0 0 1px var(--ku-line),inset 0 1px 0 var(--ku-rim);
989
- --ku-divider:var(--k-ui-divider,transparent);
990
- --ku-row-x:var(--k-ui-row-x,6px);
991
- --ku-row-radius:max(0px,calc(var(--ku-panel-radius) - var(--ku-row-x)));
992
- }
993
- :where(.knobs-ui)[data-frame="flat"]{--ku-gap:var(--k-ui-gap,0px);--ku-pane-bg:var(--k-ui-pane,transparent);--ku-pane-radius:0px;--ku-pane-ring:none;
994
- --ku-divider:var(--k-ui-divider,var(--ku-line));--ku-row-x:var(--k-ui-row-x,0px);--ku-row-radius:0px;
995
- --ku-select:var(--k-ui-select,color-mix(in srgb,var(--ku-accent) 24%,transparent));--ku-select-focus:var(--k-ui-select-focus,color-mix(in srgb,var(--ku-accent) 34%,transparent))}
2567
+ --_ku-gap:var(--k-ui-gap,6px);
2568
+ --_ku-pane-m:calc(var(--_ku-gap) / 2);
2569
+ --_ku-pane-bg:var(--_k-pane-bg);
2570
+ --_ku-pane-radius:var(--_k-radius-panel);
2571
+ --_ku-pane-ring:inset 0 0 0 1px var(--_k-border),inset 0 1px 0 var(--_k-rim);
2572
+ --_ku-divider:var(--k-ui-divider,var(--k-split-gutter,transparent));
2573
+ --_ku-row-x:var(--k-ui-row-x,6px);
2574
+ --_ku-row-radius:max(0px,calc(var(--_ku-pane-radius) - var(--_ku-row-x)));
2575
+ }
2576
+ :where(.knobs-ui)[data-frame="flat"]{--_ku-gap:var(--k-ui-gap,0px);--_ku-pane-bg:var(--k-ui-pane,var(--k-pane-bg,transparent));--_ku-pane-radius:0px;--_ku-pane-ring:none;
2577
+ --_ku-divider:var(--_k-split-gutter);--_ku-row-x:var(--k-ui-row-x,0px);--_ku-row-radius:0px;
2578
+ --_ku-select:var(--_k-selection);--_ku-select-focus:var(--k-ui-select-focus,color-mix(in srgb,var(--_k-accent) 34%,transparent))}
996
2579
  /* One surface per thing: a piece on another surface draws no card of its own. Whatever draws a
997
2580
  card (a walkthrough's step, a host's own) carries .knobs-surface, and a split's pane that's a
998
2581
  card (not only a slot for another split) counts as one; any piece inside it, or one
999
2582
  marked data-nested, loses its fill and ring and parts its own panes on hairlines as the flat
1000
2583
  frame does, so cards never stack two or three borders deep. Pieces draw their card from
1001
- --ku-pane-bg and --ku-pane-ring so this reaches them. */
1002
- :where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip) .knobs-ui:not(.knobs-surface),.knobs-ui[data-nested]{--ku-gap:var(--k-ui-gap,0px);--ku-pane-bg:transparent;--ku-pane-ring:none;
1003
- --ku-divider:var(--k-ui-divider,var(--ku-line));--k-diff-bg:transparent}
1004
- :where(.knobs-ui)[data-theme="light"],
1005
- :where(:root[data-theme="light"]) :where(.knobs-ui)[data-theme="auto"]{${lightBlock}}
1006
- @media(prefers-color-scheme:light){:where(:root:not([data-theme="dark"])) :where(.knobs-ui)[data-theme="auto"]{${lightBlock}}}
2584
+ --_ku-pane-bg and --_ku-pane-ring so this reaches them. */
2585
+ :where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip) .knobs-ui:not(.knobs-surface),.knobs-ui[data-nested]{--_ku-gap:var(--k-ui-gap,0px);--_ku-pane-bg:transparent;--_ku-pane-ring:none;
2586
+ --_ku-divider:var(--_k-split-gutter);--_kd-bg:transparent}
1007
2587
  /* Only the pieces' own elements take their type and resets: what you put in a pane is yours. */
1008
2588
  .knobs-ui{box-sizing:border-box}
1009
2589
  :where(.knobs-split>*,.knobs-pane-clip,.knobs-pane-inner,.knobs-pane-body,.knobs-pane-head,.knobs-pane-head *,.knobs-pane-rail,.knobs-pane-rail *,.knobs-tree,.knobs-tree *,.knobs-tree-ghost){box-sizing:border-box}
1010
- :is(.knobs-tree,.knobs-pane-head,.knobs-pane-rail,.knobs-tree-ghost){font:var(--ku-font-weight) var(--ku-font-size)/1.35 var(--ku-font);color:var(--ku-text);text-align:left;
2590
+ :is(.knobs-tree,.knobs-pane-head,.knobs-pane-rail,.knobs-tree-ghost){font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);text-align:left;
1011
2591
  letter-spacing:normal;word-spacing:normal;text-transform:none;text-indent:0;text-shadow:none;font-style:normal;-webkit-font-smoothing:antialiased}
1012
2592
  /* A host's element rules (button{padding}, header{margin}, mark{background}) stop at these, as
1013
2593
  they do at panels; (0,1,0), so the pieces' own rules after it win. */
@@ -1045,17 +2625,17 @@ var init_look = __esm(() => {
1045
2625
  :is(.knobs-tree,.knobs-activity)::-webkit-scrollbar{display:none}
1046
2626
  .knobs-scrollbar{position:sticky;top:0;z-index:3;height:0;pointer-events:none}
1047
2627
  .knobs-scrollbar[hidden]{display:none}
1048
- .knobs-scrollbar-thumb{position:absolute;top:0;right:2px;width:5px;border-radius:3px;background:color-mix(in srgb,var(--ku-text) 30%,transparent);opacity:0;
2628
+ .knobs-scrollbar-thumb{position:absolute;top:0;right:2px;width:5px;border-radius:3px;background:color-mix(in srgb,var(--_k-fg) 30%,transparent);opacity:0;
1049
2629
  transition:opacity .3s ease-out,background .15s}
1050
2630
  :hover>.knobs-scrollbar>.knobs-scrollbar-thumb,.knobs-scrollbar:is([data-active],[data-dragging])>.knobs-scrollbar-thumb{opacity:1;pointer-events:auto;transition-duration:.12s,.15s}
1051
- .knobs-scrollbar-thumb:hover,.knobs-scrollbar[data-dragging]>.knobs-scrollbar-thumb{background:color-mix(in srgb,var(--ku-text) 48%,transparent)}
2631
+ .knobs-scrollbar-thumb:hover,.knobs-scrollbar[data-dragging]>.knobs-scrollbar-thumb{background:color-mix(in srgb,var(--_k-fg) 48%,transparent)}
1052
2632
 
1053
2633
  /* Split: panes along a row or column, hairline dividers with a wider grip. */
1054
2634
  .knobs-split{position:relative;display:flex;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden}
1055
2635
  .knobs-split[data-direction="column"]{flex-direction:column}
1056
2636
  .knobs-pane{position:relative;flex:none;min-width:0;min-height:0;overflow:hidden}
1057
- .knobs-pane-clip{position:absolute;inset:0;margin:var(--ku-pane-m);overflow:hidden;border-radius:var(--ku-pane-radius);background:var(--ku-pane-bg)}
1058
- .knobs-pane-clip::after{content:"";position:absolute;inset:0;border-radius:inherit;box-shadow:var(--ku-pane-ring);pointer-events:none}
2637
+ .knobs-pane-clip{position:absolute;inset:0;margin:var(--_ku-pane-m);overflow:hidden;border-radius:var(--_ku-pane-radius);background:var(--_ku-pane-bg)}
2638
+ .knobs-pane-clip::after{content:"";position:absolute;inset:0;border-radius:inherit;box-shadow:var(--_ku-pane-ring);pointer-events:none}
1059
2639
  /* A pane holding another split is only its slot: the split's own panes are the cards. */
1060
2640
  .knobs-pane[data-nested]>.knobs-pane-clip{margin:0;background:transparent}
1061
2641
  .knobs-pane[data-nested]>.knobs-pane-clip::after{content:none}
@@ -1063,36 +2643,36 @@ var init_look = __esm(() => {
1063
2643
  .knobs-pane-body{position:relative;flex:1;min-width:0;min-height:0;overflow:hidden}
1064
2644
  .knobs-pane[data-scroll] .knobs-pane-body{overflow:auto;scrollbar-width:thin}
1065
2645
  .knobs-pane[data-rail][data-collapsed][data-settled]>.knobs-pane-clip>.knobs-pane-inner,.knobs-pane:not([data-rail])[data-collapsed][data-settled]>.knobs-pane-clip>.knobs-pane-inner>.knobs-pane-body{visibility:hidden}
1066
- .knobs-ui .knobs-pane-head{display:flex;align-items:center;gap:6px;flex:none;height:var(--ku-row);padding:0 calc(var(--ku-inset) - 4px) 0 var(--ku-inset);user-select:none;-webkit-user-select:none}
1067
- .knobs-pane-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--ku-title-weight);color:var(--ku-text)}
1068
- .knobs-pane-count{flex:none;color:var(--ku-dim);font-variant-numeric:tabular-nums}
2646
+ .knobs-ui .knobs-pane-head{display:flex;align-items:center;gap:6px;flex:none;height:var(--_k-row);padding:0 calc(var(--_k-inset) - 4px) 0 var(--_k-inset);user-select:none;-webkit-user-select:none}
2647
+ .knobs-pane-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--_k-weight-title);color:var(--_k-fg)}
2648
+ .knobs-pane-count{flex:none;color:var(--_k-fg-3);font-variant-numeric:tabular-nums}
1069
2649
  .knobs-pane-fill{flex:1}
1070
- .knobs-ui .knobs-pane-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:calc(var(--ku-radius) * 999);color:var(--ku-dim);cursor:pointer;
2650
+ .knobs-ui .knobs-pane-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:calc(var(--_k-radius) * 999);color:var(--_k-fg-3);cursor:pointer;
1071
2651
  transition:background var(--hover-t,.15s),color .15s}
1072
- .knobs-ui .knobs-pane-btn:is(:hover,:focus-visible){background:var(--ku-wash-hi);color:var(--ku-text)}
1073
- .knobs-ui .knobs-pane-btn[aria-pressed="true"]{color:var(--ku-accent)}
2652
+ .knobs-ui .knobs-pane-btn:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
2653
+ .knobs-ui .knobs-pane-btn[aria-pressed="true"]{color:var(--_k-accent)}
1074
2654
  .knobs-pane-btn svg{width:13px;height:13px}
1075
2655
  .knobs-pane-head[data-toggles]{cursor:pointer}
1076
2656
  /* A collapsed pane's rail: its title along the edge; a click opens it. It holds on to the edge the
1077
2657
  pane folds toward, as wide as the rail, over the card (which folds to its size): only its label
1078
2658
  and chevron draw, and a nested split's slot, which has no card, gives it one of its own. */
1079
- .knobs-ui .knobs-pane-rail{position:absolute;margin:var(--ku-pane-m);border-radius:var(--ku-pane-radius);background-color:transparent;display:flex;align-items:center;gap:8px;color:var(--ku-label);cursor:pointer;opacity:0;pointer-events:none;
1080
- font-weight:var(--ku-title-weight);transition:background .15s,color .15s}
1081
- .knobs-ui .knobs-pane[data-nested]>.knobs-pane-rail{background-color:var(--ku-pane-bg);box-shadow:var(--ku-pane-ring)}
1082
- .knobs-split[data-direction="row"]>.knobs-pane>.knobs-pane-rail{top:0;bottom:0;width:var(--ku-rail);writing-mode:vertical-rl;padding:10px 0}
2659
+ .knobs-ui .knobs-pane-rail{position:absolute;margin:var(--_ku-pane-m);border-radius:var(--_ku-pane-radius);background-color:transparent;display:flex;align-items:center;gap:8px;color:var(--_k-fg-2);cursor:pointer;opacity:0;pointer-events:none;
2660
+ font-weight:var(--_k-weight-title);transition:background .15s,color .15s}
2661
+ .knobs-ui .knobs-pane[data-nested]>.knobs-pane-rail{background-color:var(--_ku-pane-bg);box-shadow:var(--_ku-pane-ring)}
2662
+ .knobs-split[data-direction="row"]>.knobs-pane>.knobs-pane-rail{top:0;bottom:0;width:var(--_ku-rail);writing-mode:vertical-rl;padding:10px 0}
1083
2663
  .knobs-split[data-direction="row"]>.knobs-pane[data-edge="start"]>.knobs-pane-rail{right:0}
1084
2664
  .knobs-split[data-direction="row"]>.knobs-pane[data-edge="end"]>.knobs-pane-rail{left:0}
1085
- .knobs-split[data-direction="column"]>.knobs-pane>.knobs-pane-rail{left:0;right:0;height:var(--ku-rail);padding:0 var(--ku-inset)}
2665
+ .knobs-split[data-direction="column"]>.knobs-pane>.knobs-pane-rail{left:0;right:0;height:var(--_ku-rail);padding:0 var(--_k-inset)}
1086
2666
  .knobs-split[data-direction="column"]>.knobs-pane[data-edge="start"]>.knobs-pane-rail{bottom:0}
1087
2667
  .knobs-split[data-direction="column"]>.knobs-pane[data-edge="end"]>.knobs-pane-rail{top:0}
1088
2668
  .knobs-pane[data-collapsed]>.knobs-pane-rail{pointer-events:auto}
1089
2669
  /* Its hover wash fades, rather than going in one frame as a click opens the pane. */
1090
- .knobs-ui .knobs-pane-rail::before{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--ku-wash);opacity:0;transition:opacity .15s;pointer-events:none}
2670
+ .knobs-ui .knobs-pane-rail::before{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--_ku-wash);opacity:0;transition:opacity .15s;pointer-events:none}
1091
2671
  .knobs-pane-rail>*{position:relative}
1092
- .knobs-ui .knobs-pane[data-collapsed]>.knobs-pane-rail:is(:hover,:focus-visible){color:var(--ku-text)}
2672
+ .knobs-ui .knobs-pane[data-collapsed]>.knobs-pane-rail:is(:hover,:focus-visible){color:var(--_k-fg)}
1093
2673
  .knobs-ui .knobs-pane[data-collapsed]>.knobs-pane-rail:is(:hover,:focus-visible)::before{opacity:1}
1094
2674
  .knobs-pane-rail-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
1095
- .knobs-pane-chevron{display:flex;flex:none;width:11px;height:11px;writing-mode:horizontal-tb;color:var(--ku-dim)}
2675
+ .knobs-pane-chevron{display:flex;flex:none;width:11px;height:11px;writing-mode:horizontal-tb;color:var(--_k-fg-3)}
1096
2676
  .knobs-pane-turn{display:flex;width:100%;height:100%;transform-origin:50% 50%}
1097
2677
  .knobs-pane-rail svg{width:11px;height:11px}
1098
2678
  /* The rail's chevron stands in for the header's collapse icon (it turns into the rail's), so the
@@ -1100,26 +2680,26 @@ var init_look = __esm(() => {
1100
2680
  .knobs-pane[data-morph]>.knobs-pane-clip>.knobs-pane-inner>.knobs-pane-head>.knobs-pane-collapse>svg{visibility:hidden}
1101
2681
  /* So does the rail's label for the title, when it travels (split's fold: { title: "travel" }). */
1102
2682
  .knobs-pane[data-travel]>.knobs-pane-clip>.knobs-pane-inner>.knobs-pane-head>.knobs-pane-title{visibility:hidden}
1103
- .knobs-pane[data-morph]:not([data-collapsed]):has(>.knobs-pane-clip>.knobs-pane-inner>.knobs-pane-head>.knobs-pane-collapse:is(:hover,:focus-visible))>.knobs-pane-rail .knobs-pane-chevron{color:var(--ku-text)}
2683
+ .knobs-pane[data-morph]:not([data-collapsed]):has(>.knobs-pane-clip>.knobs-pane-inner>.knobs-pane-head>.knobs-pane-collapse:is(:hover,:focus-visible))>.knobs-pane-rail .knobs-pane-chevron{color:var(--_k-fg)}
1104
2684
  .knobs-pane[data-morph]:not([data-collapsed])>.knobs-pane-rail .knobs-pane-chevron{transition:color .15s}
1105
2685
 
1106
- .knobs-divider{position:relative;z-index:2;flex:none;width:1px;background:var(--ku-divider);touch-action:none;outline:none}
2686
+ .knobs-divider{position:relative;z-index:2;flex:none;width:1px;background:var(--_ku-divider);touch-action:none;outline:none}
1107
2687
  .knobs-split[data-direction="column"]>.knobs-divider{width:auto;height:1px}
1108
- .knobs-divider::before{content:"";position:absolute;top:0;bottom:0;left:calc(50% - var(--ku-hit) / 2);width:var(--ku-hit);cursor:col-resize}
1109
- .knobs-split[data-direction="column"]>.knobs-divider::before{left:0;right:0;top:calc(50% - var(--ku-hit) / 2);bottom:auto;width:auto;height:var(--ku-hit);cursor:row-resize}
2688
+ .knobs-divider::before{content:"";position:absolute;top:0;bottom:0;left:calc(50% - var(--_ku-hit) / 2);width:var(--_ku-hit);cursor:col-resize}
2689
+ .knobs-split[data-direction="column"]>.knobs-divider::before{left:0;right:0;top:calc(50% - var(--_ku-hit) / 2);bottom:auto;width:auto;height:var(--_ku-hit);cursor:row-resize}
1110
2690
  /* Hover, focus and drags draw the hairline in the accent, with a soft wash beside it. */
1111
- .knobs-divider::after{content:"";position:absolute;inset:0 -1px;background:var(--ku-accent);opacity:0;pointer-events:none;
1112
- box-shadow:0 0 0 2px color-mix(in srgb,var(--ku-accent) 18%,transparent);transition:opacity .16s}
2691
+ .knobs-divider::after{content:"";position:absolute;inset:0 -1px;background:var(--_k-accent);opacity:0;pointer-events:none;
2692
+ box-shadow:0 0 0 2px color-mix(in srgb,var(--_k-accent) 18%,transparent);transition:opacity .16s}
1113
2693
  .knobs-split[data-direction="column"]>.knobs-divider::after{inset:-1px 0}
1114
2694
  .knobs-divider:hover::after{opacity:.7;transition-delay:.12s}
1115
2695
  .knobs-divider:focus-visible::after,.knobs-divider[data-active]::after{opacity:1;transition-delay:0s}
1116
2696
  /* Between cards, the hairline gives way to a grip: a small capsule in the gap that shows on
1117
2697
  hover, and lengthens and takes the accent while dragged or focused. */
1118
- .knobs-split:not([data-frame="flat"])>.knobs-divider::after{inset:auto;left:50%;top:50%;width:4px;height:28px;margin:-14px 0 0 -2px;border-radius:2px;background:var(--ku-line-hi);box-shadow:none;
1119
- transition:opacity .16s,background .16s,scale var(--ku-ease-ms) var(--ku-ease)}
2698
+ .knobs-split:not([data-frame="flat"])>.knobs-divider::after{inset:auto;left:50%;top:50%;width:4px;height:28px;margin:-14px 0 0 -2px;border-radius:2px;background:var(--_k-border-strong);box-shadow:none;
2699
+ transition:opacity .16s,background .16s,scale var(--_ku-ease-ms) var(--_ku-ease)}
1120
2700
  .knobs-split[data-direction="column"]:not([data-frame="flat"])>.knobs-divider::after{inset:auto;left:50%;top:50%;width:28px;height:4px;margin:-2px 0 0 -14px}
1121
2701
  .knobs-split:not([data-frame="flat"])>.knobs-divider:hover::after{opacity:1}
1122
- .knobs-split:not([data-frame="flat"])>.knobs-divider:is(:focus-visible,[data-active])::after{background:var(--ku-accent);opacity:.9;scale:1 1.45}
2702
+ .knobs-split:not([data-frame="flat"])>.knobs-divider:is(:focus-visible,[data-active])::after{background:var(--_k-accent);opacity:.9;scale:1 1.45}
1123
2703
  .knobs-split[data-direction="column"]:not([data-frame="flat"])>.knobs-divider:is(:focus-visible,[data-active])::after{scale:1.45 1}
1124
2704
  :root[data-knobs-resizing],:root[data-knobs-resizing] *{user-select:none!important;-webkit-user-select:none!important}
1125
2705
  :root[data-knobs-resizing="row"] *{cursor:col-resize!important}
@@ -1129,112 +2709,124 @@ var init_look = __esm(() => {
1129
2709
  /* Tree: one scroller, rows placed by transform, only those near the view in the DOM. */
1130
2710
  .knobs-tree{position:relative;overflow:auto;height:100%;outline:none;scrollbar-width:none;overscroll-behavior:contain;user-select:none;-webkit-user-select:none}
1131
2711
  .knobs-tree-space{position:relative;width:100%;pointer-events:none}
1132
- .knobs-tree-row{position:absolute;left:var(--ku-row-x);right:var(--ku-row-x);top:0;display:flex;align-items:center;height:var(--ku-row);padding-right:calc(var(--ku-inset) - 4px);
1133
- color:var(--ku-text);white-space:nowrap;cursor:default;will-change:transform;contain:layout style}
1134
- .knobs-tree-row::before{content:"";position:absolute;inset:0;border-radius:var(--ku-row-radius);background:var(--ku-wash);opacity:0;transition:opacity calc(var(--ku-hover-out) * 1ms),background .12s;pointer-events:none}
1135
- .knobs-tree:not([data-keyboard]):not([data-dragging]) .knobs-tree-row:hover::before{opacity:1;transition-duration:calc(var(--ku-hover-in) * 1ms)}
1136
- .knobs-tree-row[aria-selected="true"]::before{opacity:1;background:var(--ku-select)}
1137
- .knobs-tree:focus-visible .knobs-tree-row[data-active]::before,.knobs-tree[data-keyboard]:focus .knobs-tree-row[data-active]::before{opacity:1;background:var(--ku-wash-hi)}
1138
- .knobs-tree:focus .knobs-tree-row[data-active][aria-selected="true"]::before{background:var(--ku-select-focus)}
1139
- .knobs-tree-row[data-drop="into"]::before{opacity:1;background:color-mix(in srgb,var(--ku-accent) 30%,transparent)}
2712
+ .knobs-tree-row{position:absolute;left:var(--_ku-row-x);right:var(--_ku-row-x);top:0;display:flex;align-items:center;height:var(--_k-row);padding-right:calc(var(--_k-inset) - 4px);
2713
+ color:var(--_k-fg);white-space:nowrap;cursor:default;will-change:transform;contain:layout style}
2714
+ .knobs-tree-row::before{content:"";position:absolute;inset:0;border-radius:var(--_ku-row-radius);background:var(--_ku-wash);opacity:0;transition:opacity calc(var(--_k-hover-out) * 1ms),background .12s;pointer-events:none}
2715
+ .knobs-tree:not([data-keyboard]):not([data-dragging]) .knobs-tree-row:hover::before{opacity:1;transition-duration:calc(var(--_k-hover-in) * 1ms)}
2716
+ .knobs-tree-row[aria-selected="true"]::before{opacity:1;background:var(--_ku-select)}
2717
+ .knobs-tree:focus-visible .knobs-tree-row[data-active]::before,.knobs-tree[data-keyboard]:focus .knobs-tree-row[data-active]::before{opacity:1;background:var(--_ku-wash-hi)}
2718
+ .knobs-tree:focus .knobs-tree-row[data-active][aria-selected="true"]::before{background:var(--_ku-select-focus)}
2719
+ .knobs-tree-row[data-drop="into"]::before{opacity:1;background:color-mix(in srgb,var(--_k-accent) 30%,transparent)}
1140
2720
  .knobs-tree-row[data-dragged]{opacity:.38}
1141
2721
  /* glide: one highlight under the selected row that glides between rows (the row's own stays off). */
1142
- .knobs-tree-cursor{position:absolute;left:var(--ku-row-x);right:var(--ku-row-x);top:0;height:var(--ku-row);border-radius:var(--ku-row-radius);background:var(--ku-select);
2722
+ .knobs-tree-cursor{position:absolute;left:var(--_ku-row-x);right:var(--_ku-row-x);top:0;height:var(--_k-row);border-radius:var(--_ku-row-radius);background:var(--_ku-select);
1143
2723
  opacity:0;pointer-events:none;will-change:transform;transition:opacity .15s ease-out,background .12s}
1144
2724
  .knobs-tree-cursor[data-on]{opacity:1}
1145
- .knobs-tree:focus .knobs-tree-cursor{background:var(--ku-select-focus)}
2725
+ .knobs-tree:focus .knobs-tree-cursor{background:var(--_ku-select-focus)}
1146
2726
  .knobs-tree[data-glide] .knobs-tree-row[aria-selected="true"]::before{opacity:0!important}
1147
2727
  .knobs-tree-row>*{position:relative}
1148
- .knobs-tree-caret{flex:none;display:flex;align-items:center;justify-content:center;width:16px;height:100%;color:var(--ku-dim);transition:transform var(--ku-ease-ms) var(--ku-ease)}
2728
+ .knobs-tree-caret{flex:none;display:flex;align-items:center;justify-content:center;width:16px;height:100%;color:var(--_k-fg-3);transition:transform var(--_ku-ease-ms) var(--_ku-ease)}
1149
2729
  .knobs-tree-caret svg{width:9px;height:9px}
1150
2730
  .knobs-tree-row[aria-expanded="true"]>.knobs-tree-caret{transform:rotate(90deg)}
1151
2731
  .knobs-tree-row:not([aria-expanded])>.knobs-tree-caret{visibility:hidden}
1152
- .knobs-tree-icon{flex:none;display:flex;align-items:center;justify-content:center;width:14px;margin-right:6px;color:var(--ku-dim);font-size:calc(var(--ku-font-size) - 1px)}
1153
- .knobs-tree-label{position:relative;flex:1;min-width:0;overflow:hidden;font-weight:var(--ku-font-weight)}
1154
- .knobs-tree-row[data-ancestor] .knobs-tree-label{color:var(--ku-label)}
1155
- .knobs-tree-label .knobs-tree-mark{color:var(--ku-accent)}
2732
+ .knobs-tree-icon{flex:none;display:flex;align-items:center;justify-content:center;width:14px;margin-right:6px;color:var(--_k-fg-3);font-size:calc(var(--_k-font-size) - 1px)}
2733
+ .knobs-tree-label{position:relative;flex:1;min-width:0;overflow:hidden;font-weight:var(--_k-weight)}
2734
+ .knobs-tree-row[data-ancestor] .knobs-tree-label{color:var(--_k-fg-2)}
2735
+ .knobs-tree-label .knobs-tree-mark{color:var(--_k-accent)}
1156
2736
  .knobs-tree-row[data-off~="visible"] :is(.knobs-tree-label,.knobs-tree-icon){opacity:.45}
1157
- .knobs-tree-row[data-off~="locked"] .knobs-tree-label{color:var(--ku-label)}
1158
- .knobs-tree-detail{flex:none;margin-left:6px;color:var(--ku-dim);font-variant-numeric:tabular-nums}
2737
+ .knobs-tree-row[data-off~="locked"] .knobs-tree-label{color:var(--_k-fg-2)}
2738
+ .knobs-tree-detail{flex:none;margin-left:6px;color:var(--_k-fg-3);font-variant-numeric:tabular-nums}
1159
2739
  .knobs-tree-tools{flex:none;display:flex;align-items:center;gap:1px;margin-left:4px}
1160
- .knobs-ui .knobs-tree-toggle{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:calc(var(--ku-radius) * 999);color:var(--ku-dim);cursor:pointer;opacity:0;transition:opacity .12s,color .12s,background .12s}
2740
+ .knobs-ui .knobs-tree-toggle{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:calc(var(--_k-radius) * 999);color:var(--_k-fg-3);cursor:pointer;opacity:0;transition:opacity .12s,color .12s,background .12s}
1161
2741
  .knobs-ui .knobs-tree-toggle svg{width:12px;height:12px}
1162
2742
  .knobs-tree-row:is(:hover,[data-active],[aria-selected="true"]) .knobs-tree-toggle,.knobs-ui .knobs-tree-toggle[aria-pressed="false"]{opacity:1}
1163
- .knobs-ui .knobs-tree-toggle:hover{background:var(--ku-wash-hi);color:var(--ku-text)}
1164
- .knobs-ui .knobs-tree-toggle[aria-pressed="false"]{color:var(--ku-label)}
2743
+ .knobs-ui .knobs-tree-toggle:hover{background:var(--_ku-wash-hi);color:var(--_k-fg)}
2744
+ .knobs-ui .knobs-tree-toggle[aria-pressed="false"]{color:var(--_k-fg-2)}
1165
2745
  /* Renaming in place, as a number is edited in a panel: no box, just the text and an underline. */
1166
- .knobs-ui .knobs-tree-edit{position:absolute;inset:auto 0 auto 0;top:50%;transform:translateY(-50%);width:100%;height:calc(var(--ku-font-size) * 1.5);padding:0;
1167
- background:transparent;color:var(--ku-text);caret-color:var(--ku-accent);font:inherit;font-weight:var(--ku-font-weight);border-bottom:1px solid var(--ku-text)}
1168
- .knobs-tree-edit::selection{background:color-mix(in srgb,var(--ku-accent) 40%,transparent)}
2746
+ .knobs-ui .knobs-tree-edit{position:absolute;inset:auto 0 auto 0;top:50%;transform:translateY(-50%);width:100%;height:calc(var(--_k-font-size) * 1.5);padding:0;
2747
+ background:transparent;color:var(--_k-fg);caret-color:var(--_k-accent);font:inherit;font-weight:var(--_k-weight);border-bottom:1px solid var(--_k-fg)}
2748
+ .knobs-tree-edit::selection{background:color-mix(in srgb,var(--_k-accent) 40%,transparent)}
1169
2749
  .knobs-tree-row[data-editing] .knobs-tree-text{visibility:hidden}
1170
- .knobs-tree-line{position:absolute;left:0;right:6px;top:0;height:2px;margin-top:-1px;border-radius:1px;background:var(--ku-accent);pointer-events:none;opacity:0;transition:opacity .1s}
1171
- .knobs-tree-line::before{content:"";position:absolute;left:-3px;top:-2px;width:6px;height:6px;border-radius:50%;box-shadow:inset 0 0 0 2px var(--ku-accent)}
2750
+ .knobs-tree-line{position:absolute;left:0;right:6px;top:0;height:2px;margin-top:-1px;border-radius:1px;background:var(--_k-accent);pointer-events:none;opacity:0;transition:opacity .1s}
2751
+ .knobs-tree-line::before{content:"";position:absolute;left:-3px;top:-2px;width:6px;height:6px;border-radius:50%;box-shadow:inset 0 0 0 2px var(--_k-accent)}
1172
2752
  .knobs-tree[data-dragging] .knobs-tree-line[data-shown]{opacity:1}
1173
- .knobs-tree-ghost{position:fixed;left:0;top:0;z-index:2147480004;padding:2px 8px;background:var(--ku-bg);color:var(--ku-text);border-radius:var(--ku-radius);
1174
- box-shadow:0 0 0 1px var(--ku-line-hi),0 6px 18px rgba(0,0,0,.35);pointer-events:none;white-space:nowrap;font:var(--ku-font-weight) var(--ku-font-size)/1.6 var(--ku-font)}
1175
- .knobs-tree-empty{padding:10px var(--ku-inset);color:var(--ku-dim)}
2753
+ .knobs-tree-ghost{position:fixed;left:0;top:0;z-index:2147480004;padding:2px 8px;background:var(--_k-bg);color:var(--_k-fg);border-radius:var(--_k-radius);
2754
+ box-shadow:0 0 0 1px var(--_k-border-strong),0 6px 18px rgba(0,0,0,calc(.35 * var(--_k-shadow-k,1)));pointer-events:none;white-space:nowrap;font:var(--_k-weight) var(--_k-font-size)/1.6 var(--_k-font)}
2755
+ .knobs-tree-empty{padding:10px var(--_k-inset);color:var(--_k-fg-3)}
1176
2756
 
1177
2757
  /* Timeline: a transport (play, the time) beside a track: the ruler's canvas over a lane of
1178
2758
  markers, ranges as soft bands, and the playhead, a hairline in the accent with a cap. */
1179
2759
  :where(.knobs-timeline,.knobs-timeline *){box-sizing:border-box}
1180
- .knobs-ui.knobs-timeline{display:flex;align-items:stretch;gap:10px;width:100%;height:100%;min-height:52px;padding:6px var(--ku-inset) 8px 8px;outline:none;user-select:none;-webkit-user-select:none;
1181
- font:var(--ku-font-weight) var(--ku-font-size)/1.35 var(--ku-font);color:var(--ku-text);letter-spacing:normal;text-align:left}
2760
+ .knobs-ui.knobs-timeline{display:flex;align-items:stretch;gap:10px;width:100%;height:100%;min-height:52px;padding:6px var(--_k-inset) 8px 8px;outline:none;user-select:none;-webkit-user-select:none;
2761
+ font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);letter-spacing:normal;text-align:left}
1182
2762
  :where(.knobs-ui) :is(.knobs-tl-play,.knobs-tl-edit){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;margin:0;padding:0;outline:none;box-shadow:none}
1183
2763
  .knobs-tl-transport{flex:none;display:flex;align-items:center;gap:8px;min-width:96px}
1184
- .knobs-ui .knobs-tl-play{flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--ku-control-h);height:var(--ku-control-h);min-width:22px;min-height:22px;border-radius:calc(var(--ku-radius) * 999);
1185
- background:var(--ku-surface-hi);color:var(--ku-text);cursor:pointer;transition:background .15s,transform .15s var(--ku-ease)}
1186
- .knobs-ui .knobs-tl-play:hover{background:color-mix(in srgb,var(--ku-text) 16%,transparent)}
2764
+ .knobs-ui .knobs-tl-play{flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--_k-control-h);height:var(--_k-control-h);min-width:22px;min-height:22px;border-radius:calc(var(--_k-radius) * 999);
2765
+ background:var(--_k-fill-selected);color:var(--_k-fg);cursor:pointer;transition:background .15s,transform .15s var(--_ku-ease)}
2766
+ .knobs-ui .knobs-tl-play:hover{background:color-mix(in srgb,var(--_k-fg) 16%,transparent)}
1187
2767
  .knobs-ui .knobs-tl-play:active{transform:scale(.94)}
1188
2768
  .knobs-tl-play svg{width:12px;height:12px}
1189
- .knobs-timeline[data-playing] .knobs-tl-play{background:var(--ku-accent);color:var(--ku-bg)}
2769
+ .knobs-timeline[data-playing] .knobs-tl-play{background:var(--_k-accent);color:var(--_k-bg)}
1190
2770
  .knobs-tl-time{display:flex;flex-direction:column;line-height:1.2;font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
1191
- .knobs-tl-now{font:var(--ku-font-weight) var(--ku-value-size)/1.2 var(--ku-value-font);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";color:var(--ku-text);white-space:nowrap}
1192
- .knobs-tl-sub{font-size:var(--ku-text-meta);color:var(--ku-dim);white-space:nowrap}
1193
- .knobs-tl-track{position:relative;flex:1;min-width:0;overflow:hidden;border-radius:var(--ku-radius);background:var(--ku-surface);cursor:col-resize;touch-action:none;
1194
- transition:background calc(var(--ku-hover-out) * 1ms)}
1195
- .knobs-timeline:focus-visible .knobs-tl-track,.knobs-timeline[data-keyboard]:focus .knobs-tl-track{background:color-mix(in srgb,var(--ku-surface-hi) 80%,transparent)}
2771
+ .knobs-tl-now{font:var(--_k-weight) var(--_k-value-size)/1.2 var(--_k-value-font);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";color:var(--_k-fg);white-space:nowrap}
2772
+ .knobs-tl-sub{font-size:var(--_k-text-meta);color:var(--_k-fg-3);white-space:nowrap}
2773
+ .knobs-tl-track{position:relative;flex:1;min-width:0;overflow:hidden;border-radius:var(--_k-radius);background:var(--_k-fill);cursor:col-resize;touch-action:none;
2774
+ transition:background calc(var(--_k-hover-out) * 1ms)}
2775
+ .knobs-timeline:focus-visible .knobs-tl-track,.knobs-timeline[data-keyboard]:focus .knobs-tl-track{background:color-mix(in srgb,var(--_k-fill-selected) 80%,transparent)}
1196
2776
  .knobs-tl-ruler{position:absolute;left:0;top:0;height:22px;pointer-events:none}
1197
2777
  .knobs-tl-lane{position:absolute;left:0;right:0;top:22px;bottom:0;pointer-events:none}
1198
2778
  /* Ranges: a soft band through the lane, its edges handles; the loop range in the accent. */
1199
- .knobs-tl-range{position:absolute;left:0;top:0;bottom:0;width:0;background:color-mix(in srgb,var(--ku-text) 6%,transparent);will-change:transform}
1200
- .knobs-tl-range[data-loop]{background:color-mix(in srgb,var(--ku-accent) 11%,transparent)}
1201
- .knobs-tl-range[data-selected]{background:color-mix(in srgb,var(--ku-accent) 18%,transparent)}
2779
+ .knobs-tl-range{position:absolute;left:0;top:0;bottom:0;width:0;background:color-mix(in srgb,var(--_k-fg) 6%,transparent);will-change:transform}
2780
+ .knobs-tl-range[data-loop]{background:color-mix(in srgb,var(--_k-accent) 11%,transparent)}
2781
+ .knobs-tl-range[data-selected]{background:color-mix(in srgb,var(--_k-accent) 18%,transparent)}
1202
2782
  .knobs-tl-edge{position:absolute;top:0;bottom:0;width:9px;cursor:ew-resize}
1203
2783
  .knobs-tl-edge[data-edge="start"]{left:-4px}
1204
2784
  .knobs-tl-edge[data-edge="end"]{right:-5px}
1205
- .knobs-tl-edge::after{content:"";position:absolute;top:0;bottom:0;left:4px;width:1px;background:color-mix(in srgb,var(--ku-accent) 55%,transparent);transition:background .15s,box-shadow .15s}
1206
- .knobs-tl-edge:hover::after,.knobs-tl-range[data-selected] .knobs-tl-edge::after{background:var(--ku-accent);box-shadow:0 0 0 1px color-mix(in srgb,var(--ku-accent) 22%,transparent)}
1207
- .knobs-tl-rlabel{position:absolute;left:5px;bottom:3px;padding:0 5px;border-radius:max(0px,calc(var(--ku-radius) - 3px));font-size:var(--ku-text-meta);line-height:16px;color:var(--ku-label);cursor:grab;white-space:nowrap}
2785
+ .knobs-tl-edge::after{content:"";position:absolute;top:0;bottom:0;left:4px;width:1px;background:color-mix(in srgb,var(--_k-accent) 55%,transparent);transition:background .15s,box-shadow .15s}
2786
+ .knobs-tl-edge:hover::after,.knobs-tl-range[data-selected] .knobs-tl-edge::after{background:var(--_k-accent);box-shadow:0 0 0 1px color-mix(in srgb,var(--_k-accent) 22%,transparent)}
2787
+ .knobs-tl-rlabel{position:absolute;left:5px;bottom:3px;padding:0 5px;border-radius:max(0px,calc(var(--_k-radius) - 3px));font-size:var(--_k-text-meta);line-height:16px;color:var(--_k-fg-2);cursor:grab;white-space:nowrap}
1208
2788
  .knobs-tl-rlabel:empty{display:none}
1209
- .knobs-tl-rlabel:hover{background:var(--ku-wash-hi);color:var(--ku-text)}
2789
+ .knobs-tl-rlabel:hover{background:var(--_ku-wash-hi);color:var(--_k-fg)}
1210
2790
  /* Markers: a diamond on the ruler's edge and a label chip below it. */
1211
- .knobs-tl-marker{position:absolute;left:0;top:-22px;bottom:0;width:0;will-change:transform;pointer-events:none;--knobs-tl-c:var(--knobs-tl-color,var(--ku-label))}
2791
+ .knobs-tl-marker{position:absolute;left:0;top:-22px;bottom:0;width:0;will-change:transform;pointer-events:none;--knobs-tl-c:var(--knobs-tl-color,var(--_k-fg-2))}
1212
2792
  .knobs-tl-marker::before{content:"";position:absolute;top:22px;bottom:0;left:-.5px;width:1px;background:color-mix(in srgb,var(--knobs-tl-c) 40%,transparent)}
1213
2793
  .knobs-tl-pin{position:absolute;top:13px;left:-5px;width:10px;height:10px;pointer-events:auto;cursor:grab}
1214
- .knobs-tl-pin::after{content:"";position:absolute;inset:1.5px;border-radius:min(2px,var(--ku-radius));background:var(--knobs-tl-c);rotate:45deg;transition:background .15s,scale .2s var(--ku-ease)}
1215
- .knobs-tl-mlabel{position:absolute;top:26px;left:3px;max-width:140px;padding:0 6px;border-radius:max(0px,calc(var(--ku-radius) - 3px));background:var(--ku-surface-hi);color:var(--ku-text);
1216
- font-size:var(--ku-text-meta);line-height:17px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:auto;cursor:grab;transition:background .15s,color .15s}
1217
- .knobs-tl-marker[data-selected]{--knobs-tl-c:var(--ku-accent)}
1218
- .knobs-tl-marker[data-selected] .knobs-tl-mlabel{background:color-mix(in srgb,var(--ku-accent) 24%,var(--ku-surface-hi))}
2794
+ .knobs-tl-pin::after{content:"";position:absolute;inset:1.5px;border-radius:min(2px,var(--_k-radius));background:var(--knobs-tl-c);rotate:45deg;transition:background .15s,scale .2s var(--_ku-ease)}
2795
+ .knobs-tl-mlabel{position:absolute;top:26px;left:3px;max-width:140px;padding:0 6px;border-radius:max(0px,calc(var(--_k-radius) - 3px));background:var(--_k-fill-selected);color:var(--_k-fg);
2796
+ font-size:var(--_k-text-meta);line-height:17px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:auto;cursor:grab;transition:background .15s,color .15s}
2797
+ .knobs-tl-marker[data-selected]{--knobs-tl-c:var(--_k-accent)}
2798
+ .knobs-tl-marker[data-selected] .knobs-tl-mlabel{background:color-mix(in srgb,var(--_k-accent) 24%,var(--_k-fill-selected))}
1219
2799
  .knobs-tl-marker[data-selected] .knobs-tl-pin::after{scale:1.2}
1220
2800
  .knobs-timeline[data-dragging] .knobs-tl-marker[data-selected] :is(.knobs-tl-pin,.knobs-tl-mlabel){cursor:grabbing}
1221
2801
  .knobs-tl-marker[data-editing] .knobs-tl-mlabel{visibility:hidden}
1222
- .knobs-ui .knobs-tl-edit{position:absolute;top:26px;left:3px;width:120px;height:17px;padding:0 6px;font-size:var(--ku-text-meta);color:var(--ku-text);caret-color:var(--ku-accent);
1223
- background:var(--ku-bg);border-radius:max(0px,calc(var(--ku-radius) - 3px));box-shadow:inset 0 -1px 0 var(--ku-text);pointer-events:auto}
2802
+ .knobs-ui .knobs-tl-edit{position:absolute;top:26px;left:3px;width:120px;height:17px;padding:0 6px;font-size:var(--_k-text-meta);color:var(--_k-fg);caret-color:var(--_k-accent);
2803
+ background:var(--_k-bg);border-radius:max(0px,calc(var(--_k-radius) - 3px));box-shadow:inset 0 -1px 0 var(--_k-fg);pointer-events:auto}
1224
2804
  /* The playhead: an accent hairline with a rounded cap in the ruler; it glows a little while held
1225
2805
  on a marker. */
1226
2806
  .knobs-tl-head{position:absolute;left:0;top:0;bottom:0;width:0;will-change:transform;pointer-events:none}
1227
- .knobs-tl-head::before{content:"";position:absolute;top:4px;bottom:0;left:-.75px;width:1.5px;background:var(--ku-accent)}
1228
- .knobs-tl-head::after{content:"";position:absolute;top:3px;left:-4.5px;width:9px;height:13px;border-radius:min(4.5px,var(--ku-radius)) min(4.5px,var(--ku-radius)) min(4.5px,var(--ku-radius)) min(4.5px,var(--ku-radius));
1229
- background:var(--ku-accent);box-shadow:0 1px 3px rgba(0,0,0,calc(.3 * var(--k-lift,1)));transition:box-shadow .15s,scale .18s var(--ku-ease)}
2807
+ .knobs-tl-head::before{content:"";position:absolute;top:4px;bottom:0;left:-.75px;width:1.5px;background:var(--_k-accent)}
2808
+ .knobs-tl-head::after{content:"";position:absolute;top:3px;left:-4.5px;width:9px;height:13px;border-radius:min(4.5px,var(--_k-radius)) min(4.5px,var(--_k-radius)) min(4.5px,var(--_k-radius)) min(4.5px,var(--_k-radius));
2809
+ background:var(--_k-accent);box-shadow:0 1px 3px rgba(0,0,0,calc(.3 * var(--k-lift,1)));transition:box-shadow .15s,scale .18s var(--_ku-ease)}
1230
2810
  .knobs-timeline[data-scrubbing] .knobs-tl-head::after{scale:1.12}
1231
- .knobs-timeline[data-stuck] .knobs-tl-head::after{box-shadow:0 0 0 3px color-mix(in srgb,var(--ku-accent) 26%,transparent)}
1232
- .knobs-tl-hover{position:absolute;left:0;top:0;bottom:0;width:1px;margin-left:-.5px;background:var(--ku-line-hi);transform:translateX(-100px);pointer-events:none;opacity:0;transition:opacity .15s}
2811
+ .knobs-timeline[data-stuck] .knobs-tl-head::after{box-shadow:0 0 0 3px color-mix(in srgb,var(--_k-accent) 26%,transparent)}
2812
+ .knobs-tl-hover{position:absolute;left:0;top:0;bottom:0;width:1px;margin-left:-.5px;background:var(--_k-border-strong);transform:translateX(-100px);pointer-events:none;opacity:0;transition:opacity .15s}
1233
2813
  .knobs-tl-track:hover .knobs-tl-hover{opacity:1}
1234
2814
  .knobs-timeline[data-scrubbing] .knobs-tl-hover{opacity:0}
1235
2815
  @media(prefers-reduced-motion:reduce){.knobs-timeline :where(*,::before,::after){transition:none!important}}
1236
2816
  @media(prefers-reduced-motion:reduce){:is(.knobs-tree,.knobs-split>.knobs-divider,.knobs-pane-head,.knobs-pane-rail) :where(*,::before,::after){transition:none!important}}
1237
- `;
2817
+ `, uiCss = () => aliased(css2 + readoutCss + overlayCss + bentoCss + activityCss + pickerCss + compareCss) + rolling_css_default, lookDefaults, tune = (s, m) => {
2818
+ s.omega = m.omega;
2819
+ s.zeta = m.zeta;
2820
+ return s;
2821
+ }, svg = (body, box = 16) => `<svg viewBox="0 0 ${box} ${box}" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`, ICONS;
2822
+ var init_look = __esm(() => {
2823
+ init_appearance();
2824
+ init_activity_css();
2825
+ init_picker_css();
2826
+ init_root();
2827
+ init_glide();
2828
+ init_motion();
2829
+ init_keys();
1238
2830
  lookDefaults = { current: {} };
1239
2831
  ICONS = {
1240
2832
  caret: svg('<path d="M6 3.5 10.5 8 6 12.5"/>'),
@@ -1338,73 +2930,73 @@ var storageKey = (id, part) => `knobs:${encodeURIComponent(id)}:${part}:v1`;
1338
2930
  // src/ui/diff-css.ts
1339
2931
  var snappy2, diffCss;
1340
2932
  var init_diff_css = __esm(() => {
1341
- snappy2 = springCss({ duration: 0.25, bounce: 0 });
2933
+ init_motion();
2934
+ snappy2 = springCss(SPRINGS.snappy);
1342
2935
  diffCss = `
1343
2936
  @property --kd-ft{syntax:"<length>";inherits:false;initial-value:0px}
1344
2937
  @property --kd-fb{syntax:"<length>";inherits:false;initial-value:0px}
1345
- :where(.knobs-ui){--kd-add:var(--k-diff-add,color-mix(in oklab,#3fb950 70%,var(--ku-text)));--kd-del:var(--k-diff-del,color-mix(in oklab,#f0524a 70%,var(--ku-text)));
1346
- --kd-mod:var(--k-diff-mod,color-mix(in oklab,#d29922 72%,var(--ku-text)));--kd-move:var(--k-diff-move,color-mix(in oklab,#58a6ff 68%,var(--ku-text)))}
2938
+ :where(.knobs-ui){--kd-add:var(--_k-diff-add);--kd-del:var(--_k-diff-del);--kd-mod:var(--_k-diff-mod);--kd-move:var(--k-diff-move,var(--_k-info))}
1347
2939
  :where(.knobs-diff,.knobs-diff *,.knobs-diff-files,.knobs-diff-files *){box-sizing:border-box}
1348
- .knobs-ui.knobs-diff{--kd-bg:var(--k-diff-bg,var(--ku-bg));--kd-solid:var(--kd-fill,var(--kd-bg));--kd-line:calc(var(--ku-font-size) * 1.5);
1349
- --kd-i:var(--k-diff-inset,8px);--kd-x:var(--kd-i);--kd-inner:max(3px,calc(var(--ku-pane-radius) - var(--kd-i)));--kd-ctl:var(--kd-inner);
1350
- --kd-head:calc(var(--ku-control-h) + 2 * var(--kd-i));--kd-fade:var(--k-diff-fade,20px);--kd-stick:0px;position:relative;display:flex;flex-direction:column;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;
1351
- background:var(--kd-bg);border-radius:var(--ku-pane-radius);font:var(--ku-font-weight) var(--ku-font-size)/1.35 var(--ku-font);color:var(--ku-text);text-align:left;
2940
+ .knobs-ui.knobs-diff{--kd-bg:var(--k-diff-bg,var(--_kd-bg,var(--_k-bg)));--kd-solid:var(--kd-fill,var(--kd-bg));--kd-line:calc(var(--_k-font-size) * 1.5);
2941
+ --kd-i:var(--k-diff-inset,8px);--kd-x:var(--kd-i);--kd-inner:max(3px,calc(var(--_ku-pane-radius) - var(--kd-i)));--kd-ctl:var(--kd-inner);
2942
+ --kd-head:calc(var(--_k-control-h) + 2 * var(--kd-i));--kd-fade:var(--k-diff-fade,20px);--kd-stick:0px;position:relative;display:flex;flex-direction:column;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;
2943
+ background:var(--kd-bg);border-radius:var(--_ku-pane-radius);font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);text-align:left;
1352
2944
  letter-spacing:normal;word-spacing:normal;text-transform:none;-webkit-font-smoothing:antialiased}
1353
2945
  .knobs-ui.knobs-diff[data-height="auto"]{height:auto}
1354
- .knobs-diff::after{content:"";position:absolute;inset:0;z-index:3;border-radius:inherit;box-shadow:var(--ku-pane-ring);pointer-events:none}
2946
+ .knobs-diff::after{content:"";position:absolute;inset:0;z-index:3;border-radius:inherit;box-shadow:var(--_ku-pane-ring);pointer-events:none}
1355
2947
  .knobs-diff [hidden],.knobs-diff-files [hidden]{display:none!important}
1356
2948
  .knobs-diff svg{display:block;flex:none}
1357
- .knobs-ui.knobs-diff[data-on="surface"]{--kd-x:0px;--kd-head:var(--ku-control-h);--kd-ctl:var(--ku-radius)}
2949
+ .knobs-ui.knobs-diff[data-on="surface"]{--kd-x:0px;--kd-head:var(--_k-control-h);--kd-ctl:var(--_k-radius)}
1358
2950
  /* The header's hairline shows only once the code has scrolled under it. */
1359
2951
  .knobs-diff-head{position:relative;z-index:1;flex:none;display:flex;align-items:center;gap:8px;height:var(--kd-head);padding:0 var(--kd-x);
1360
2952
  box-shadow:inset 0 -1px transparent;transition:box-shadow .15s;user-select:none;-webkit-user-select:none}
1361
- .knobs-diff[data-scrolled]>.knobs-diff-head{box-shadow:inset 0 -1px var(--ku-line)}
2953
+ .knobs-diff[data-scrolled]>.knobs-diff-head{box-shadow:inset 0 -1px var(--_k-border)}
1362
2954
  .knobs-diff-path{flex:0 1 auto;min-width:0;overflow:hidden;white-space:nowrap}
1363
- .knobs-diff-dir,.knobs-diff-from{color:var(--ku-dim)}
1364
- .knobs-diff-base{color:var(--ku-text);font-weight:var(--ku-title-weight)}
2955
+ .knobs-diff-dir,.knobs-diff-from{color:var(--_k-fg-3)}
2956
+ .knobs-diff-base{color:var(--_k-fg);font-weight:var(--_k-weight-title)}
1365
2957
  .knobs-diff-stat,.knobs-diff-counts{flex:none;display:inline-flex;gap:6px;font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
1366
- .knobs-diff-stat{font-size:var(--ku-text-meta);align-items:center}
2958
+ .knobs-diff-stat{font-size:var(--_k-text-meta);align-items:center}
1367
2959
  /* +/− as five squares, GitHub's way. */
1368
2960
  .knobs-diff-bar{display:inline-flex;gap:1px;margin-left:1px}
1369
- .knobs-diff-bar>i{width:6px;height:6px;border-radius:1.5px;background:color-mix(in srgb,var(--ku-text) 14%,transparent)}
2961
+ .knobs-diff-bar>i{width:6px;height:6px;border-radius:1.5px;background:color-mix(in srgb,var(--_k-fg) 14%,transparent)}
1370
2962
  .knobs-diff-bar>i[data-kind="add"]{background:var(--kd-add)}
1371
2963
  .knobs-diff-bar>i[data-kind="del"]{background:var(--kd-del)}
1372
2964
  .knobs-diff-add{color:var(--kd-add)}
1373
2965
  .knobs-diff-del{color:var(--kd-del)}
1374
2966
  .knobs-diff-counts>:empty{display:none}
1375
- .knobs-diff-status{font:600 calc(var(--ku-font-size) - 2px)/1 var(--ku-mono);color:var(--ku-dim)}
2967
+ .knobs-diff-status{font:600 calc(var(--_k-font-size) - 2px)/1 var(--_k-mono);color:var(--_k-fg-3)}
1376
2968
  .knobs-diff-status[data-change="change"]{color:var(--kd-mod)}
1377
2969
  .knobs-diff-status[data-change="new"]{color:var(--kd-add)}
1378
2970
  .knobs-diff-status[data-change="deleted"]{color:var(--kd-del)}
1379
2971
  .knobs-diff-status[data-change="rename"]{color:var(--kd-move)}
1380
2972
  .knobs-diff-fill{flex:1}
1381
- .knobs-diff-nav{flex:none;display:inline-flex;align-items:center;gap:1px;color:var(--ku-dim);font-size:var(--ku-text-meta);font-variant-numeric:tabular-nums}
2973
+ .knobs-diff-nav{flex:none;display:inline-flex;align-items:center;gap:1px;color:var(--_k-fg-3);font-size:var(--_k-text-meta);font-variant-numeric:tabular-nums}
1382
2974
  .knobs-diff-nav>span{min-width:3.6em;text-align:center}
1383
2975
  :where(.knobs-ui) :is(.knobs-diff-btn,.knobs-diff-seg>button,.knobs-diff-viewed,.knobs-diff-filter>input,.knobs-diff-filter>button){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;border-radius:0;
1384
2976
  margin:0;padding:0;min-width:0;box-shadow:none;outline:none}
1385
- .knobs-ui .knobs-diff-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:calc(var(--ku-radius) * 999);color:var(--ku-dim);cursor:pointer;
2977
+ .knobs-ui .knobs-diff-btn{flex:none;display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:calc(var(--_k-radius) * 999);color:var(--_k-fg-3);cursor:pointer;
1386
2978
  transition:background .15s,color .15s,opacity .15s}
1387
- .knobs-ui .knobs-diff-btn:is(:hover,:focus-visible){background:var(--ku-wash-hi);color:var(--ku-text)}
1388
- .knobs-ui .knobs-diff-btn[aria-pressed="true"]{color:var(--ku-text);background:var(--ku-wash)}
2979
+ .knobs-ui .knobs-diff-btn:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
2980
+ .knobs-ui .knobs-diff-btn[aria-pressed="true"]{color:var(--_k-fg);background:var(--_ku-wash)}
1389
2981
  .knobs-ui .knobs-diff-btn:disabled{opacity:.35;cursor:default;background:transparent}
1390
2982
  .knobs-diff-btn svg{width:13px;height:13px}
1391
2983
  /* Viewed: a check with its word, as on GitHub; the path dims once it's ticked. */
1392
- .knobs-ui .knobs-diff-viewed{flex:none;display:inline-flex;align-items:center;gap:5px;height:var(--ku-control-h);padding:0 8px 0 6px;border-radius:var(--kd-ctl);color:var(--ku-label);
1393
- font-size:var(--ku-text-meta);font-weight:var(--ku-label-weight);white-space:nowrap;cursor:pointer;transition:background .15s,color .15s}
1394
- .knobs-ui .knobs-diff-viewed:is(:hover,:focus-visible){background:var(--ku-wash-hi);color:var(--ku-text)}
1395
- .knobs-ui .knobs-diff-viewed[aria-pressed="true"]{color:var(--ku-text);background:var(--ku-wash)}
2984
+ .knobs-ui .knobs-diff-viewed{flex:none;display:inline-flex;align-items:center;gap:5px;height:var(--_k-control-h);padding:0 8px 0 6px;border-radius:var(--kd-ctl);color:var(--_k-fg-2);
2985
+ font-size:var(--_k-text-meta);font-weight:var(--_k-weight-label);white-space:nowrap;cursor:pointer;transition:background .15s,color .15s}
2986
+ .knobs-ui .knobs-diff-viewed:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
2987
+ .knobs-ui .knobs-diff-viewed[aria-pressed="true"]{color:var(--_k-fg);background:var(--_ku-wash)}
1396
2988
  .knobs-diff-viewed svg{width:13px;height:13px}
1397
2989
  .knobs-diff-viewed[aria-pressed="true"] svg{color:var(--kd-add)}
1398
2990
  .knobs-diff-path{transition:opacity .2s}
1399
2991
  .knobs-diff[data-viewed]>.knobs-diff-head .knobs-diff-path,.knobs-diff-part[data-viewed] .knobs-diff-path{opacity:.6}
1400
2992
  /* Split | Unified: one pill that glides between the two, raised as a panel's segments are (a
1401
2993
  lighter bg in dark, near white in light). */
1402
- .knobs-diff-seg{position:relative;flex:none;display:grid;grid-template-columns:1fr 1fr;height:var(--ku-control-h);padding:2px;border-radius:var(--kd-ctl);background:var(--ku-seg-bg)}
1403
- .knobs-ui .knobs-diff-seg>button{position:relative;z-index:1;padding:0 9px;border-radius:max(0px,calc(var(--kd-ctl) - 2px));color:var(--ku-label);font-size:var(--ku-text-meta);
1404
- font-weight:var(--ku-label-weight);white-space:nowrap;cursor:pointer;transition:color .15s}
1405
- .knobs-ui .knobs-diff-seg>button:is(:hover,:focus-visible),.knobs-ui .knobs-diff-seg>button[aria-checked="true"]{color:var(--ku-text)}
1406
- .knobs-diff-pill{position:absolute;top:2px;bottom:2px;left:2px;width:calc(50% - 2px);border-radius:max(0px,calc(var(--kd-ctl) - 2px));background:var(--k-pill-bg,color-mix(in oklab,var(--ku-bg) 88%,#fff));
1407
- box-shadow:0 1px 2px rgba(0,0,0,calc(.16 * var(--k-lift,1)));transition:transform var(--ku-ease-ms) var(--ku-ease)}
2994
+ .knobs-diff-seg{position:relative;flex:none;display:grid;grid-template-columns:1fr 1fr;height:var(--_k-control-h);padding:2px;border-radius:var(--kd-ctl);background:var(--_k-segmented-track)}
2995
+ .knobs-ui .knobs-diff-seg>button{position:relative;z-index:1;padding:0 9px;border-radius:max(0px,calc(var(--kd-ctl) - 2px));color:var(--_k-fg-2);font-size:var(--_k-text-meta);
2996
+ font-weight:var(--_k-weight-label);white-space:nowrap;cursor:pointer;transition:color .15s}
2997
+ .knobs-ui .knobs-diff-seg>button:is(:hover,:focus-visible),.knobs-ui .knobs-diff-seg>button[aria-checked="true"]{color:var(--_k-fg)}
2998
+ .knobs-diff-pill{position:absolute;top:2px;bottom:2px;left:2px;width:calc(50% - 2px);border-radius:max(0px,calc(var(--kd-ctl) - 2px));background:color-mix(in srgb,var(--_k-accent) 18%,var(--_k-segmented-active));
2999
+ box-shadow:0 1px 2px rgba(0,0,0,calc(.16 * var(--k-lift,1)));transition:transform var(--_ku-ease-ms) var(--_ku-ease)}
1408
3000
  .knobs-diff-seg[data-value="unified"]>.knobs-diff-pill{transform:translateX(100%)}
1409
3001
  .knobs-diff[data-frame="flat"] .knobs-diff-pill{box-shadow:none}
1410
3002
  /* The diff: one layer per file or layout on show, the old fading under the new. */
@@ -1425,30 +3017,30 @@ var init_diff_css = __esm(() => {
1425
3017
  .knobs-diff-scroll::-webkit-scrollbar{display:none;width:0;height:0}
1426
3018
  .knobs-diff-layer{position:absolute;inset:0;z-index:4;pointer-events:none;overflow:hidden}
1427
3019
  .knobs-diff-hbar{position:absolute;height:5px;pointer-events:none}
1428
- .knobs-diff-hbar>i{position:absolute;left:0;top:0;height:5px;border-radius:3px;background:color-mix(in srgb,var(--ku-text) 30%,transparent);opacity:0;pointer-events:none;
3020
+ .knobs-diff-hbar>i{position:absolute;left:0;top:0;height:5px;border-radius:3px;background:color-mix(in srgb,var(--_k-fg) 30%,transparent);opacity:0;pointer-events:none;
1429
3021
  transition:opacity .3s,background .15s}
1430
3022
  .knobs-diff-body:hover .knobs-diff-hbar>i,.knobs-diff-hbar:is([data-active],[data-dragging])>i{opacity:1;pointer-events:auto;transition-duration:.12s,.15s}
1431
- .knobs-diff-hbar>i:hover,.knobs-diff-hbar[data-dragging]>i{background:color-mix(in srgb,var(--ku-text) 48%,transparent)}
3023
+ .knobs-diff-hbar>i:hover,.knobs-diff-hbar[data-dragging]>i{background:color-mix(in srgb,var(--_k-fg) 48%,transparent)}
1432
3024
  /* stack: every file down one scroller, each header sticking until the next pushes it off. It's
1433
3025
  flush (square, no card around its file), opaque in the code's own colour, with a hairline
1434
3026
  under it only while it's stuck; a gap, not a line, parts one file from the next. */
1435
- .knobs-diff[data-stack]{--kd-stick:var(--ku-row)}
3027
+ .knobs-diff[data-stack]{--kd-stick:var(--_k-row)}
1436
3028
  .knobs-diff-part+.knobs-diff-part{margin-top:var(--kd-i)}
1437
- .knobs-diff-part-head{position:sticky;top:0;z-index:2;border-radius:0;display:flex;align-items:center;gap:8px;height:var(--ku-row);padding:0 var(--kd-x);background:var(--kd-solid);
3029
+ .knobs-diff-part-head{position:sticky;top:0;z-index:2;border-radius:0;display:flex;align-items:center;gap:8px;height:var(--_k-row);padding:0 var(--kd-x);background:var(--kd-solid);
1438
3030
  box-shadow:inset 0 0 transparent;transition:box-shadow .15s;user-select:none;-webkit-user-select:none}
1439
- .knobs-diff-part>.knobs-diff-part-head[data-stuck]{box-shadow:inset 0 -1px var(--ku-line)}
1440
- .knobs-diff-part-head .knobs-diff-counts{font-size:var(--ku-text-meta);align-items:center}
3031
+ .knobs-diff-part>.knobs-diff-part-head[data-stuck]{box-shadow:inset 0 -1px var(--_k-border)}
3032
+ .knobs-diff-part-head .knobs-diff-counts{font-size:var(--_k-text-meta);align-items:center}
1441
3033
  .knobs-diff-part-head .knobs-diff-status{flex:none;width:10px}
1442
- .knobs-diff-part-note{padding:var(--kd-i) var(--kd-x);color:var(--ku-dim)}
3034
+ .knobs-diff-part-note{padding:var(--kd-i) var(--kd-x);color:var(--_k-fg-3)}
1443
3035
  .knobs-diff[data-height="auto"] .knobs-diff-scroll{overscroll-behavior:auto}
1444
3036
  .knobs-diff-slot[data-leaving]{pointer-events:none}
1445
- .knobs-diff-note{position:absolute;inset:0;display:grid;place-items:center;padding:12px;color:var(--ku-dim);text-align:center;pointer-events:none;transition:opacity .2s}
1446
- .knobs-diff[data-height="auto"] .knobs-diff-note{position:static;min-height:calc(var(--ku-row) * 2)}
3037
+ .knobs-diff-note{position:absolute;inset:0;display:grid;place-items:center;padding:12px;color:var(--_k-fg-3);text-align:center;pointer-events:none;transition:opacity .2s}
3038
+ .knobs-diff[data-height="auto"] .knobs-diff-note{position:static;min-height:calc(var(--_k-row) * 2)}
1447
3039
  .knobs-diff diffs-container{
1448
3040
  --diffs-bg:var(--kd-solid);
1449
- --diffs-font-family:var(--ku-mono);
1450
- --diffs-header-font-family:var(--ku-font);
1451
- --diffs-font-size:calc(var(--ku-font-size) - .5px);
3041
+ --diffs-font-family:var(--_k-mono);
3042
+ --diffs-header-font-family:var(--_k-font);
3043
+ --diffs-font-size:calc(var(--_k-font-size) - .5px);
1452
3044
  --diffs-line-height:var(--kd-line);
1453
3045
  --diffs-gap-inline:var(--kd-x);
1454
3046
  --diffs-gap-block:var(--kd-i);
@@ -1463,47 +3055,47 @@ var init_diff_css = __esm(() => {
1463
3055
  --diffs-bg-deletion-number-override:color-mix(in srgb,var(--kd-del) 55%,var(--kd-solid));
1464
3056
  --diffs-bg-addition-emphasis-override:color-mix(in srgb,var(--kd-add) 22%,transparent);
1465
3057
  --diffs-bg-deletion-emphasis-override:color-mix(in srgb,var(--kd-del) 22%,transparent);
1466
- --diffs-bg-separator-override:color-mix(in srgb,var(--ku-text) 4.5%,var(--kd-solid));
1467
- --diffs-bg-context-override:color-mix(in srgb,var(--ku-text) 3%,var(--kd-solid));
1468
- --diffs-bg-buffer-override:color-mix(in srgb,var(--ku-text) 3.5%,var(--kd-solid));
1469
- --diffs-bg-selection-override:var(--ku-accent);
1470
- --diffs-fg-number-override:var(--ku-dim);
3058
+ --diffs-bg-separator-override:color-mix(in srgb,var(--_k-fg) 4.5%,var(--kd-solid));
3059
+ --diffs-bg-context-override:color-mix(in srgb,var(--_k-fg) 3%,var(--kd-solid));
3060
+ --diffs-bg-buffer-override:color-mix(in srgb,var(--_k-fg) 3.5%,var(--kd-solid));
3061
+ --diffs-bg-selection-override:var(--_k-accent);
3062
+ --diffs-fg-number-override:var(--_k-fg-3);
1471
3063
  }
1472
3064
  /* diffReview: one card, the file list a drawer at its left (its width springs; the list inside
1473
3065
  is pinned to its right edge, so it slides out from under the diff), parted from the diff by a
1474
3066
  hairline. The diff in it draws no card of its own. */
1475
- .knobs-ui.knobs-diff-review{position:relative;display:flex;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;border-radius:var(--ku-pane-radius);background:var(--ku-pane-bg);
1476
- font:var(--ku-font-weight) var(--ku-font-size)/1.35 var(--ku-font);color:var(--ku-text);text-align:left;letter-spacing:normal;-webkit-font-smoothing:antialiased}
1477
- .knobs-diff-review::after{content:"";position:absolute;inset:0;z-index:5;border-radius:inherit;box-shadow:var(--ku-pane-ring);pointer-events:none}
3067
+ .knobs-ui.knobs-diff-review{position:relative;display:flex;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;border-radius:var(--_ku-pane-radius);background:var(--_ku-pane-bg);
3068
+ font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);text-align:left;letter-spacing:normal;-webkit-font-smoothing:antialiased}
3069
+ .knobs-diff-review::after{content:"";position:absolute;inset:0;z-index:5;border-radius:inherit;box-shadow:var(--_ku-pane-ring);pointer-events:none}
1478
3070
  :where(.knobs-diff-review,.knobs-diff-review *){box-sizing:border-box}
1479
- .knobs-diff-drawer{position:relative;flex:none;width:0;height:100%;overflow:hidden;box-shadow:inset -1px 0 var(--ku-line)}
3071
+ .knobs-diff-drawer{position:relative;flex:none;width:0;height:100%;overflow:hidden;box-shadow:inset -1px 0 var(--_k-border)}
1480
3072
  .knobs-diff-drawer[data-shut]{visibility:hidden}
1481
3073
  .knobs-diff-drawer-in{position:absolute;top:0;bottom:0;right:0;display:flex;flex-direction:column}
1482
- .knobs-diff-drawer-head{flex:none;display:flex;align-items:center;gap:6px;height:calc(var(--ku-control-h) + 2 * var(--k-diff-inset,8px));padding:0 var(--k-diff-inset,8px) 0 calc(var(--ku-row-x) + 8px);
3074
+ .knobs-diff-drawer-head{flex:none;display:flex;align-items:center;gap:6px;height:calc(var(--_k-control-h) + 2 * var(--k-diff-inset,8px));padding:0 var(--k-diff-inset,8px) 0 calc(var(--_ku-row-x) + 8px);
1483
3075
  user-select:none;-webkit-user-select:none}
1484
- .knobs-diff-drawer-title{font-weight:var(--ku-title-weight)}
1485
- .knobs-diff-drawer-count{color:var(--ku-dim);font-size:var(--ku-text-meta);font-variant-numeric:tabular-nums}
3076
+ .knobs-diff-drawer-title{font-weight:var(--_k-weight-title)}
3077
+ .knobs-diff-drawer-count{color:var(--_k-fg-3);font-size:var(--_k-text-meta);font-variant-numeric:tabular-nums}
1486
3078
  .knobs-diff-drawer-in>.knobs-diff-files{flex:1;min-height:0;height:auto}
1487
3079
  .knobs-diff-main{position:relative;flex:1;min-width:0;height:100%}
1488
3080
  /* height: "auto": the card as tall as its diff; the drawer stretches to it. */
1489
3081
  .knobs-ui.knobs-diff-review[data-height="auto"],.knobs-diff-review[data-height="auto"]>:is(.knobs-diff-drawer,.knobs-diff-main){height:auto}
1490
- .knobs-diff-review .knobs-ui.knobs-diff{--k-diff-bg:transparent;--ku-pane-ring:none;border-radius:0}
3082
+ .knobs-diff-review .knobs-ui.knobs-diff{--_kd-bg:transparent;--_ku-pane-ring:none;border-radius:0}
1491
3083
  .knobs-ui .knobs-diff-toggle{margin-left:-4px}
1492
3084
  .knobs-ui .knobs-diff-toggle[aria-pressed]:not(:hover,:focus-visible){background:transparent}
1493
3085
  /* diffReview's file list: a filter over a compact tree, a status letter, the counts and their
1494
3086
  bar on each file; one highlight glides to the file on show. Viewed files dim, with a tick. */
1495
3087
  .knobs-diff-files{--k-row:var(--k-diff-row,28px);display:flex;flex-direction:column;height:100%;min-height:0;padding-top:2px}
1496
- .knobs-diff-filter{position:relative;flex:none;display:flex;align-items:center;gap:6px;height:26px;margin:0 var(--ku-row-x) 4px;padding:0 4px 0 8px;
1497
- border-radius:max(6px,var(--ku-row-radius));background:var(--ku-wash);color:var(--ku-dim);box-shadow:inset 0 0 0 1px transparent;transition:background .15s,box-shadow .15s}
1498
- .knobs-diff-filter:focus-within{background:var(--ku-wash-hi);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ku-accent) 45%,transparent)}
3088
+ .knobs-diff-filter{position:relative;flex:none;display:flex;align-items:center;gap:6px;height:26px;margin:0 var(--_ku-row-x) 4px;padding:0 4px 0 8px;
3089
+ border-radius:max(6px,var(--_ku-row-radius));background:var(--_ku-wash);color:var(--_k-fg-3);box-shadow:inset 0 0 0 1px transparent;transition:background .15s,box-shadow .15s}
3090
+ .knobs-diff-filter:focus-within{background:var(--_ku-wash-hi);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--_k-accent) 45%,transparent)}
1499
3091
  .knobs-diff-filter svg{width:12px;height:12px;flex:none}
1500
- .knobs-ui .knobs-diff-filter>input{flex:1;min-width:0;height:100%;font:var(--ku-font-weight) var(--ku-font-size)/1 var(--ku-font);color:var(--ku-text);caret-color:var(--ku-accent);background:transparent}
1501
- .knobs-ui .knobs-diff-filter>input::placeholder{color:var(--ku-dim)}
1502
- .knobs-ui .knobs-diff-filter>button{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;color:var(--ku-dim);cursor:pointer;transition:background .12s,color .12s,opacity .12s}
1503
- .knobs-ui .knobs-diff-filter>button:hover{background:var(--ku-wash-hi);color:var(--ku-text)}
3092
+ .knobs-ui .knobs-diff-filter>input{flex:1;min-width:0;height:100%;font:var(--_k-weight) var(--_k-font-size)/1 var(--_k-font);color:var(--_k-fg);caret-color:var(--_k-accent);background:transparent}
3093
+ .knobs-ui .knobs-diff-filter>input::placeholder{color:var(--_k-fg-3)}
3094
+ .knobs-ui .knobs-diff-filter>button{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;color:var(--_k-fg-3);cursor:pointer;transition:background .12s,color .12s,opacity .12s}
3095
+ .knobs-ui .knobs-diff-filter>button:hover{background:var(--_ku-wash-hi);color:var(--_k-fg)}
1504
3096
  .knobs-diff-filter>button svg{width:10px;height:10px}
1505
3097
  .knobs-diff-list{position:relative;flex:1;min-height:0}
1506
- .knobs-diff-files .knobs-diff-counts{font-size:var(--ku-text-meta);align-items:center}
3098
+ .knobs-diff-files .knobs-diff-counts{font-size:var(--_k-text-meta);align-items:center}
1507
3099
  .knobs-diff-files .knobs-diff-counts{gap:5px}
1508
3100
  .knobs-diff-files .knobs-diff-bar{margin-left:0}
1509
3101
  .knobs-diff-files .knobs-diff-bar>i{width:4px;height:4px;border-radius:1px}
@@ -2218,6 +3810,40 @@ function parseCssColor(raw, fallback = [1, 1, 1, 1]) {
2218
3810
  cache.set(s, out);
2219
3811
  return out;
2220
3812
  }
3813
+ function pickScheme(raw, light) {
3814
+ let s = raw;
3815
+ for (let at = s.lastIndexOf("light-dark(");at >= 0; at = s.lastIndexOf("light-dark(")) {
3816
+ let depth = 0;
3817
+ let comma = -1;
3818
+ let end = -1;
3819
+ for (let i = at + 11;i < s.length; i++) {
3820
+ const ch = s[i];
3821
+ if (ch === "(")
3822
+ depth++;
3823
+ else if (ch === ")") {
3824
+ if (depth === 0) {
3825
+ end = i;
3826
+ break;
3827
+ }
3828
+ depth--;
3829
+ } else if (ch === "," && depth === 0 && comma < 0)
3830
+ comma = i;
3831
+ }
3832
+ if (end < 0 || comma < 0)
3833
+ break;
3834
+ const side = light ? s.slice(at + 11, comma) : s.slice(comma + 1, end);
3835
+ s = s.slice(0, at) + side.trim() + s.slice(end + 1);
3836
+ }
3837
+ return s;
3838
+ }
3839
+ function tokenColor(style, name, fallback) {
3840
+ const raw = style.getPropertyValue(name).trim();
3841
+ return raw ? parseCssColor(pickScheme(raw, isLightStyle(style)), fallback) : fallback;
3842
+ }
3843
+ function tokenCss(style, name, fallback) {
3844
+ const raw = style.getPropertyValue(name).trim();
3845
+ return raw ? pickScheme(raw, isLightStyle(style)) : fallback;
3846
+ }
2221
3847
  var cache, probe = null, probeCtx = () => {
2222
3848
  if (probe)
2223
3849
  return probe;
@@ -2229,7 +3855,7 @@ var cache, probe = null, probeCtx = () => {
2229
3855
  probe = c.getContext("2d", { willReadFrequently: true });
2230
3856
  }
2231
3857
  return probe;
2232
- }, rgbaCss = (c) => `rgba(${Math.round(c[0] * 255)},${Math.round(c[1] * 255)},${Math.round(c[2] * 255)},${Math.round(c[3] * 1000) / 1000})`;
3858
+ }, rgbaCss = (c) => `rgba(${Math.round(c[0] * 255)},${Math.round(c[1] * 255)},${Math.round(c[2] * 255)},${Math.round(c[3] * 1000) / 1000})`, isLightStyle = (style) => style.getPropertyValue("--_k-light").trim() === "1";
2233
3859
  var init_rgba = __esm(() => {
2234
3860
  cache = new Map;
2235
3861
  });
@@ -2700,13 +4326,13 @@ function hintTokens(doc, groups) {
2700
4326
  };
2701
4327
  const panel = doc.querySelector(".knobs-panel");
2702
4328
  const piece = groups.find((g) => g.source && !g.source.paint)?.source?.root;
2703
- const pick = (k, fallback) => read(panel, [`--k-${k}`]) || read(piece, [`--ku-${k}`, `--k-${k}`]) || fallback;
4329
+ const pick = (k, fallback) => read(panel, [`--_k-${k}`]) || read(piece, [`--_k-${k}`]) || fallback;
2704
4330
  return {
2705
4331
  "--kh-accent": pick("accent", "#fff"),
2706
4332
  "--kh-bg": pick("bg", "#1c1c1e"),
2707
4333
  "--kh-mono": pick("mono", "ui-monospace,Menlo,monospace"),
2708
- "--kh-radius": read(panel, ["--k-radius-sm"]) || "4px",
2709
- "--kh-size": read(panel, ["--k-text-cap"]) || "10px",
4334
+ "--kh-radius": read(panel, ["--_k-radius-sm"]) || "4px",
4335
+ "--kh-size": read(panel, ["--_k-text-cap"]) || "10px",
2710
4336
  "--kh-typed": read(panel, ["--k-hint-typed-opacity"]) || ".42",
2711
4337
  "--kh-lift": read(panel, ["--k-lift"]) || "1",
2712
4338
  "--kh-ease": read(panel, ["--k-ease"]) || "cubic-bezier(.2,.8,.2,1)"
@@ -3054,7 +4680,7 @@ function tree(container, options) {
3054
4680
  root.setAttribute("aria-multiselectable", "true");
3055
4681
  if (options.label)
3056
4682
  root.setAttribute("aria-label", options.label);
3057
- applyLook(root, options);
4683
+ applyLook2(root, options);
3058
4684
  const space = doc.createElement("div");
3059
4685
  space.className = "knobs-tree-space";
3060
4686
  const line = doc.createElement("div");
@@ -3099,7 +4725,7 @@ function tree(container, options) {
3099
4725
  const measure = () => {
3100
4726
  syncFrame(root);
3101
4727
  const probe = doc.createElement("div");
3102
- probe.style.cssText = "position:absolute;visibility:hidden;height:var(--ku-row);width:var(--ku-indent);padding-left:var(--ku-inset)";
4728
+ probe.style.cssText = "position:absolute;visibility:hidden;height:var(--_k-row);width:var(--_ku-indent);padding-left:var(--_k-inset)";
3103
4729
  root.append(probe);
3104
4730
  const r = probe.getBoundingClientRect();
3105
4731
  h = options.rowHeight ?? (r.height || 26);
@@ -3618,11 +5244,8 @@ function tree(container, options) {
3618
5244
  function beginDrag(id) {
3619
5245
  const ids = topmost(items, access, isSelected(id) ? sel.ids : [id]);
3620
5246
  const ghost = doc.createElement("div");
3621
- ghost.className = "knobs-ui knobs-tree-ghost";
3622
- if (options.preset)
3623
- ghost.dataset.preset = options.preset.name;
3624
- if (options.theme)
3625
- ghost.dataset.theme = options.theme;
5247
+ ghost.className = "knobs-root knobs-ui knobs-tree-ghost";
5248
+ applyLook(ghost, lookAt(root));
3626
5249
  ghost.textContent = ids.length === 1 ? renamed.get(ids[0]) ?? access.label(index.get(ids[0]).item) : `${ids.length} items`;
3627
5250
  doc.body.append(ghost);
3628
5251
  dragging = { ids, ghost, x: press.x, y: press.y, hoverAt: 0, hoverId: null };
@@ -3968,10 +5591,12 @@ function builtinIcon(id, on) {
3968
5591
  }
3969
5592
  var MOVE, EDGE = 28;
3970
5593
  var init_tree = __esm(() => {
5594
+ init_appearance();
5595
+ init_motion();
3971
5596
  init_page_hints();
3972
5597
  init_look();
3973
5598
  init_tree_model();
3974
- MOVE = springMotion({ duration: 0.3, bounce: 0 });
5599
+ MOVE = springMotion(SPRINGS.default);
3975
5600
  });
3976
5601
 
3977
5602
  // src/ui/diff.ts
@@ -3980,7 +5605,7 @@ function injectDiffStyles(doc) {
3980
5605
  return;
3981
5606
  const style = doc.createElement("style");
3982
5607
  style.dataset.knobsUiDiff = "";
3983
- style.textContent = diffCss;
5608
+ style.textContent = aliased(diffCss);
3984
5609
  doc.head.append(style);
3985
5610
  }
3986
5611
  function diffCounts(file, doc = document, options = {}) {
@@ -4036,10 +5661,10 @@ function backdrop(el, view) {
4036
5661
  if (!out)
4037
5662
  return null;
4038
5663
  for (let i = layers.length - 1;i >= 0; i--)
4039
- out = over(layers[i], out);
5664
+ out = over2(layers[i], out);
4040
5665
  return out;
4041
5666
  }
4042
- function over(top, under) {
5667
+ function over2(top, under) {
4043
5668
  const [r, g, b, a] = top;
4044
5669
  const [R, G, B, A] = under;
4045
5670
  const o = a + A * (1 - a);
@@ -4078,7 +5703,7 @@ function codeDiff(container, options) {
4078
5703
  root.dataset.height = auto ? "auto" : "fill";
4079
5704
  if (stack)
4080
5705
  root.dataset.stack = "";
4081
- applyLook(root, options);
5706
+ applyLook2(root, options);
4082
5707
  injectDiffStyles(doc);
4083
5708
  const make = (tag, cls) => {
4084
5709
  const el = doc.createElement(tag);
@@ -4400,7 +6025,7 @@ function codeDiff(container, options) {
4400
6025
  scrolls.set(slot.file, slot.sc.scrollTop);
4401
6026
  slot.leaving = true;
4402
6027
  slot.el.dataset.leaving = "";
4403
- tune(slot.o, reducedMotion(win) ? FADE3 : OUT).set(0);
6028
+ tune(slot.o, reducedMotion(win) ? FADE4 : OUT).set(0);
4404
6029
  };
4405
6030
  const say = (text) => {
4406
6031
  note.textContent = text ?? "";
@@ -4514,7 +6139,7 @@ function codeDiff(container, options) {
4514
6139
  slot.bars.rescan();
4515
6140
  slot.sc.scrollTop = same ? along * (slot.sc.scrollHeight - slot.sc.clientHeight) : scrolls.get(file.name) ?? 0;
4516
6141
  slot.fades.update();
4517
- tune(slot.o, reducedMotion(win) ? FADE3 : IN).snap(0).set(1);
6142
+ tune(slot.o, reducedMotion(win) ? FADE4 : IN).snap(0).set(1);
4518
6143
  style(slot);
4519
6144
  live.push(slot);
4520
6145
  sizes.disconnect();
@@ -4829,7 +6454,7 @@ function codeDiff(container, options) {
4829
6454
  return;
4830
6455
  const behind = backdrop(root.parentElement, win);
4831
6456
  if (behind)
4832
- root.style.setProperty("--kd-fill", rgbaCss(over(own, behind)));
6457
+ root.style.setProperty("--kd-fill", rgbaCss(over2(own, behind)));
4833
6458
  };
4834
6459
  const rescheme = () => {
4835
6460
  syncFrame(root);
@@ -5042,7 +6667,8 @@ function diffReview(container, options) {
5042
6667
  const doc = container.ownerDocument;
5043
6668
  const look = {
5044
6669
  ...options.preset ? { preset: options.preset } : {},
5045
- ...options.theme ? { theme: options.theme } : {}
6670
+ ...options.theme ? { theme: options.theme } : {},
6671
+ ...options.appearance ? { appearance: options.appearance } : {}
5046
6672
  };
5047
6673
  const title = options.title ?? "Files";
5048
6674
  const store = options.storage === undefined ? browserStorage() : options.storage;
@@ -5065,7 +6691,7 @@ function diffReview(container, options) {
5065
6691
  const root = doc.createElement("div");
5066
6692
  root.className = "knobs-diff-review";
5067
6693
  root.dataset.height = options.height ?? "fill";
5068
- applyLook(root, look);
6694
+ applyLook2(root, look);
5069
6695
  injectDiffStyles(doc);
5070
6696
  const drawer = doc.createElement("div");
5071
6697
  drawer.className = "knobs-diff-drawer";
@@ -5369,19 +6995,21 @@ function diffReview(container, options) {
5369
6995
  }
5370
6996
  };
5371
6997
  }
5372
- var lib, load = () => lib ??= import("@pierre/diffs"), SYNTAX, IN, OUT, FADE3, HEIGHT, DRAWER, BLUR = 3, WRAP, PREV, UNVIEWED, VIEWED, SEARCH, CLEAR2, SIDEBAR, SEPARATOR = 32;
6998
+ var lib, load = () => lib ??= import("@pierre/diffs"), SYNTAX, IN, OUT, FADE4, HEIGHT, DRAWER, BLUR = 3, WRAP, PREV, UNVIEWED, VIEWED, SEARCH, CLEAR2, SIDEBAR, SEPARATOR = 32;
5373
6999
  var init_diff = __esm(() => {
7000
+ init_glide();
7001
+ init_motion();
5374
7002
  init_diff_css();
5375
7003
  init_diff_model();
5376
7004
  init_look();
5377
7005
  init_rgba();
5378
7006
  init_tree();
5379
7007
  SYNTAX = { dark: "pierre-dark", light: "pierre-light" };
5380
- IN = springMotion({ duration: 0.3, bounce: 0 });
5381
- OUT = springMotion({ duration: 0.24, bounce: 0 });
5382
- FADE3 = springMotion({ duration: 0.16, bounce: 0 });
5383
- HEIGHT = springMotion({ duration: 0.4, bounce: 0 });
5384
- DRAWER = springMotion({ duration: 0.4, bounce: 0 });
7008
+ IN = springMotion(SPRINGS.default);
7009
+ OUT = springMotion(SPRINGS.snappy);
7010
+ FADE4 = springMotion(FADE);
7011
+ HEIGHT = springMotion(SPRINGS.calm);
7012
+ DRAWER = springMotion(SPRINGS.calm);
5385
7013
  WRAP = svg('<path d="M2.5 4h11"/><path d="M2.5 8h9a2 2 0 0 1 0 4H8.5"/><path d="M10 10.5 8.5 12l1.5 1.5"/><path d="M2.5 12h3"/>');
5386
7014
  PREV = svg('<path d="M10 3.5 5.5 8l4.5 4.5"/>');
5387
7015
  UNVIEWED = svg('<circle cx="8" cy="8" r="5.5"/>');
@@ -5406,7 +7034,7 @@ function layerElement(doc, cls, look) {
5406
7034
  const el = doc.createElement("div");
5407
7035
  el.className = cls;
5408
7036
  layerRoot(doc).append(el);
5409
- applyLook(el, lookOf(look));
7037
+ applyLook2(el, lookOf(look));
5410
7038
  return el;
5411
7039
  }
5412
7040
  function presence(el, o = {}) {
@@ -5445,7 +7073,7 @@ function presence(el, o = {}) {
5445
7073
  });
5446
7074
  const tune = (seconds, zeta) => {
5447
7075
  const reduced = reducedMotion(win);
5448
- spring.omega = 2 * Math.PI / (reduced ? 0.16 : seconds);
7076
+ spring.omega = 2 * Math.PI / (reduced ? FADE.duration : seconds);
5449
7077
  spring.zeta = reduced ? 1 : zeta;
5450
7078
  };
5451
7079
  render();
@@ -5573,6 +7201,7 @@ var lookOf = (look) => ({ ...lookDefaults.current, ...look }), roots, stacks, FO
5573
7201
  h: doc.documentElement.clientHeight
5574
7202
  });
5575
7203
  var init_layer = __esm(() => {
7204
+ init_motion();
5576
7205
  init_look();
5577
7206
  roots = new WeakMap;
5578
7207
  stacks = new WeakMap;
@@ -5667,7 +7296,7 @@ function softClamp(x, min, max, knee = 12) {
5667
7296
  return min + k * Math.exp(-(min + k - x) / k);
5668
7297
  return x;
5669
7298
  }
5670
- function solve(input) {
7299
+ function solve2(input) {
5671
7300
  const { panes, sizes, collapsed, fixed = {} } = input;
5672
7301
  const rail = input.rail ?? (() => 0);
5673
7302
  const room = Math.max(0, input.total - (input.divider ?? 1) * Math.max(0, panes.length - 1));
@@ -5789,15 +7418,15 @@ function foldProgress(size, open, rail) {
5789
7418
  return Math.min(1, Math.max(0, (open - size) / span));
5790
7419
  }
5791
7420
  function face(prev, away) {
5792
- const lo = clamp01(1 - away / FACE_IN);
5793
- const hi = clamp01(1 - away / FACE_OUT);
7421
+ const lo = clamp012(1 - away / FACE_IN);
7422
+ const hi = clamp012(1 - away / FACE_OUT);
5794
7423
  return Math.min(hi, Math.max(lo, prev));
5795
7424
  }
5796
7425
  function foldFaces(prev, p) {
5797
7426
  return { content: face(prev.content, p), rail: face(prev.rail, 1 - p) };
5798
7427
  }
5799
7428
  function chevronTurn(p, edge) {
5800
- return (edge === "start" ? 180 : -180) * (1 - clamp01(p));
7429
+ return (edge === "start" ? 180 : -180) * (1 - clamp012(p));
5801
7430
  }
5802
7431
  function chevronFlip(f, edge) {
5803
7432
  return chevronTurn(f, edge);
@@ -5811,7 +7440,7 @@ function foldStyle(options = {}) {
5811
7440
  };
5812
7441
  }
5813
7442
  function titleTravel(at, open, rail, edge, p) {
5814
- const k = 1 - clamp01(p);
7443
+ const k = 1 - clamp012(p);
5815
7444
  const dx = at.title - at.label - (edge === "start" ? open - rail : 0);
5816
7445
  return { x: dx * k, y: at.dy * k, turn: -90 * k };
5817
7446
  }
@@ -5840,7 +7469,7 @@ function serializeLayout(layout) {
5840
7469
  collapsed[id] = true;
5841
7470
  return JSON.stringify({ sizes, collapsed });
5842
7471
  }
5843
- var DEFAULT_MIN = 48, COLLAPSE_PAST = 40, paneMin = (p) => Math.max(0, p.min ?? DEFAULT_MIN), paneMax = (p) => Math.max(paneMin(p), p.max ?? Number.POSITIVE_INFINITY), FACE_OUT = 0.4, FACE_IN = 0.3, clamp01 = (x) => Math.min(1, Math.max(0, x)), FOLD_STYLE;
7472
+ var DEFAULT_MIN = 48, COLLAPSE_PAST = 40, paneMin = (p) => Math.max(0, p.min ?? DEFAULT_MIN), paneMax = (p) => Math.max(paneMin(p), p.max ?? Number.POSITIVE_INFINITY), FACE_OUT = 0.4, FACE_IN = 0.3, clamp012 = (x) => Math.min(1, Math.max(0, x)), FOLD_STYLE;
5844
7473
  var init_split_model = __esm(() => {
5845
7474
  FOLD_STYLE = { chevron: "flip", title: "travel", duration: 0.25 };
5846
7475
  });
@@ -6418,7 +8047,7 @@ function timeline(container, options) {
6418
8047
  root.setAttribute("aria-roledescription", "timeline");
6419
8048
  root.setAttribute("aria-label", options.label ?? "Timeline");
6420
8049
  root.setAttribute("aria-keyshortcuts", "Space ArrowLeft ArrowRight , . Home End [ ] I O M");
6421
- applyLook(root, options);
8050
+ applyLook2(root, options);
6422
8051
  const transport = el("div", "knobs-tl-transport");
6423
8052
  const playBtn = el("button", "knobs-tl-play");
6424
8053
  playBtn.type = "button";
@@ -6475,11 +8104,11 @@ function timeline(container, options) {
6475
8104
  const readColors = () => {
6476
8105
  const cs = win.getComputedStyle(root);
6477
8106
  colors = {
6478
- tick: cs.getPropertyValue("--ku-line-hi").trim() || "rgba(255,255,255,.18)",
6479
- major: cs.getPropertyValue("--ku-dim").trim() || "rgba(255,255,255,.42)",
6480
- label: cs.getPropertyValue("--ku-label").trim() || "rgba(255,255,255,.64)",
6481
- line: cs.getPropertyValue("--ku-line").trim() || "rgba(255,255,255,.1)",
6482
- font: `${cs.getPropertyValue("--ku-font-weight").trim() || 400} ${cs.getPropertyValue("--ku-text-meta").trim() || "11px"} ${cs.getPropertyValue("--ku-font").trim() || "system-ui"}`
8107
+ tick: tokenCss(cs, "--kv-border-strong", "rgba(255,255,255,.18)"),
8108
+ major: tokenCss(cs, "--kv-fg-3", "rgba(255,255,255,.42)"),
8109
+ label: tokenCss(cs, "--kv-fg-2", "rgba(255,255,255,.64)"),
8110
+ line: tokenCss(cs, "--kv-border", "rgba(255,255,255,.1)"),
8111
+ font: `${cs.getPropertyValue("--_k-weight").trim() || 400} ${(Number.parseFloat(cs.fontSize) || 12) - 1}px ${cs.getPropertyValue("--_k-font").trim() || "system-ui"}`
6483
8112
  };
6484
8113
  drawn = "";
6485
8114
  };
@@ -7346,14 +8975,16 @@ function timeline(container, options) {
7346
8975
  }
7347
8976
  var RULER = 22, INSTANT2, CALM, GLIDE, uid2 = 0, PLAY2 = '<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M5 3.6v8.8c0 .5.5.8.9.5l6.6-4.4c.4-.3.4-.8 0-1L5.9 3.1c-.4-.3-.9 0-.9.5Z" fill="currentColor"/></svg>', PAUSE = '<svg viewBox="0 0 16 16" aria-hidden="true"><rect x="4" y="3.2" width="2.8" height="9.6" rx="1" fill="currentColor"/><rect x="9.2" y="3.2" width="2.8" height="9.6" rx="1" fill="currentColor"/></svg>';
7348
8977
  var init_timeline = __esm(() => {
8978
+ init_rgba();
8979
+ init_motion();
7349
8980
  init_page_hints();
7350
8981
  init_menu();
7351
8982
  init_look();
7352
8983
  init_split_model();
7353
8984
  init_timeline_model();
7354
- INSTANT2 = springMotion({ duration: 0.1, bounce: 0 });
7355
- CALM = springMotion({ duration: 0.4, bounce: 0 });
7356
- GLIDE = springMotion({ duration: 0.22, bounce: 0 });
8985
+ INSTANT2 = springMotion(SPRINGS.instant);
8986
+ CALM = springMotion(SPRINGS.calm);
8987
+ GLIDE = springMotion(SPRINGS.snappy);
7357
8988
  });
7358
8989
 
7359
8990
  // src/ui/compare-model.ts
@@ -8464,7 +10095,7 @@ function compareStrip(container, options) {
8464
10095
  root.className = "knobs-cmp-strip";
8465
10096
  root.setAttribute("role", "img");
8466
10097
  root.setAttribute("aria-label", "Frame strip: Before over After, with how much they differ");
8467
- applyLook(root, options);
10098
+ applyLook2(root, options);
8468
10099
  const canvas = doc.createElement("canvas");
8469
10100
  canvas.setAttribute("aria-hidden", "true");
8470
10101
  root.append(canvas);
@@ -8584,10 +10215,10 @@ function compareStrip(container, options) {
8584
10215
  const readColors = () => {
8585
10216
  const cs = win.getComputedStyle(root);
8586
10217
  colors = {
8587
- surface: rgba(cs.getPropertyValue("--ku-surface"), [1, 1, 1, 0.055]),
8588
- accent: rgba(cs.getPropertyValue("--ku-accent"), [1, 1, 1, 1]),
8589
- diff: rgba(cs.getPropertyValue("--ku-cmp-diff"), [0.49, 0.81, 0.61, 1]),
8590
- wash: rgba(cs.getPropertyValue("--ku-surface-hi"), [1, 1, 1, 0.11])
10218
+ surface: rgba(tokenCss(cs, "--kv-fill", ""), [1, 1, 1, 0.055]),
10219
+ accent: rgba(tokenCss(cs, "--kv-accent", ""), [1, 1, 1, 1]),
10220
+ diff: rgba(tokenCss(cs, "--_ku-cmp-diff", ""), [0.49, 0.81, 0.61, 1]),
10221
+ wash: rgba(tokenCss(cs, "--kv-fill-selected", ""), [1, 1, 1, 0.11])
8591
10222
  };
8592
10223
  };
8593
10224
  let hover = null;
@@ -8831,7 +10462,8 @@ function compare(container, options) {
8831
10462
  const win = doc.defaultView;
8832
10463
  const look = {
8833
10464
  ...options.preset ? { preset: options.preset } : {},
8834
- ...options.theme ? { theme: options.theme } : {}
10465
+ ...options.theme ? { theme: options.theme } : {},
10466
+ ...options.appearance ? { appearance: options.appearance } : {}
8835
10467
  };
8836
10468
  let mode = options.mode ?? "side";
8837
10469
  let wipe = Math.min(1, Math.max(0, options.wipe ?? 0.5));
@@ -8852,7 +10484,7 @@ function compare(container, options) {
8852
10484
  root.setAttribute("aria-roledescription", "compare");
8853
10485
  root.setAttribute("aria-label", options.label ?? "Compare");
8854
10486
  root.setAttribute("aria-keyshortcuts", "Space ArrowLeft ArrowRight Shift+ArrowLeft Shift+ArrowRight , . 1 2 3 4 S W D X Z L 0 = -");
8855
- applyLook(root, options);
10487
+ applyLook2(root, options);
8856
10488
  root.dataset.mode = mode;
8857
10489
  if (auto)
8858
10490
  root.dataset.auto = "";
@@ -8860,7 +10492,7 @@ function compare(container, options) {
8860
10492
  const modes = el("div", "knobs-cmp-modes");
8861
10493
  modes.setAttribute("role", "radiogroup");
8862
10494
  modes.setAttribute("aria-label", "Mode");
8863
- const modeBtns = MODES.map((m, i) => {
10495
+ const modeBtns = MODES2.map((m, i) => {
8864
10496
  const b = el("button", "knobs-cmp-mode");
8865
10497
  b.type = "button";
8866
10498
  b.tabIndex = -1;
@@ -8951,7 +10583,7 @@ function compare(container, options) {
8951
10583
  let pending = false;
8952
10584
  let gpu = null;
8953
10585
  const lay = new Spring(mode === "side" ? 0 : 1, LAYOUT2.omega, LAYOUT2.zeta, 0.0001);
8954
- const fade = new Spring(1, FADE5.omega, FADE5.zeta, 0.001);
10586
+ const fade = new Spring(1, FADE6.omega, FADE6.zeta, 0.001);
8955
10587
  let fromMode = mode;
8956
10588
  let toMode = mode;
8957
10589
  let phase = false;
@@ -9286,7 +10918,7 @@ function compare(container, options) {
9286
10918
  };
9287
10919
  const syncModeUi = () => {
9288
10920
  root.dataset.mode = mode;
9289
- MODES.forEach((m, i) => {
10921
+ MODES2.forEach((m, i) => {
9290
10922
  modeBtns[i].setAttribute("aria-checked", String(m.mode === mode));
9291
10923
  });
9292
10924
  handle.tabIndex = mode === "wipe" ? 0 : -1;
@@ -9296,7 +10928,7 @@ function compare(container, options) {
9296
10928
  return;
9297
10929
  mode = next;
9298
10930
  const reduced = reducedMotion(win);
9299
- tune(fade, reduced ? FADE_REDUCED : FADE5);
10931
+ tune(fade, reduced ? FADE_REDUCED : FADE6);
9300
10932
  if (fade.x >= 0.5) {
9301
10933
  fromMode = toMode;
9302
10934
  fade.snap(0);
@@ -9646,7 +11278,7 @@ function compare(container, options) {
9646
11278
  stageRect = null;
9647
11279
  };
9648
11280
  const readColors = () => {
9649
- const c = parseCssColor(win.getComputedStyle(root).getPropertyValue("--ku-cmp-diff"), [0.49, 0.81, 0.61, 1]);
11281
+ const c = tokenColor(win.getComputedStyle(root), "--_ku-cmp-diff", [0.49, 0.81, 0.61, 1]);
9650
11282
  accent = [c[0], c[1], c[2]];
9651
11283
  labelW = [labels[0].offsetWidth, labels[1].offsetWidth];
9652
11284
  requestDraw();
@@ -9912,7 +11544,7 @@ function compare(container, options) {
9912
11544
  if (e.altKey || e.shiftKey)
9913
11545
  return;
9914
11546
  claim();
9915
- return setMode(MODES[Number(key) - 1].mode);
11547
+ return setMode(MODES2[Number(key) - 1].mode);
9916
11548
  case "x":
9917
11549
  if (e.altKey)
9918
11550
  return;
@@ -10047,7 +11679,7 @@ function compare(container, options) {
10047
11679
  holdLoupe(false);
10048
11680
  });
10049
11681
  const unregisterHints = options.hints === false ? undefined : hints.register(root, () => [
10050
- ...MODES.map((m, i) => ({
11682
+ ...MODES2.map((m, i) => ({
10051
11683
  el: modeBtns[i],
10052
11684
  label: m.label,
10053
11685
  activate: () => setMode(m.mode)
@@ -10202,8 +11834,9 @@ function compare(container, options) {
10202
11834
  wake();
10203
11835
  return api;
10204
11836
  }
10205
- var LAYOUT2, FADE5, FADE_REDUCED, ZOOM, FLICKER_MS = 400, SLOP = 12, INSET = 8, LOUPE, FAST_SEEK_FRAMES = 15, RELEASE_MS = 3000, MODES, KEY_MODE;
11837
+ var LAYOUT2, FADE6, FADE_REDUCED, ZOOM, FLICKER_MS = 400, SLOP = 12, INSET = 8, LOUPE, FAST_SEEK_FRAMES = 15, RELEASE_MS = 3000, MODES2, KEY_MODE;
10206
11838
  var init_compare = __esm(() => {
11839
+ init_motion();
10207
11840
  init_page_hints();
10208
11841
  init_compare_frames();
10209
11842
  init_compare_gpu();
@@ -10213,11 +11846,11 @@ var init_compare = __esm(() => {
10213
11846
  init_rgba();
10214
11847
  init_timeline();
10215
11848
  LAYOUT2 = springMotion({ duration: 0.35, bounce: 0 });
10216
- FADE5 = springMotion({ duration: 0.25, bounce: 0 });
10217
- FADE_REDUCED = springMotion({ duration: 0.15, bounce: 0 });
11849
+ FADE6 = springMotion(SPRINGS.snappy);
11850
+ FADE_REDUCED = springMotion(FADE);
10218
11851
  ZOOM = springMotion({ duration: 0.35, bounce: 0 });
10219
11852
  LOUPE = { r: 88, zoom: 4 };
10220
- MODES = [
11853
+ MODES2 = [
10221
11854
  { mode: "side", label: "Side by side", key: "S" },
10222
11855
  { mode: "wipe", label: "Wipe", key: "W" },
10223
11856
  { mode: "difference", label: "Difference", key: "D" },
@@ -10961,6 +12594,10 @@ function rt(e, t) {
10961
12594
  let n = new oe(e, t, Fe);
10962
12595
  return _.add(e), n;
10963
12596
  }
12597
+
12598
+ // src/ui/activity.ts
12599
+ init_motion();
12600
+
10964
12601
  // src/ui/activity-model.ts
10965
12602
  function flattenActivity(events, expanded) {
10966
12603
  const rows = [];
@@ -11117,12 +12754,12 @@ var ACTIVITY_ICONS = {
11117
12754
  shipped: svg('<circle cx="8" cy="8" r="5.8"/><path d="m5.6 8.2 1.7 1.7 3.2-3.6"/>')
11118
12755
  };
11119
12756
  var PLAY = '<svg viewBox="0 0 8 8" aria-hidden="true"><path d="M1.5 1v6l5.2-3Z" fill="currentColor"/></svg>';
11120
- var REFLOW = springMotion({ duration: 0.3, bounce: 0 });
11121
- var OPEN = springMotion({ duration: 0.22, bounce: 0 });
11122
- var CLOSE = springMotion({ duration: 0.18, bounce: 0 });
11123
- var BLOOM = springMotion({ duration: 0.3, bounce: 0 });
11124
- var EXIT = springMotion({ duration: 0.24, bounce: 0 });
11125
- var FADE = springMotion({ duration: 0.16, bounce: 0 });
12757
+ var REFLOW = springMotion(SPRINGS.default);
12758
+ var OPEN = springMotion(SPRINGS.snappy);
12759
+ var CLOSE2 = springMotion(CLOSE);
12760
+ var BLOOM = springMotion(SPRINGS.default);
12761
+ var EXIT = springMotion(SPRINGS.snappy);
12762
+ var FADE2 = springMotion(FADE);
11126
12763
  var CLEAR = [11, 5];
11127
12764
  var PAD = 6;
11128
12765
  var SLIDE = 8;
@@ -11143,7 +12780,7 @@ function activity(container, options) {
11143
12780
  root.setAttribute("role", "tree");
11144
12781
  if (options.label)
11145
12782
  root.setAttribute("aria-label", options.label);
11146
- applyLook(root, options);
12783
+ applyLook2(root, options);
11147
12784
  const space = doc.createElement("div");
11148
12785
  space.className = "knobs-activity-space";
11149
12786
  const hl = doc.createElement("div");
@@ -11447,7 +13084,7 @@ function activity(container, options) {
11447
13084
  function sync(cause, toggled) {
11448
13085
  const reduced = reducedMotion(win);
11449
13086
  const animate = cause !== "snap";
11450
- const glide = cause === "open" ? OPEN : cause === "close" ? CLOSE : REFLOW;
13087
+ const glide = cause === "open" ? OPEN : cause === "close" ? CLOSE2 : REFLOW;
11451
13088
  const before = [...views.values()].filter((v) => !v.leaving).map((v) => v.id);
11452
13089
  rows = flattenActivity(events, expanded);
11453
13090
  selected = keepSelection(rows, selected, (id) => index.get(id)?.parent);
@@ -11485,7 +13122,7 @@ function activity(container, options) {
11485
13122
  v.p.snap(1);
11486
13123
  } else if (reduced) {
11487
13124
  v.y.snap(goal);
11488
- tune(v.p, FADE).snap(0).set(1);
13125
+ tune(v.p, FADE2).snap(0).set(1);
11489
13126
  } else {
11490
13127
  const parent = row.parent !== null ? views.get(row.parent) : undefined;
11491
13128
  if (parent && !parent.leaving) {
@@ -11517,7 +13154,7 @@ function activity(container, options) {
11517
13154
  v.el.dataset.leaving = "";
11518
13155
  v.el.setAttribute("aria-selected", "false");
11519
13156
  if (reduced) {
11520
- tune(v.p, FADE).set(0);
13157
+ tune(v.p, FADE2).set(0);
11521
13158
  continue;
11522
13159
  }
11523
13160
  const group = index.get(v.id)?.parent ?? null;
@@ -11525,8 +13162,8 @@ function activity(container, options) {
11525
13162
  if (parent && !parent.leaving && v.depth === 1) {
11526
13163
  v.under = group;
11527
13164
  const drawer = cause === "close" && group === toggled;
11528
- tune(v.y, drawer ? CLOSE : glide).set(drawer ? v.y.target - shut : targets.get(group) ?? parent.y.target);
11529
- tune(v.p, drawer ? CLOSE : EXIT).set(0);
13165
+ tune(v.y, drawer ? CLOSE2 : glide).set(drawer ? v.y.target - shut : targets.get(group) ?? parent.y.target);
13166
+ tune(v.p, drawer ? CLOSE2 : EXIT).set(0);
11530
13167
  } else {
11531
13168
  v.from = 0;
11532
13169
  tune(v.p, EXIT).set(0);
@@ -11629,7 +13266,7 @@ function activity(container, options) {
11629
13266
  const to = targets.get(id);
11630
13267
  const far = from !== undefined && to !== undefined && Math.abs(to - from) > 400;
11631
13268
  const reduced = reducedMotion(win);
11632
- moveHighlight(reduced || from === undefined ? null : springMotion({ duration: far ? 0.42 : 0.3, bounce: 0 }));
13269
+ moveHighlight(reduced || from === undefined ? null : springMotion(far ? SPRINGS.calm : SPRINGS.default));
11633
13270
  root.setAttribute("aria-activedescendant", domId(id));
11634
13271
  if (source === "key") {
11635
13272
  scrollHold = null;
@@ -11797,6 +13434,10 @@ function activity(container, options) {
11797
13434
  };
11798
13435
  return handle;
11799
13436
  }
13437
+
13438
+ // src/ui/bento.ts
13439
+ init_motion();
13440
+
11800
13441
  // src/ui/bento-model.ts
11801
13442
  var FIT_MAX = 24;
11802
13443
  var clamp = (x, a, b) => Math.min(b, Math.max(a, x));
@@ -12117,16 +13758,16 @@ function motionBlur(speed, max = 3, per = 1600) {
12117
13758
 
12118
13759
  // src/ui/bento.ts
12119
13760
  init_look();
12120
- var LAYOUT = springMotion({ duration: 0.4, bounce: 0 });
12121
- var ZOOM_IN = springMotion({ duration: 0.45, bounce: 0 });
12122
- var ZOOM_OUT = springMotion({ duration: 0.38, bounce: 0 });
12123
- var SLIDE2 = springMotion({ duration: 0.3, bounce: 0 });
12124
- var SLIDE_OUT = springMotion({ duration: 0.25, bounce: 0 });
12125
- var ENTER = springMotion({ duration: 0.3, bounce: 0 });
12126
- var EXIT2 = springMotion({ duration: 0.25, bounce: 0 });
12127
- var WASH = springMotion({ duration: 0.25, bounce: 0 });
12128
- var FADE2 = springMotion({ duration: 0.18, bounce: 0 });
12129
- var INSTANT = springMotion({ duration: 0.1, bounce: 0 });
13761
+ var LAYOUT = springMotion(SPRINGS.calm);
13762
+ var ZOOM_IN = springMotion(SPRINGS.smooth);
13763
+ var ZOOM_OUT = springMotion(SPRINGS.calm);
13764
+ var SLIDE2 = springMotion(SPRINGS.default);
13765
+ var SLIDE_OUT = springMotion(SPRINGS.snappy);
13766
+ var ENTER = springMotion(SPRINGS.default);
13767
+ var EXIT2 = springMotion(SPRINGS.snappy);
13768
+ var WASH = springMotion(SPRINGS.snappy);
13769
+ var FADE3 = springMotion(FADE);
13770
+ var INSTANT = springMotion(SPRINGS.instant);
12130
13771
  var SLIDE_BY = 0.12;
12131
13772
  var EXIT_BLUR = 3;
12132
13773
  var px = (x) => new Spring(x, LAYOUT.omega, LAYOUT.zeta, 0.05);
@@ -12169,7 +13810,7 @@ function bento(container, options) {
12169
13810
  root.setAttribute("role", "listbox");
12170
13811
  root.setAttribute("aria-multiselectable", "true");
12171
13812
  root.setAttribute("aria-label", options.label ?? "Ideas");
12172
- applyLook(root, options);
13813
+ applyLook2(root, options);
12173
13814
  const space = doc.createElement("div");
12174
13815
  space.className = "knobs-bento-space";
12175
13816
  const scrim = doc.createElement("div");
@@ -12291,7 +13932,7 @@ function bento(container, options) {
12291
13932
  if (enter && !reduced())
12292
13933
  drive(t.life.snap(0), ENTER, 1);
12293
13934
  else if (enter)
12294
- drive(t.life.snap(0), FADE2, 1);
13935
+ drive(t.life.snap(0), FADE3, 1);
12295
13936
  if (reduced() || !from)
12296
13937
  for (const s of [t.x, t.y, t.w, t.h])
12297
13938
  s.snap(s.target);
@@ -12621,7 +14262,7 @@ function bento(container, options) {
12621
14262
  if (r)
12622
14263
  setBox(t, r.w, r.h);
12623
14264
  if (f.out || f.veil)
12624
- drive(t.life.snap(0), reduced() ? FADE2 : ENTER, 1);
14265
+ drive(t.life.snap(0), reduced() ? FADE3 : ENTER, 1);
12625
14266
  t.drawn = "";
12626
14267
  draw(t);
12627
14268
  syncZoomed();
@@ -12654,7 +14295,7 @@ function bento(container, options) {
12654
14295
  f.z.snap(1);
12655
14296
  f.dx.snap(0);
12656
14297
  f.veil = true;
12657
- drive(f.alpha.snap(f.alpha.target === 0 ? f.alpha.x : 0), FADE2, 1);
14298
+ drive(f.alpha.snap(f.alpha.target === 0 ? f.alpha.x : 0), FADE3, 1);
12658
14299
  } else {
12659
14300
  f.veil = false;
12660
14301
  drive(f.z, ZOOM_IN, 1);
@@ -12689,7 +14330,7 @@ function bento(container, options) {
12689
14330
  revealUnder(f.tile.id);
12690
14331
  if (reduced()) {
12691
14332
  f.veil = true;
12692
- drive(f.alpha, FADE2, 0);
14333
+ drive(f.alpha, FADE3, 0);
12693
14334
  } else
12694
14335
  drive(f.z, ZOOM_OUT, 0);
12695
14336
  syncZoomed();
@@ -12710,7 +14351,7 @@ function bento(container, options) {
12710
14351
  cur.out = true;
12711
14352
  cur.veil = false;
12712
14353
  drive(cur.dx, SLIDE_OUT, -dir * by);
12713
- drive(cur.alpha, reduced() ? FADE2 : SLIDE_OUT, 0);
14354
+ drive(cur.alpha, reduced() ? FADE3 : SLIDE_OUT, 0);
12714
14355
  let f = focusOf(t);
12715
14356
  if (!f) {
12716
14357
  f = beginFocus(t);
@@ -12722,7 +14363,7 @@ function bento(container, options) {
12722
14363
  f.veil = false;
12723
14364
  drive(f.z, ZOOM_IN, 1);
12724
14365
  drive(f.dx, SLIDE2, 0);
12725
- drive(f.alpha, reduced() ? FADE2 : SLIDE2, 1);
14366
+ drive(f.alpha, reduced() ? FADE3 : SLIDE2, 1);
12726
14367
  setActive(id);
12727
14368
  syncZoomed();
12728
14369
  loop.wake();
@@ -13046,7 +14687,7 @@ function bento(container, options) {
13046
14687
  if (f)
13047
14688
  endFocus(f);
13048
14689
  t.leaving = true;
13049
- drive(t.life, reduced() ? FADE2 : EXIT2, 0);
14690
+ drive(t.life, reduced() ? FADE3 : EXIT2, 0);
13050
14691
  }
13051
14692
  items = next;
13052
14693
  reindex();
@@ -13114,6 +14755,7 @@ function bento(container, options) {
13114
14755
  init_diff();
13115
14756
 
13116
14757
  // src/ui/picker.ts
14758
+ init_motion();
13117
14759
  init_look();
13118
14760
 
13119
14761
  // src/ui/picker-model.ts
@@ -13164,10 +14806,10 @@ function settleHeight(previous, now, frames, limit = 6) {
13164
14806
  }
13165
14807
 
13166
14808
  // src/ui/picker.ts
13167
- var OPEN2 = springMotion({ duration: 0.22, bounce: 0 });
13168
- var CLOSE2 = springMotion({ duration: 0.18, bounce: 0 });
13169
- var CARD = springMotion({ duration: 0.3, bounce: 0 });
13170
- var FADE4 = springMotion({ duration: 0.16, bounce: 0 });
14809
+ var OPEN2 = springMotion(SPRINGS.snappy);
14810
+ var CLOSE3 = springMotion(CLOSE);
14811
+ var CARD = springMotion(SPRINGS.default);
14812
+ var FADE5 = springMotion(FADE);
13171
14813
  var DRIFT = 6;
13172
14814
  var CHECK = svg('<path d="m3.5 8.4 3 3 6-6.6"/>');
13173
14815
  function optionPicker(container, options) {
@@ -13189,7 +14831,7 @@ function optionPicker(container, options) {
13189
14831
  root.setAttribute("role", "radiogroup");
13190
14832
  if (options.label)
13191
14833
  root.setAttribute("aria-label", options.label);
13192
- applyLook(root, options);
14834
+ applyLook2(root, options);
13193
14835
  const card = doc.createElement("div");
13194
14836
  card.className = "knobs-picker-card";
13195
14837
  card.setAttribute("aria-hidden", "true");
@@ -13365,10 +15007,10 @@ function optionPicker(container, options) {
13365
15007
  e.body.dataset.moving = "";
13366
15008
  if (reduced) {
13367
15009
  e.h.snap(open ? natural(e) : 0);
13368
- tune(e.o, FADE4).set(open ? 1 : 0);
15010
+ tune(e.o, FADE5).set(open ? 1 : 0);
13369
15011
  } else {
13370
- tune(e.h, open ? OPEN2 : CLOSE2).set(open ? natural(e) : 0);
13371
- tune(e.o, open ? OPEN2 : CLOSE2).set(open ? 1 : 0);
15012
+ tune(e.h, open ? OPEN2 : CLOSE3).set(open ? natural(e) : 0);
15013
+ tune(e.o, open ? OPEN2 : CLOSE3).set(open ? 1 : 0);
13372
15014
  }
13373
15015
  loop.wake();
13374
15016
  };
@@ -13545,7 +15187,7 @@ function optionPicker(container, options) {
13545
15187
  e.head.tabIndex = -1;
13546
15188
  if (e.open)
13547
15189
  setOpen(e, false, true);
13548
- tune(e.presence, reduced ? FADE4 : CLOSE2).set(0);
15190
+ tune(e.presence, reduced ? FADE5 : CLOSE3).set(0);
13549
15191
  }
13550
15192
  let before = card;
13551
15193
  list.forEach((o, i) => {
@@ -13559,7 +15201,7 @@ function optionPicker(container, options) {
13559
15201
  e = make(o);
13560
15202
  ro.observe(e.el);
13561
15203
  if (animate)
13562
- tune(e.presence, reduced ? FADE4 : OPEN2).snap(0).set(1);
15204
+ tune(e.presence, reduced ? FADE5 : OPEN2).snap(0).set(1);
13563
15205
  }
13564
15206
  if (before.nextElementSibling !== e.el)
13565
15207
  before.after(e.el);
@@ -13671,6 +15313,7 @@ function optionPicker(container, options) {
13671
15313
  }
13672
15314
 
13673
15315
  // src/ui/split.ts
15316
+ init_motion();
13674
15317
  init_look();
13675
15318
  init_page_hints();
13676
15319
 
@@ -13854,9 +15497,9 @@ function tooltip(el, content, options = {}) {
13854
15497
 
13855
15498
  // src/ui/split.ts
13856
15499
  init_split_model();
13857
- var FLIP = springMotion({ duration: 0.25, bounce: 0 });
15500
+ var FLIP = springMotion(SPRINGS.snappy);
13858
15501
  var FLIP_DEPTH = 28;
13859
- var SETTLE = springMotion({ duration: 0.3, bounce: 0 });
15502
+ var SETTLE = springMotion(SPRINGS.default);
13860
15503
  var CONTENT_BLUR = 3;
13861
15504
  var LABEL_BLUR = 2;
13862
15505
  var COUNT_CLEAR = 0.12;
@@ -13912,7 +15555,7 @@ function split(container, options) {
13912
15555
  const root = doc.createElement("div");
13913
15556
  root.className = "knobs-split";
13914
15557
  root.dataset.direction = direction;
13915
- applyLook(root, options);
15558
+ applyLook2(root, options);
13916
15559
  const host = container.closest(".knobs-pane");
13917
15560
  host?.setAttribute("data-nested", "");
13918
15561
  const views = new Map;
@@ -14077,7 +15720,7 @@ function split(container, options) {
14077
15720
  const measure = () => {
14078
15721
  syncFrame(root);
14079
15722
  const probe = doc.createElement("div");
14080
- probe.style.cssText = "position:absolute;visibility:hidden;width:var(--ku-rail);height:var(--ku-pane-m)";
15723
+ probe.style.cssText = "position:absolute;visibility:hidden;width:var(--_ku-rail);height:var(--_ku-pane-m)";
14081
15724
  root.append(probe);
14082
15725
  const r = probe.getBoundingClientRect();
14083
15726
  paneM = r.height;
@@ -14131,8 +15774,8 @@ function split(container, options) {
14131
15774
  out[id] = s.x;
14132
15775
  return out;
14133
15776
  };
14134
- const target = () => solve({ panes: specs, sizes, collapsed, total: total(), rail });
14135
- const current = () => solve({ panes: specs, sizes, collapsed, total: total(), rail, fixed: fixed() });
15777
+ const target = () => solve2({ panes: specs, sizes, collapsed, total: total(), rail });
15778
+ const current = () => solve2({ panes: specs, sizes, collapsed, total: total(), rail, fixed: fixed() });
14136
15779
  const SIDES = { row: ["right", "left"], column: ["bottom", "top"] };
14137
15780
  const sides = (v) => {
14138
15781
  const [a, b] = SIDES[direction];
@@ -14183,7 +15826,7 @@ function split(container, options) {
14183
15826
  put(label, "opacity", "");
14184
15827
  put(label, "filter", "");
14185
15828
  put(label, "transform", k === 0 ? "" : `translate(${t.x.toFixed(2)}px,${t.y.toFixed(2)}px) rotate(${t.turn.toFixed(2)}deg)`);
14186
- put(label, "color", k === 0 ? "" : `color-mix(in srgb,var(--ku-text) ${(k * 100).toFixed(1)}%,var(--ku-label))`);
15829
+ put(label, "color", k === 0 ? "" : `color-mix(in srgb,var(--kv-fg) ${(k * 100).toFixed(1)}%,var(--kv-fg-2))`);
14187
15830
  } else {
14188
15831
  put(label, "transform", "");
14189
15832
  put(label, "color", "");
@@ -14473,7 +16116,7 @@ function split(container, options) {
14473
16116
  const first = target();
14474
16117
  for (const spec of specs) {
14475
16118
  const open = { ...collapsed, [spec.id]: false };
14476
- views.get(spec.id).open = collapsed[spec.id] ? solve({ panes: specs, sizes, collapsed: open, total: total(), rail })[spec.id] : first[spec.id];
16119
+ views.get(spec.id).open = collapsed[spec.id] ? solve2({ panes: specs, sizes, collapsed: open, total: total(), rail })[spec.id] : first[spec.id];
14477
16120
  }
14478
16121
  render(first);
14479
16122
  measureChevrons();
@@ -14573,6 +16216,7 @@ init_compare_strip();
14573
16216
  init_tree();
14574
16217
 
14575
16218
  // src/ui/walkthrough.ts
16219
+ init_motion();
14576
16220
  init_page_hints();
14577
16221
 
14578
16222
  // src/ui/confirm.ts
@@ -14656,7 +16300,7 @@ function toast(message, options = {}) {
14656
16300
  const key = options.within ?? doc;
14657
16301
  let r = regions.get(key);
14658
16302
  if (!r || !r.el.isConnected) {
14659
- const el = options.within ? Object.assign(doc.createElement("div"), { className: "knobs-ui knobs-toast" }) : layerElement(doc, "knobs-layer knobs-toast", options.look);
16303
+ const el = options.within ? Object.assign(doc.createElement("div"), { className: "knobs-root knobs-ui knobs-toast" }) : layerElement(doc, "knobs-layer knobs-toast", options.look);
14660
16304
  if (options.within) {
14661
16305
  injectUiStyles(doc);
14662
16306
  options.within.append(el);
@@ -14712,25 +16356,25 @@ function toast(message, options = {}) {
14712
16356
 
14713
16357
  // src/ui/walkthrough-media.ts
14714
16358
  init_compare_model();
16359
+ init_glide();
14715
16360
  init_look();
14716
16361
 
14717
16362
  // src/ui/walkthrough-css.ts
14718
- var snappy3 = springCss({ duration: 0.25, bounce: 0 });
14719
- var calm = springCss({ duration: 0.4, bounce: 0 });
16363
+ init_motion();
16364
+ var snappy3 = springCss(SPRINGS.snappy);
16365
+ var calm = springCss(SPRINGS.calm);
14720
16366
  var walkthroughCss = `
14721
16367
  :where(.knobs-walkthrough,.knobs-walkthrough *,.knobs-wt-slot,.knobs-wt-slot *){box-sizing:border-box}
14722
16368
  .knobs-ui.knobs-walkthrough{--kw-snappy:${snappy3.easing};--kw-snappy-ms:${snappy3.duration}ms;--kw-calm:${calm.easing};--kw-calm-ms:${calm.duration}ms;
14723
- --kw-text:var(--k-walkthrough-text,14px);--kw-measure:var(--k-walkthrough-measure,68ch);--kw-good:var(--k-walkthrough-good,#30d158);--kw-info:var(--k-walkthrough-info,#64d2ff);
14724
- --kw-card:var(--ku-pane-bg);--kw-card-ring:var(--ku-pane-ring);--kw-pad:16px;--kw-ink:var(--k-walkthrough-ink,#ff375f);
14725
- container:knobs-wt / inline-size;display:block;width:100%;color:var(--ku-text);font:var(--ku-font-weight) var(--kw-text)/1.5 var(--ku-font);text-align:left;
16369
+ --kw-text:var(--k-walkthrough-text,14px);--kw-measure:var(--k-walkthrough-measure,68ch);--kw-good:var(--k-walkthrough-good,var(--_k-ok));--kw-info:var(--k-walkthrough-info,var(--_k-info));
16370
+ --kw-card:var(--_ku-pane-bg);--kw-card-ring:var(--_ku-pane-ring);--kw-pad:16px;--kw-ink:var(--k-walkthrough-ink,#ff375f);
16371
+ container:knobs-wt / inline-size;display:block;width:100%;color:var(--_k-fg);font:var(--_k-weight) var(--kw-text)/1.5 var(--_k-font);text-align:left;
14726
16372
  letter-spacing:normal;-webkit-font-smoothing:antialiased}
14727
- .knobs-ui.knobs-walkthrough[data-theme="light"],:where(:root[data-theme="light"]) .knobs-ui.knobs-walkthrough[data-theme="auto"]{--kw-good:var(--k-walkthrough-good,#248a3d);--kw-info:var(--k-walkthrough-info,#0071a4)}
14728
- @media(prefers-color-scheme:light){:where(:root:not([data-theme="dark"])) .knobs-ui.knobs-walkthrough[data-theme="auto"]{--kw-good:var(--k-walkthrough-good,#248a3d);--kw-info:var(--k-walkthrough-info,#0071a4)}}
14729
16373
  .knobs-walkthrough [hidden]{display:none!important}
14730
16374
  .knobs-walkthrough :is(h1,h2,h3,p){margin:0;font:inherit;letter-spacing:inherit}
14731
16375
  .knobs-walkthrough a{color:inherit;text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 35%,transparent);text-underline-offset:2px;transition:text-decoration-color .15s}
14732
16376
  .knobs-walkthrough a:hover{text-decoration-color:currentColor}
14733
- .knobs-walkthrough code,.knobs-wt-slot code{font:calc(1em - 1px) var(--ku-mono);padding:1px 5px;border-radius:5px;background:var(--ku-surface)}
16377
+ .knobs-walkthrough code,.knobs-wt-slot code{font:calc(1em - 1px) var(--_k-mono);padding:1px 5px;border-radius:5px;background:var(--_k-fill)}
14734
16378
  :where(.knobs-ui) :is(.knobs-wt-btn,.knobs-wt-pick,.knobs-wt-toc-step){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;
14735
16379
  background:transparent;border:0;border-radius:0;margin:0;padding:0;min-width:0;box-shadow:none;outline:none}
14736
16380
 
@@ -14741,40 +16385,40 @@ var walkthroughCss = `
14741
16385
 
14742
16386
  /* ——— the page's head ——— */
14743
16387
  .knobs-wt-head{display:flex;flex-direction:column;gap:10px}
14744
- .knobs-wt-title{font-size:calc(var(--kw-text) + 10px)!important;font-weight:var(--ku-title-weight)!important;line-height:1.2;letter-spacing:-.01em!important}
14745
- .knobs-wt-summary{max-width:var(--kw-measure);color:var(--ku-label)}
14746
- .knobs-wt-meta{display:flex;flex-wrap:wrap;gap:6px 16px;color:var(--ku-dim);font-size:calc(var(--kw-text) - 2px)}
16388
+ .knobs-wt-title{font-size:calc(var(--kw-text) + 10px)!important;font-weight:var(--_k-weight-title)!important;line-height:1.2;letter-spacing:-.01em!important}
16389
+ .knobs-wt-summary{max-width:var(--kw-measure);color:var(--_k-fg-2)}
16390
+ .knobs-wt-meta{display:flex;flex-wrap:wrap;gap:6px 16px;color:var(--_k-fg-3);font-size:calc(var(--kw-text) - 2px)}
14747
16391
  .knobs-wt-meta>span{display:inline-flex;gap:6px;white-space:nowrap}
14748
- .knobs-wt-meta b{font-weight:var(--ku-font-weight);color:var(--ku-label);font-family:var(--ku-mono);font-size:calc(1em - .5px)}
16392
+ .knobs-wt-meta b{font-weight:var(--_k-weight);color:var(--_k-fg-2);font-family:var(--_k-mono);font-size:calc(1em - .5px)}
14749
16393
 
14750
16394
  /* ——— a section: a PR or topic ——— */
14751
16395
  .knobs-wt-section{display:flex;flex-direction:column;gap:14px;min-width:0}
14752
16396
  .knobs-wt-shead{display:flex;flex-direction:column;gap:6px;scroll-margin-top:16px}
14753
- .knobs-wt-kicker{display:flex;align-items:center;gap:10px;font-size:calc(var(--kw-text) - 2px);color:var(--ku-dim)}
14754
- .knobs-wt-kicker a{font-family:var(--ku-mono);color:var(--ku-label);text-decoration:none}
14755
- .knobs-wt-kicker a:hover{color:var(--ku-text)}
14756
- .knobs-wt-stitle{font-size:calc(var(--kw-text) + 4px)!important;font-weight:var(--ku-title-weight)!important;line-height:1.3}
14757
- .knobs-wt-ssum{max-width:var(--kw-measure);color:var(--ku-label)}
14758
- .knobs-wt-chip{display:inline-flex;align-items:center;gap:6px;height:20px;padding:0 8px;border-radius:999px;font-size:calc(var(--kw-text) - 3px);font-weight:var(--ku-label-weight);white-space:nowrap;
14759
- --kw-tone:var(--ku-label);color:var(--kw-tone);background:color-mix(in srgb,var(--kw-tone) 14%,transparent)}
16397
+ .knobs-wt-kicker{display:flex;align-items:center;gap:10px;font-size:calc(var(--kw-text) - 2px);color:var(--_k-fg-3)}
16398
+ .knobs-wt-kicker a{font-family:var(--_k-mono);color:var(--_k-fg-2);text-decoration:none}
16399
+ .knobs-wt-kicker a:hover{color:var(--_k-fg)}
16400
+ .knobs-wt-stitle{font-size:calc(var(--kw-text) + 4px)!important;font-weight:var(--_k-weight-title)!important;line-height:1.3}
16401
+ .knobs-wt-ssum{max-width:var(--kw-measure);color:var(--_k-fg-2)}
16402
+ .knobs-wt-chip{display:inline-flex;align-items:center;gap:6px;height:20px;padding:0 8px;border-radius:999px;font-size:calc(var(--kw-text) - 3px);font-weight:var(--_k-weight-label);white-space:nowrap;
16403
+ --kw-tone:var(--_k-fg-2);color:var(--kw-tone);background:color-mix(in srgb,var(--kw-tone) 14%,transparent)}
14760
16404
  .knobs-wt-chip::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}
14761
16405
  :is(.knobs-wt-chip,.knobs-wt-toc-glyph)[data-tone="good"]{--kw-tone:var(--kw-good)}
14762
- :is(.knobs-wt-chip,.knobs-wt-toc-glyph)[data-tone="warn"]{--kw-tone:var(--ku-warn)}
14763
- :is(.knobs-wt-chip,.knobs-wt-toc-glyph)[data-tone="bad"]{--kw-tone:var(--ku-critical)}
16406
+ :is(.knobs-wt-chip,.knobs-wt-toc-glyph)[data-tone="warn"]{--kw-tone:var(--_k-warn)}
16407
+ :is(.knobs-wt-chip,.knobs-wt-toc-glyph)[data-tone="bad"]{--kw-tone:var(--_k-danger)}
14764
16408
  :is(.knobs-wt-chip,.knobs-wt-toc-glyph)[data-tone="info"]{--kw-tone:var(--kw-info)}
14765
- :is(.knobs-wt-chip,.knobs-wt-toc-glyph)[data-tone="dim"]{--kw-tone:var(--ku-label)}
16409
+ :is(.knobs-wt-chip,.knobs-wt-toc-glyph)[data-tone="dim"]{--kw-tone:var(--_k-fg-2)}
14766
16410
 
14767
16411
  /* ——— a step: one card ——— */
14768
- .knobs-wt-step{position:relative;display:flex;flex-direction:column;gap:12px;padding:var(--kw-pad);border-radius:var(--ku-panel-radius);background:var(--kw-card);box-shadow:var(--kw-card-ring);
16412
+ .knobs-wt-step{position:relative;display:flex;flex-direction:column;gap:12px;padding:var(--kw-pad);border-radius:var(--_k-radius-panel);background:var(--kw-card);box-shadow:var(--kw-card-ring);
14769
16413
  scroll-margin-top:16px;outline:none;container:knobs-wt-step / inline-size}
14770
- .knobs-walkthrough[data-frame="flat"] .knobs-wt-step{box-shadow:inset 0 0 0 1px var(--ku-line)}
16414
+ .knobs-walkthrough[data-frame="flat"] .knobs-wt-step{box-shadow:inset 0 0 0 1px var(--_k-border)}
14771
16415
  .knobs-wt-step-head{display:flex;align-items:baseline;gap:10px;min-width:0}
14772
- .knobs-wt-num{flex:none;font:var(--ku-font-weight) calc(var(--kw-text) - 2px)/1 var(--ku-mono);color:var(--ku-dim);font-variant-numeric:tabular-nums}
14773
- .knobs-wt-stepTitle{flex:1;min-width:0;font-weight:var(--ku-title-weight)!important}
14774
- .knobs-wt-caption{max-width:var(--kw-measure);color:var(--ku-label);margin-top:-6px!important}
14775
- .knobs-wt-question{font-weight:var(--ku-label-weight)!important}
16416
+ .knobs-wt-num{flex:none;font:var(--_k-weight) calc(var(--kw-text) - 2px)/1 var(--_k-mono);color:var(--_k-fg-3);font-variant-numeric:tabular-nums}
16417
+ .knobs-wt-stepTitle{flex:1;min-width:0;font-weight:var(--_k-weight-title)!important}
16418
+ .knobs-wt-caption{max-width:var(--kw-measure);color:var(--_k-fg-2);margin-top:-6px!important}
16419
+ .knobs-wt-question{font-weight:var(--_k-weight-label)!important}
14776
16420
  /* The step Kit is on: its number lights, and its choices show their keys. */
14777
- .knobs-wt-step[data-current] .knobs-wt-num{color:var(--ku-text)}
16421
+ .knobs-wt-step[data-current] .knobs-wt-num{color:var(--_k-fg)}
14778
16422
  .knobs-wt-media{display:grid;grid-template-columns:repeat(var(--kw-n,1),minmax(0,1fr));gap:12px;min-width:0}
14779
16423
  @container knobs-wt-step (max-width:640px){.knobs-wt-media{grid-template-columns:minmax(0,1fr)}}
14780
16424
 
@@ -14783,16 +16427,16 @@ var walkthroughCss = `
14783
16427
  .knobs-wt-feed-list{list-style:none;margin:0;padding:0;max-height:260px;overflow:auto;scrollbar-width:none;display:flex;flex-direction:column}
14784
16428
  .knobs-wt-feed-list::-webkit-scrollbar{display:none}
14785
16429
  .knobs-wt-fi{display:grid;grid-template-columns:64px 56px minmax(0,1fr) auto;gap:10px;align-items:baseline;padding:6px 0;font-size:calc(var(--kw-text) - 1px)}
14786
- .knobs-wt-fi+.knobs-wt-fi{box-shadow:inset 0 1px 0 var(--ku-line)}
14787
- .knobs-wt-fi-when{color:var(--ku-dim);font-size:calc(var(--kw-text) - 2.5px);font-variant-numeric:tabular-nums;white-space:nowrap}
14788
- .knobs-wt-fi-kind{color:var(--ku-label);font-size:calc(var(--kw-text) - 2.5px);font-weight:var(--ku-label-weight)}
16430
+ .knobs-wt-fi+.knobs-wt-fi{box-shadow:inset 0 1px 0 var(--_k-border)}
16431
+ .knobs-wt-fi-when{color:var(--_k-fg-3);font-size:calc(var(--kw-text) - 2.5px);font-variant-numeric:tabular-nums;white-space:nowrap}
16432
+ .knobs-wt-fi-kind{color:var(--_k-fg-2);font-size:calc(var(--kw-text) - 2.5px);font-weight:var(--_k-weight-label)}
14789
16433
  .knobs-wt-fi[data-kind="qa"] .knobs-wt-fi-kind{color:var(--kw-info)}
14790
- .knobs-wt-fi-body{max-width:var(--kw-measure);color:var(--ku-text)}
14791
- .knobs-wt-fi-q{color:var(--ku-label)}
14792
- .knobs-wt-fi-q::before{content:"You asked: ";color:var(--ku-dim)}
14793
- :where(.knobs-ui) .knobs-wt-fi-step{all:revert;box-sizing:border-box;font:var(--ku-font-weight) calc(var(--kw-text) - 2.5px)/1 var(--ku-mono);color:var(--ku-label);background:transparent;border:0;
16434
+ .knobs-wt-fi-body{max-width:var(--kw-measure);color:var(--_k-fg)}
16435
+ .knobs-wt-fi-q{color:var(--_k-fg-2)}
16436
+ .knobs-wt-fi-q::before{content:"You asked: ";color:var(--_k-fg-3)}
16437
+ :where(.knobs-ui) .knobs-wt-fi-step{all:revert;box-sizing:border-box;font:var(--_k-weight) calc(var(--kw-text) - 2.5px)/1 var(--_k-mono);color:var(--_k-fg-2);background:transparent;border:0;
14794
16438
  padding:3px 6px;margin:0;border-radius:6px;cursor:pointer;outline:none;transition:background .15s,color .15s}
14795
- .knobs-ui .knobs-wt-fi-step:is(:hover,:focus-visible){background:var(--ku-wash-hi);color:var(--ku-text)}
16439
+ .knobs-ui .knobs-wt-fi-step:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
14796
16440
 
14797
16441
  /* ——— a step's sent notes ——— */
14798
16442
  .knobs-wt-notes{display:flex;flex-direction:column}
@@ -14801,47 +16445,47 @@ var walkthroughCss = `
14801
16445
  transition:height var(--kw-snappy-ms) var(--kw-snappy),opacity var(--kw-snappy-ms) var(--kw-snappy),filter var(--kw-snappy-ms) var(--kw-snappy)}
14802
16446
  .knobs-wt-n[data-entering]{opacity:0;filter:blur(3px)}
14803
16447
  .knobs-wt-n[data-leaving]{opacity:0;filter:blur(3px);padding-block:0}
14804
- .knobs-wt-n+.knobs-wt-n{box-shadow:inset 0 1px 0 var(--ku-line)}
14805
- .knobs-wt-n-meta{flex:none;min-width:44px;padding-top:2px;color:var(--ku-dim);font:var(--ku-font-weight) calc(var(--kw-text) - 2.5px)/1.4 var(--ku-mono);font-variant-numeric:tabular-nums}
16448
+ .knobs-wt-n+.knobs-wt-n{box-shadow:inset 0 1px 0 var(--_k-border)}
16449
+ .knobs-wt-n-meta{flex:none;min-width:44px;padding-top:2px;color:var(--_k-fg-3);font:var(--_k-weight) calc(var(--kw-text) - 2.5px)/1.4 var(--_k-mono);font-variant-numeric:tabular-nums}
14806
16450
  .knobs-wt-n-meta[data-seek]{cursor:pointer}
14807
- .knobs-wt-n-meta[data-seek]:hover{color:var(--ku-text)}
16451
+ .knobs-wt-n-meta[data-seek]:hover{color:var(--_k-fg)}
14808
16452
  .knobs-wt-n-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px;font-size:calc(var(--kw-text) - 1px)}
14809
16453
  .knobs-wt-n-voice{height:30px;max-width:320px}
14810
- .knobs-wt-n-ink{display:block;width:120px;max-height:80px;border-radius:6px;background:var(--ku-surface)}
16454
+ .knobs-wt-n-ink{display:block;width:120px;max-height:80px;border-radius:6px;background:var(--_k-fill)}
14811
16455
  .knobs-wt-n-ink path{fill:none;stroke:var(--kw-ink);stroke-width:2px;vector-effect:non-scaling-stroke;stroke-linecap:round;stroke-linejoin:round}
14812
16456
 
14813
16457
  /* ——— the note bar, docked at the bottom of the column ——— */
14814
16458
  .knobs-wt-dock{position:sticky;bottom:12px;z-index:40;margin-top:-24px}
14815
- .knobs-wt-notebar{display:flex;flex-direction:column;gap:2px;padding:6px 6px 6px 14px;border-radius:calc(var(--ku-panel-radius) + 2px);background:var(--ku-bg);
14816
- box-shadow:var(--ku-pane-ring),var(--ku-shadow)}
14817
- .knobs-wt-on{padding-top:3px;color:var(--ku-dim);font-size:calc(var(--kw-text) - 2.5px);white-space:nowrap;overflow:hidden;
16459
+ .knobs-wt-notebar{display:flex;flex-direction:column;gap:2px;padding:6px 6px 6px 14px;border-radius:calc(var(--_k-radius-panel) + 2px);background:var(--_k-bg);
16460
+ box-shadow:var(--_ku-pane-ring),var(--_k-shadow-overlay)}
16461
+ .knobs-wt-on{padding-top:3px;color:var(--_k-fg-3);font-size:calc(var(--kw-text) - 2.5px);white-space:nowrap;overflow:hidden;
14818
16462
  -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 1.5em),transparent);mask-image:linear-gradient(to right,#000 calc(100% - 1.5em),transparent)}
14819
16463
  .knobs-wt-row{display:flex;align-items:flex-end;gap:4px}
14820
16464
  :where(.knobs-ui) :is(.knobs-wt-input,.knobs-wt-tool,.knobs-wt-x,.knobs-wt-back){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:0;
14821
16465
  border-radius:0;margin:0;padding:0;min-width:0;box-shadow:none;outline:none}
14822
- .knobs-ui .knobs-wt-input{flex:1;min-width:0;height:32px;max-height:140px;padding:6px 0;resize:none;color:var(--ku-text);caret-color:var(--ku-accent);line-height:20px;font-size:var(--kw-text)}
14823
- .knobs-ui .knobs-wt-input::placeholder{color:var(--ku-dim)}
16466
+ .knobs-ui .knobs-wt-input{flex:1;min-width:0;height:32px;max-height:140px;padding:6px 0;resize:none;color:var(--_k-fg);caret-color:var(--_k-accent);line-height:20px;font-size:var(--kw-text)}
16467
+ .knobs-ui .knobs-wt-input::placeholder{color:var(--_k-fg-3)}
14824
16468
  .knobs-wt-attach{display:flex;gap:4px;align-items:center;align-self:center}
14825
16469
  .knobs-wt-attach:empty{display:none}
14826
- .knobs-wt-chip-a{display:inline-flex;align-items:center;gap:2px;height:24px;padding:0 2px 0 9px;border-radius:999px;background:var(--ku-surface-hi);font-size:calc(var(--kw-text) - 2.5px);white-space:nowrap}
14827
- .knobs-ui .knobs-wt-x{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;color:var(--ku-dim);cursor:pointer;transition:background .15s,color .15s}
14828
- .knobs-ui .knobs-wt-x:is(:hover,:focus-visible){background:var(--ku-wash-hi);color:var(--ku-text)}
16470
+ .knobs-wt-chip-a{display:inline-flex;align-items:center;gap:2px;height:24px;padding:0 2px 0 9px;border-radius:999px;background:var(--_k-fill-selected);font-size:calc(var(--kw-text) - 2.5px);white-space:nowrap}
16471
+ .knobs-ui .knobs-wt-x{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;color:var(--_k-fg-3);cursor:pointer;transition:background .15s,color .15s}
16472
+ .knobs-ui .knobs-wt-x:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
14829
16473
  .knobs-wt-x svg{width:10px;height:10px}
14830
- .knobs-ui .knobs-wt-tool{flex:none;display:inline-flex;align-items:center;justify-content:center;gap:5px;min-width:32px;height:32px;padding:0 8px;border-radius:calc(var(--ku-radius) + 2px);
14831
- color:var(--ku-label);cursor:pointer;transition:background .15s,color .15s}
14832
- .knobs-ui .knobs-wt-tool:is(:hover,:focus-visible){background:var(--ku-wash-hi);color:var(--ku-text)}
14833
- .knobs-ui .knobs-wt-tool[aria-pressed="true"]{background:var(--ku-surface-hi);color:var(--ku-text)}
16474
+ .knobs-ui .knobs-wt-tool{flex:none;display:inline-flex;align-items:center;justify-content:center;gap:5px;min-width:32px;height:32px;padding:0 8px;border-radius:calc(var(--_k-radius) + 2px);
16475
+ color:var(--_k-fg-2);cursor:pointer;transition:background .15s,color .15s}
16476
+ .knobs-ui .knobs-wt-tool:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
16477
+ .knobs-ui .knobs-wt-tool[aria-pressed="true"]{background:var(--_k-fill-selected);color:var(--_k-fg)}
14834
16478
  .knobs-wt-tool svg{width:15px;height:15px}
14835
16479
  .knobs-wt-rec{font-size:calc(var(--kw-text) - 2.5px);font-variant-numeric:tabular-nums}
14836
16480
  .knobs-wt-rec:empty{display:none}
14837
- .knobs-ui .knobs-wt-tool[data-send]{color:var(--ku-dim)}
14838
- .knobs-ui .knobs-wt-tool[data-send][data-ready]{background:var(--ku-accent);color:var(--ku-bg)}
16481
+ .knobs-ui .knobs-wt-tool[data-send]{color:var(--_k-fg-3)}
16482
+ .knobs-ui .knobs-wt-tool[data-send][data-ready]{background:var(--_k-accent);color:var(--_k-bg)}
14839
16483
  /* Back: in place over the bar for a few seconds after a note moves the page on. */
14840
- .knobs-ui .knobs-wt-back{position:absolute;left:8px;bottom:calc(100% + 8px);height:28px;padding:0 12px;border-radius:999px;background:var(--ku-bg);color:var(--ku-text);
14841
- box-shadow:var(--ku-pane-ring),var(--ku-shadow);font-size:calc(var(--kw-text) - 1.5px);font-weight:var(--ku-label-weight);cursor:pointer;
16484
+ .knobs-ui .knobs-wt-back{position:absolute;left:8px;bottom:calc(100% + 8px);height:28px;padding:0 12px;border-radius:999px;background:var(--_k-bg);color:var(--_k-fg);
16485
+ box-shadow:var(--_ku-pane-ring),var(--_k-shadow-overlay);font-size:calc(var(--kw-text) - 1.5px);font-weight:var(--_k-weight-label);cursor:pointer;
14842
16486
  opacity:0;scale:.96;filter:blur(3px);pointer-events:none;transition:opacity .11s cubic-bezier(.4,0,1,1),scale .11s cubic-bezier(.4,0,1,1),filter .11s cubic-bezier(.4,0,1,1)}
14843
16487
  .knobs-ui .knobs-wt-back[data-on]{opacity:1;scale:1;filter:none;pointer-events:auto;transition:opacity .15s cubic-bezier(.2,.8,.2,1),scale .15s cubic-bezier(.2,.8,.2,1),filter .15s cubic-bezier(.2,.8,.2,1)}
14844
- .knobs-ui .knobs-wt-back:hover{background:var(--ku-surface-hi)}
16488
+ .knobs-ui .knobs-wt-back:hover{background:var(--_k-fill-selected)}
14845
16489
 
14846
16490
  /* ——— ink over a step's media ——— */
14847
16491
  .knobs-wt-media,.knobs-wt-options{position:relative}
@@ -14850,10 +16494,10 @@ var walkthroughCss = `
14850
16494
  .knobs-wt-ink path{fill:none;stroke:var(--kw-ink);stroke-width:3px;vector-effect:non-scaling-stroke;stroke-linecap:round;stroke-linejoin:round}
14851
16495
 
14852
16496
  /* ——— full-window: the step over the page, its media filling it; its place held in the page ——— */
14853
- .knobs-wt-scrim{position:fixed;inset:0;z-index:30;background:color-mix(in srgb,var(--ku-page) 82%,transparent);opacity:0;pointer-events:none}
16497
+ .knobs-wt-scrim{position:fixed;inset:0;z-index:30;background:color-mix(in srgb,var(--_k-bg-page) 82%,transparent);opacity:0;pointer-events:none}
14854
16498
  .knobs-wt-scrim[data-on]{pointer-events:auto}
14855
16499
  .knobs-wt-hold-card{flex:none}
14856
- .knobs-wt-step[data-full]{position:fixed;z-index:35;margin:0;overflow:hidden;overscroll-behavior:contain;padding-bottom:84px;box-shadow:var(--kw-card-ring),var(--ku-shadow);background:var(--ku-bg)}
16500
+ .knobs-wt-step[data-full]{position:fixed;z-index:35;margin:0;overflow:hidden;overscroll-behavior:contain;padding-bottom:84px;box-shadow:var(--kw-card-ring),var(--_k-shadow-overlay);background:var(--_k-bg)}
14857
16501
  .knobs-wt-step[data-full]>:not(.knobs-wt-media){flex:none}
14858
16502
  .knobs-wt-step[data-full] .knobs-wt-notes{display:none}
14859
16503
  .knobs-wt-step[data-full]>.knobs-wt-media{flex:1;min-height:0;grid-auto-rows:minmax(0,1fr)}
@@ -14865,71 +16509,71 @@ var walkthroughCss = `
14865
16509
  /* ——— a taste test: the options side by side, Kit's pick lit and the rest stepping back ——— */
14866
16510
  .knobs-wt-options{display:grid;grid-template-columns:repeat(var(--kw-n,2),minmax(0,1fr));gap:10px}
14867
16511
  @container knobs-wt-step (max-width:640px){.knobs-wt-options{grid-template-columns:minmax(0,1fr)}}
14868
- .knobs-wt-option{position:relative;display:flex;flex-direction:column;gap:8px;min-width:0;padding:8px;border-radius:calc(var(--ku-panel-radius) - 4px);background:var(--ku-wash);
16512
+ .knobs-wt-option{position:relative;display:flex;flex-direction:column;gap:8px;min-width:0;padding:8px;border-radius:calc(var(--_k-radius-panel) - 4px);background:var(--_ku-wash);
14869
16513
  transition:background var(--kw-snappy-ms) var(--kw-snappy)}
14870
- .knobs-wt-option[data-picked]{background:color-mix(in srgb,var(--ku-accent) 12%,var(--ku-wash))}
16514
+ .knobs-wt-option[data-picked]{background:color-mix(in srgb,var(--_k-accent) 12%,var(--_ku-wash))}
14871
16515
  .knobs-wt-option>:not(.knobs-wt-pick){transition:opacity var(--kw-snappy-ms) var(--kw-snappy)}
14872
16516
  .knobs-wt-options[data-has-pick] .knobs-wt-option:not([data-picked])>:not(.knobs-wt-pick){opacity:.55}
14873
- .knobs-ui .knobs-wt-pick{display:flex;align-items:center;gap:8px;width:100%;min-height:28px;padding:0 4px;border-radius:calc(var(--ku-radius) - 2px);cursor:pointer;color:var(--ku-label);text-align:left}
14874
- .knobs-ui .knobs-wt-pick:is(:hover,:focus-visible){color:var(--ku-text)}
14875
- .knobs-wt-letter{flex:none;font:var(--ku-title-weight) calc(var(--kw-text) - 1px)/1 var(--ku-font);color:var(--ku-text)}
14876
- .knobs-wt-olabel{flex:1;min-width:0;font-weight:var(--ku-label-weight);color:var(--ku-text)}
14877
- .knobs-wt-suggested{flex:none;font-size:calc(var(--kw-text) - 3px);color:var(--ku-dim)}
14878
- .knobs-wt-check{flex:none;display:flex;width:18px;height:18px;align-items:center;justify-content:center;border-radius:50%;background:var(--ku-surface);color:transparent;
16517
+ .knobs-ui .knobs-wt-pick{display:flex;align-items:center;gap:8px;width:100%;min-height:28px;padding:0 4px;border-radius:calc(var(--_k-radius) - 2px);cursor:pointer;color:var(--_k-fg-2);text-align:left}
16518
+ .knobs-ui .knobs-wt-pick:is(:hover,:focus-visible){color:var(--_k-fg)}
16519
+ .knobs-wt-letter{flex:none;font:var(--_k-weight-title) calc(var(--kw-text) - 1px)/1 var(--_k-font);color:var(--_k-fg)}
16520
+ .knobs-wt-olabel{flex:1;min-width:0;font-weight:var(--_k-weight-label);color:var(--_k-fg)}
16521
+ .knobs-wt-suggested{flex:none;font-size:calc(var(--kw-text) - 3px);color:var(--_k-fg-3)}
16522
+ .knobs-wt-check{flex:none;display:flex;width:18px;height:18px;align-items:center;justify-content:center;border-radius:50%;background:var(--_k-fill);color:transparent;
14879
16523
  transition:background var(--kw-snappy-ms) var(--kw-snappy),color var(--kw-snappy-ms) var(--kw-snappy)}
14880
16524
  .knobs-wt-check svg{width:12px;height:12px}
14881
- .knobs-wt-option[data-picked] .knobs-wt-check{background:var(--ku-accent);color:var(--ku-bg)}
14882
- .knobs-wt-key{display:inline-flex;align-items:center;justify-content:center;min-width:15px;height:15px;padding:0 3px;border-radius:4px;background:var(--ku-surface);color:var(--ku-dim);
14883
- font:var(--ku-label-weight) calc(var(--kw-text) - 4px)/1 var(--ku-font);font-variant-numeric:tabular-nums;opacity:.5;transition:opacity .15s}
16525
+ .knobs-wt-option[data-picked] .knobs-wt-check{background:var(--_k-accent);color:var(--_k-bg)}
16526
+ .knobs-wt-key{display:inline-flex;align-items:center;justify-content:center;min-width:15px;height:15px;padding:0 3px;border-radius:4px;background:var(--_k-fill);color:var(--_k-fg-3);
16527
+ font:var(--_k-weight-label) calc(var(--kw-text) - 4px)/1 var(--_k-font);font-variant-numeric:tabular-nums;opacity:.5;transition:opacity .15s}
14884
16528
  .knobs-wt-step[data-current] .knobs-wt-key{opacity:1}
14885
- .knobs-wt-ocap{color:var(--ku-label);font-size:calc(var(--kw-text) - 1px);padding:0 4px}
16529
+ .knobs-wt-ocap{color:var(--_k-fg-2);font-size:calc(var(--kw-text) - 1px);padding:0 4px}
14886
16530
 
14887
16531
  /* ——— the rail: progress, contents, export ——— */
14888
16532
  .knobs-wt-rail{position:sticky;top:16px;display:flex;flex-direction:column;gap:14px;max-height:calc(100vh - 32px);min-height:0;font-size:calc(var(--kw-text) - 1.5px)}
14889
16533
  .knobs-wt-progress{display:flex;flex-direction:column;gap:7px}
14890
- .knobs-wt-count{display:flex;align-items:baseline;justify-content:space-between;color:var(--ku-label);font-variant-numeric:tabular-nums}
14891
- .knobs-wt-count b{color:var(--ku-text);font-weight:var(--ku-label-weight)}
14892
- .knobs-wt-bar{position:relative;height:4px;border-radius:2px;overflow:hidden;background:var(--ku-surface)}
14893
- .knobs-wt-fill{position:absolute;inset:0;border-radius:inherit;background:var(--ku-accent);transform-origin:0 50%;transform:scaleX(var(--kw-done,0))}
16534
+ .knobs-wt-count{display:flex;align-items:baseline;justify-content:space-between;color:var(--_k-fg-2);font-variant-numeric:tabular-nums}
16535
+ .knobs-wt-count b{color:var(--_k-fg);font-weight:var(--_k-weight-label)}
16536
+ .knobs-wt-bar{position:relative;height:4px;border-radius:2px;overflow:hidden;background:var(--_k-fill)}
16537
+ .knobs-wt-fill{position:absolute;inset:0;border-radius:inherit;background:var(--_k-accent);transform-origin:0 50%;transform:scaleX(var(--kw-done,0))}
14894
16538
  .knobs-walkthrough[data-settled] .knobs-wt-fill{transition:transform var(--kw-calm-ms) var(--kw-calm)}
14895
16539
  /* The contents: no box, one text spine for sections and steps (the steps' dots hang in the
14896
16540
  gutter left of it), and one pill behind the current step that springs between rows. */
14897
16541
  .knobs-wt-toc{position:relative;flex:1 1 auto;min-height:0;overflow:auto;scrollbar-width:none;margin:0 -8px;padding:0 0 8px}
14898
16542
  .knobs-wt-toc::-webkit-scrollbar{display:none}
14899
- .knobs-wt-toc-section{display:block;padding:12px 8px 4px 26px;color:var(--ku-dim);font-size:calc(var(--kw-text) - 3px);font-weight:var(--ku-label-weight);white-space:nowrap;overflow:hidden;
16543
+ .knobs-wt-toc-section{display:block;padding:12px 8px 4px 26px;color:var(--_k-fg-3);font-size:calc(var(--kw-text) - 3px);font-weight:var(--_k-weight-label);white-space:nowrap;overflow:hidden;
14900
16544
  -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 1.5em),transparent);mask-image:linear-gradient(to right,#000 calc(100% - 1.5em),transparent)}
14901
16545
  .knobs-wt-toc-section:first-of-type{padding-top:2px}
14902
- .knobs-wt-toc-mark{position:absolute;left:0;right:0;top:0;height:0;border-radius:calc(var(--ku-radius) - 1px);background:var(--ku-wash-hi);pointer-events:none;opacity:0;will-change:transform}
16546
+ .knobs-wt-toc-mark{position:absolute;left:0;right:0;top:0;height:0;border-radius:calc(var(--_k-radius) - 1px);background:var(--_ku-wash-hi);pointer-events:none;opacity:0;will-change:transform}
14903
16547
  .knobs-wt-toc-mark[data-on]{opacity:1}
14904
16548
  .knobs-walkthrough[data-settled] .knobs-wt-toc-mark{transition:opacity .15s}
14905
- .knobs-ui .knobs-wt-toc-step{position:relative;display:flex;align-items:center;width:100%;text-align:left;height:26px;padding:0 8px 0 26px;color:var(--ku-label);cursor:pointer;white-space:nowrap}
14906
- .knobs-ui .knobs-wt-toc-step:is(:hover,:focus-visible){color:var(--ku-text)}
14907
- .knobs-wt-toc-step[aria-current="step"]{color:var(--ku-text)}
16549
+ .knobs-ui .knobs-wt-toc-step{position:relative;display:flex;align-items:center;width:100%;text-align:left;height:26px;padding:0 8px 0 26px;color:var(--_k-fg-2);cursor:pointer;white-space:nowrap}
16550
+ .knobs-ui .knobs-wt-toc-step:is(:hover,:focus-visible){color:var(--_k-fg)}
16551
+ .knobs-wt-toc-step[aria-current="step"]{color:var(--_k-fg)}
14908
16552
  .knobs-wt-toc-label{flex:1;min-width:0;overflow:hidden;-webkit-mask-image:linear-gradient(to right,#000 calc(100% - 1.5em),transparent);mask-image:linear-gradient(to right,#000 calc(100% - 1.5em),transparent)}
14909
16553
  /* A step's state: an open ring, a filled dot once answered, nothing to answer a faint ring. */
14910
- .knobs-wt-toc-glyph{--kw-tone:var(--ku-dim);position:absolute;left:11px;top:50%;width:7px;height:7px;margin-top:-3.5px;border-radius:50%;box-shadow:inset 0 0 0 1.5px var(--kw-tone);
16554
+ .knobs-wt-toc-glyph{--kw-tone:var(--_k-fg-3);position:absolute;left:11px;top:50%;width:7px;height:7px;margin-top:-3.5px;border-radius:50%;box-shadow:inset 0 0 0 1.5px var(--kw-tone);
14911
16555
  transition:background var(--kw-snappy-ms) var(--kw-snappy),box-shadow var(--kw-snappy-ms) var(--kw-snappy)}
14912
- .knobs-wt-toc-glyph[data-tone="accent"]{--kw-tone:var(--ku-accent)}
16556
+ .knobs-wt-toc-glyph[data-tone="accent"]{--kw-tone:var(--_k-accent)}
14913
16557
  .knobs-wt-toc-glyph[data-done]{background:var(--kw-tone)}
14914
- .knobs-wt-toc-glyph[data-tone="none"]{box-shadow:inset 0 0 0 1px var(--ku-line)}
16558
+ .knobs-wt-toc-glyph[data-tone="none"]{box-shadow:inset 0 0 0 1px var(--_k-border)}
14915
16559
  .knobs-wt-actions{display:flex;flex-wrap:wrap;gap:4px}
14916
- .knobs-ui .knobs-wt-btn{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 9px;border-radius:var(--ku-radius);color:var(--ku-label);cursor:pointer;white-space:nowrap;
16560
+ .knobs-ui .knobs-wt-btn{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 9px;border-radius:var(--_k-radius);color:var(--_k-fg-2);cursor:pointer;white-space:nowrap;
14917
16561
  transition:background .15s,color .15s}
14918
- .knobs-ui .knobs-wt-btn:is(:hover,:focus-visible){background:var(--ku-wash-hi);color:var(--ku-text)}
14919
- .knobs-ui .knobs-wt-btn[data-primary]{background:var(--ku-surface-hi);color:var(--ku-text)}
14920
- .knobs-ui .knobs-wt-btn[data-primary]:is(:hover,:focus-visible){background:color-mix(in srgb,var(--ku-text) 16%,transparent)}
14921
- .knobs-wt-keys{color:var(--ku-dim);font-size:calc(var(--kw-text) - 3px);line-height:1.6}
14922
- .knobs-wt-keys kbd{font:inherit;color:var(--ku-label)}
16562
+ .knobs-ui .knobs-wt-btn:is(:hover,:focus-visible){background:var(--_ku-wash-hi);color:var(--_k-fg)}
16563
+ .knobs-ui .knobs-wt-btn[data-primary]{background:var(--_k-fill-selected);color:var(--_k-fg)}
16564
+ .knobs-ui .knobs-wt-btn[data-primary]:is(:hover,:focus-visible){background:color-mix(in srgb,var(--_k-fg) 16%,transparent)}
16565
+ .knobs-wt-keys{color:var(--_k-fg-3);font-size:calc(var(--kw-text) - 3px);line-height:1.6}
16566
+ .knobs-wt-keys kbd{font:inherit;color:var(--_k-fg-2)}
14923
16567
  /* Narrow: the rail becomes a bar along the top, with the progress and the export only. */
14924
16568
  @container knobs-wt (max-width:880px){
14925
- .knobs-wt-rail{z-index:4;flex-direction:row;align-items:center;gap:12px;max-height:none;margin:0 calc(var(--kw-pad) * -1) 20px;padding:8px var(--kw-pad);top:0;background:var(--ku-page)}
16569
+ .knobs-wt-rail{z-index:4;flex-direction:row;align-items:center;gap:12px;max-height:none;margin:0 calc(var(--kw-pad) * -1) 20px;padding:8px var(--kw-pad);top:0;background:var(--_k-bg-page)}
14926
16570
  .knobs-wt-progress{flex:1}.knobs-wt-toc,.knobs-wt-keys{display:none}
14927
16571
  .knobs-wt-step,.knobs-wt-shead{scroll-margin-top:60px}
14928
16572
  }
14929
16573
 
14930
16574
  /* ——— media slots ——— */
14931
- .knobs-ui.knobs-wt-slot{position:relative;min-width:0;container:knobs-wt-slot / inline-size;color:var(--ku-text);font:var(--ku-font-weight) var(--k-walkthrough-text,14px)/1.5 var(--ku-font)}
14932
- .knobs-wt-slot-label{display:block;margin:0 0 6px 2px;font:var(--ku-label-weight) calc(var(--k-walkthrough-text,14px) - 3px)/1.3 var(--ku-font);color:var(--ku-label);letter-spacing:.04em;text-transform:uppercase}
16575
+ .knobs-ui.knobs-wt-slot{position:relative;min-width:0;container:knobs-wt-slot / inline-size;color:var(--_k-fg);font:var(--_k-weight) var(--k-walkthrough-text,14px)/1.5 var(--_k-font)}
16576
+ .knobs-wt-slot-label{display:block;margin:0 0 6px 2px;font:var(--_k-weight-label) calc(var(--k-walkthrough-text,14px) - 3px)/1.3 var(--_k-font);color:var(--_k-fg-2);letter-spacing:.04em;text-transform:uppercase}
14933
16577
  /* A compare is exactly as tall as its pictures at this width, so there's no letterbox: the two
14934
16578
  sides edge to edge (side) or one (overlaid), plus its mode bar, the timeline and their two gaps
14935
16579
  (92 px), and the frame strip with its gap (158 px). */
@@ -14937,37 +16581,37 @@ var walkthroughCss = `
14937
16581
  .knobs-wt-fit[data-overlay]{height:calc(100cqw / var(--kw-aspect,1.7778) + var(--kw-chrome,92px))}
14938
16582
  .knobs-wt-fit[data-strip]{--kw-chrome:158px}
14939
16583
  .knobs-wt-fit[data-settled]{transition:height var(--k-wt-calm-ms,${calm.duration}ms) ${calm.easing}}
14940
- .knobs-wt-frame{position:relative;width:100%;overflow:hidden;border-radius:calc(var(--ku-panel-radius) - 4px);background:var(--ku-surface);aspect-ratio:var(--kw-aspect,16/9)}
16584
+ .knobs-wt-frame{position:relative;width:100%;overflow:hidden;border-radius:calc(var(--_k-radius-panel) - 4px);background:var(--_k-fill);aspect-ratio:var(--kw-aspect,16/9)}
14941
16585
  .knobs-wt-frame>:is(video,img){position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:contain;margin:0;border:0}
14942
16586
  .knobs-wt-frame[data-natural]{aspect-ratio:auto}
14943
16587
  .knobs-wt-frame[data-natural]>img{position:static;height:auto}
14944
- .knobs-wt-code{margin:0;padding:12px 14px;max-height:420px;overflow:auto;border-radius:calc(var(--ku-panel-radius) - 4px);background:var(--ku-surface);color:var(--ku-text);
14945
- font:calc(var(--k-walkthrough-text,14px) - 2px)/1.55 var(--ku-mono);white-space:pre;tab-size:2;scrollbar-width:thin}
16588
+ .knobs-wt-code{margin:0;padding:12px 14px;max-height:420px;overflow:auto;border-radius:calc(var(--_k-radius-panel) - 4px);background:var(--_k-fill);color:var(--_k-fg);
16589
+ font:calc(var(--k-walkthrough-text,14px) - 2px)/1.55 var(--_k-mono);white-space:pre;tab-size:2;scrollbar-width:thin}
14946
16590
  .knobs-wt-code[data-terminal]{white-space:pre-wrap;overflow-wrap:anywhere}
14947
- .knobs-wt-prompt{color:var(--ku-dim);user-select:none;-webkit-user-select:none}
14948
- .knobs-wt-cmd{color:var(--ku-text);font-weight:var(--ku-label-weight)}
14949
- .knobs-wt-out{color:var(--ku-label)}
14950
- .knobs-wt-metric{display:flex;flex-direction:column;gap:8px;padding:12px 14px;border-radius:calc(var(--ku-panel-radius) - 4px);background:var(--ku-surface)}
14951
- .knobs-wt-mlabel{color:var(--ku-label);font-size:calc(var(--k-walkthrough-text,14px) - 2px)}
16591
+ .knobs-wt-prompt{color:var(--_k-fg-3);user-select:none;-webkit-user-select:none}
16592
+ .knobs-wt-cmd{color:var(--_k-fg);font-weight:var(--_k-weight-label)}
16593
+ .knobs-wt-out{color:var(--_k-fg-2)}
16594
+ .knobs-wt-metric{display:flex;flex-direction:column;gap:8px;padding:12px 14px;border-radius:calc(var(--_k-radius-panel) - 4px);background:var(--_k-fill)}
16595
+ .knobs-wt-mlabel{color:var(--_k-fg-2);font-size:calc(var(--k-walkthrough-text,14px) - 2px)}
14952
16596
  .knobs-wt-mvalue{display:flex;align-items:baseline;flex-wrap:wrap;gap:8px;font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
14953
- .knobs-wt-mfrom{color:var(--ku-dim);font-size:calc(var(--k-walkthrough-text,14px) + 2px)}
14954
- .knobs-wt-mto{font-size:calc(var(--k-walkthrough-text,14px) + 12px);font-weight:var(--ku-title-weight);line-height:1}
14955
- .knobs-wt-mof{color:var(--ku-dim)}
14956
- .knobs-wt-mdelta{--kw-tone:var(--ku-label);padding:1px 7px;border-radius:999px;font-size:calc(var(--k-walkthrough-text,14px) - 3px);font-weight:var(--ku-label-weight);color:var(--kw-tone);background:color-mix(in srgb,var(--kw-tone) 14%,transparent)}
14957
- .knobs-wt-mdelta[data-tone="good"]{--kw-tone:var(--k-walkthrough-good,#30d158)}
14958
- .knobs-wt-mdelta[data-tone="bad"]{--kw-tone:var(--ku-critical)}
14959
- .knobs-wt-mtrack{position:relative;height:4px;border-radius:2px;background:color-mix(in srgb,var(--ku-text) 8%,transparent)}
16597
+ .knobs-wt-mfrom{color:var(--_k-fg-3);font-size:calc(var(--k-walkthrough-text,14px) + 2px)}
16598
+ .knobs-wt-mto{font-size:calc(var(--k-walkthrough-text,14px) + 12px);font-weight:var(--_k-weight-title);line-height:1}
16599
+ .knobs-wt-mof{color:var(--_k-fg-3)}
16600
+ .knobs-wt-mdelta{--kw-tone:var(--_k-fg-2);padding:1px 7px;border-radius:999px;font-size:calc(var(--k-walkthrough-text,14px) - 3px);font-weight:var(--_k-weight-label);color:var(--kw-tone);background:color-mix(in srgb,var(--kw-tone) 14%,transparent)}
16601
+ .knobs-wt-mdelta[data-tone="good"]{--kw-tone:var(--kw-good)}
16602
+ .knobs-wt-mdelta[data-tone="bad"]{--kw-tone:var(--_k-danger)}
16603
+ .knobs-wt-mtrack{position:relative;height:4px;border-radius:2px;background:color-mix(in srgb,var(--_k-fg) 8%,transparent)}
14960
16604
  .knobs-wt-mtrack>span{position:absolute;top:0;bottom:0;left:0;border-radius:inherit}
14961
- .knobs-wt-mtrack>.knobs-wt-mafter{background:var(--ku-accent)}
14962
- .knobs-wt-mtrack>.knobs-wt-mbefore{background:color-mix(in srgb,var(--ku-text) 30%,transparent)}
14963
- .knobs-wt-callout{--kw-tone:var(--k-walkthrough-info,#64d2ff);display:flex;gap:10px;padding:10px 14px;border-radius:calc(var(--ku-panel-radius) - 4px);background:color-mix(in srgb,var(--kw-tone) 11%,transparent);color:var(--ku-text)}
16605
+ .knobs-wt-mtrack>.knobs-wt-mafter{background:var(--_k-accent)}
16606
+ .knobs-wt-mtrack>.knobs-wt-mbefore{background:color-mix(in srgb,var(--_k-fg) 30%,transparent)}
16607
+ .knobs-wt-callout{--kw-tone:var(--kw-info);display:flex;gap:10px;padding:10px 14px;border-radius:calc(var(--_k-radius-panel) - 4px);background:color-mix(in srgb,var(--kw-tone) 11%,transparent);color:var(--_k-fg)}
14964
16608
  .knobs-wt-callout::before{content:"";flex:none;width:6px;height:6px;margin-top:.62em;border-radius:50%;background:var(--kw-tone)}
14965
- .knobs-wt-callout[data-tone="good"]{--kw-tone:var(--k-walkthrough-good,#30d158)}
14966
- .knobs-wt-callout[data-tone="warn"]{--kw-tone:var(--ku-warn)}
14967
- .knobs-wt-callout[data-tone="bad"]{--kw-tone:var(--ku-critical)}
14968
- .knobs-wt-text{max-width:var(--k-walkthrough-measure,68ch);color:var(--ku-label)}
14969
- .knobs-wt-hold{border-radius:calc(var(--ku-panel-radius) - 4px);background:var(--ku-surface)}
14970
- .knobs-wt-failed{display:flex;align-items:center;justify-content:center;min-height:80px;color:var(--ku-dim);font-size:calc(var(--k-walkthrough-text,14px) - 2px)}
16609
+ .knobs-wt-callout[data-tone="good"]{--kw-tone:var(--kw-good)}
16610
+ .knobs-wt-callout[data-tone="warn"]{--kw-tone:var(--_k-warn)}
16611
+ .knobs-wt-callout[data-tone="bad"]{--kw-tone:var(--_k-danger)}
16612
+ .knobs-wt-text{max-width:var(--k-walkthrough-measure,68ch);color:var(--_k-fg-2)}
16613
+ .knobs-wt-hold{border-radius:calc(var(--_k-radius-panel) - 4px);background:var(--_k-fill)}
16614
+ .knobs-wt-failed{display:flex;align-items:center;justify-content:center;min-height:80px;color:var(--_k-fg-3);font-size:calc(var(--k-walkthrough-text,14px) - 2px)}
14971
16615
  @media(prefers-reduced-motion:reduce){:is(.knobs-walkthrough,.knobs-wt-slot) :where(*,::before,::after){transition-duration:.15s!important;transition-property:opacity,background,color!important}}
14972
16616
  `;
14973
16617
 
@@ -15004,7 +16648,7 @@ function parseAspect(aspect) {
15004
16648
  const h = m[2] === undefined ? 1 : Number(m[2]);
15005
16649
  return w > 0 && h > 0 ? w / h : undefined;
15006
16650
  }
15007
- function source(s, base) {
16651
+ function source2(s, base) {
15008
16652
  const v = typeof s === "string" ? { src: s } : s;
15009
16653
  return { ...v, src: resolveSrc(v.src, base) };
15010
16654
  }
@@ -15013,7 +16657,7 @@ function fillMedia(m, base) {
15013
16657
  return mediaOf(resolveSrc(m, base));
15014
16658
  switch (m.kind) {
15015
16659
  case "compare":
15016
- return { ...m, before: source(m.before, base), after: source(m.after, base) };
16660
+ return { ...m, before: source2(m.before, base), after: source2(m.after, base) };
15017
16661
  case "video":
15018
16662
  return {
15019
16663
  ...m,
@@ -15414,7 +17058,7 @@ function injectWalkthroughStyles(doc) {
15414
17058
  return;
15415
17059
  const style = doc.createElement("style");
15416
17060
  style.dataset.knobsUiWalkthrough = "";
15417
- style.textContent = walkthroughCss;
17061
+ style.textContent = aliased(walkthroughCss);
15418
17062
  doc.head.append(style);
15419
17063
  }
15420
17064
  var watchers = new WeakMap;
@@ -15769,7 +17413,7 @@ function mediaSlot(container, options) {
15769
17413
  const m = fillMedia(options.media);
15770
17414
  const root = div(doc, "knobs-wt-slot");
15771
17415
  root.dataset.kind = m.kind;
15772
- applyLook(root, options);
17416
+ applyLook2(root, options);
15773
17417
  const label = labelOf2(m);
15774
17418
  if (label && (m.kind === "video" || m.kind === "image" || m.kind === "code" || m.kind === "terminal")) {
15775
17419
  const l = doc.createElement("span");
@@ -15915,8 +17559,8 @@ var ICON = {
15915
17559
  send: svg('<path d="M8 13V3.5M4 7.5 8 3.5l4 4"/>'),
15916
17560
  close: svg('<path d="M4.5 4.5l7 7M11.5 4.5l-7 7"/>')
15917
17561
  };
15918
- var CALM2 = springMotion({ duration: 0.4, bounce: 0 });
15919
- var SMOOTH = springMotion({ duration: 0.45, bounce: 0 });
17562
+ var CALM2 = springMotion(SPRINGS.calm);
17563
+ var SMOOTH = springMotion(SPRINGS.smooth);
15920
17564
  var BACK_MS = 4500;
15921
17565
  function tasteTest(container, options) {
15922
17566
  const doc = container.ownerDocument;
@@ -15936,7 +17580,7 @@ function tasteTest(container, options) {
15936
17580
  root.setAttribute("aria-label", "Options");
15937
17581
  root.style.setProperty("--kw-n", String(Math.min(list.length, 3)));
15938
17582
  if (!container.closest(".knobs-ui"))
15939
- applyLook(root, options);
17583
+ applyLook2(root, options);
15940
17584
  const slots = [];
15941
17585
  const tiles = list.map((o, i) => {
15942
17586
  const tile = el(doc, "div", "knobs-wt-option");
@@ -16025,7 +17669,7 @@ function walkthrough(container, options) {
16025
17669
  const look = lookOf2(options);
16026
17670
  const storage = options.storage === undefined ? browserStorage() : options.storage;
16027
17671
  const root = el(doc, "div", "knobs-walkthrough");
16028
- applyLook(root, options);
17672
+ applyLook2(root, options);
16029
17673
  container.append(root);
16030
17674
  let page = normalizeWalkthrough(options.doc);
16031
17675
  const keyOf = () => storageKey(page.id, "walkthrough");
@@ -16290,13 +17934,13 @@ function walkthrough(container, options) {
16290
17934
  placeFull(full);
16291
17935
  win.addEventListener("resize", onFullResize);
16292
17936
  }
16293
- tune(full.p, reduced() ? springMotion({ duration: 0.2, bounce: 0 }) : SMOOTH);
17937
+ tune(full.p, reduced() ? springMotion(FADE) : SMOOTH);
16294
17938
  full.p.set(1);
16295
17939
  record({ what: "full", step: v.step.key, detail: "on" });
16296
17940
  } else {
16297
17941
  if (!full)
16298
17942
  return;
16299
- tune(full.p, reduced() ? springMotion({ duration: 0.16, bounce: 0 }) : SMOOTH);
17943
+ tune(full.p, reduced() ? springMotion(FADE) : SMOOTH);
16300
17944
  full.p.set(0);
16301
17945
  record({ what: "full", step: full.v.step.key, detail: "off" });
16302
17946
  }