@kitlangton/knobs 0.0.0-stage → 0.1.0

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 (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1270 -2
  3. package/dist/dev/chunk-e13znr7c.js +155 -0
  4. package/dist/dev/chunk-kdewv0mt.js +1334 -0
  5. package/dist/dev/chunk-ktsn42p7.js +15668 -0
  6. package/dist/dev/chunk-qtt698hp.js +1118 -0
  7. package/dist/dev/index.js +1389 -0
  8. package/dist/index.js +2367 -0
  9. package/dist/panel.js +23635 -0
  10. package/dist/react.js +326 -0
  11. package/dist/solid.js +336 -0
  12. package/dist/themes.js +235 -0
  13. package/dist/types/core/adapter.d.ts +21 -0
  14. package/dist/types/core/code.d.ts +3 -0
  15. package/dist/types/core/color.d.ts +27 -0
  16. package/dist/types/core/easing.d.ts +21 -0
  17. package/dist/types/core/internal.d.ts +18 -0
  18. package/dist/types/core/keys.d.ts +21 -0
  19. package/dist/types/core/mutate.d.ts +21 -0
  20. package/dist/types/core/ramp.d.ts +150 -0
  21. package/dist/types/core/random.d.ts +2 -0
  22. package/dist/types/core/readout.d.ts +73 -0
  23. package/dist/types/core/remote.d.ts +258 -0
  24. package/dist/types/core/schema.d.ts +526 -0
  25. package/dist/types/core/spring.d.ts +38 -0
  26. package/dist/types/core/storage.d.ts +8 -0
  27. package/dist/types/core/store.d.ts +474 -0
  28. package/dist/types/core/theme.d.ts +27 -0
  29. package/dist/types/core/variants.d.ts +17 -0
  30. package/dist/types/index.d.ts +13 -0
  31. package/dist/types/panel/attach.d.ts +5 -0
  32. package/dist/types/panel/choice.d.ts +56 -0
  33. package/dist/types/panel/die.d.ts +121 -0
  34. package/dist/types/panel/editors.d.ts +159 -0
  35. package/dist/types/panel/folds.d.ts +14 -0
  36. package/dist/types/panel/give.d.ts +73 -0
  37. package/dist/types/panel/gpu/atlas.d.ts +40 -0
  38. package/dist/types/panel/gpu/color.d.ts +128 -0
  39. package/dist/types/panel/gpu/die.wgsl.d.ts +1 -0
  40. package/dist/types/panel/gpu/renderer.d.ts +712 -0
  41. package/dist/types/panel/gpu/shader.wgsl.d.ts +2 -0
  42. package/dist/types/panel/haptics.d.ts +8 -0
  43. package/dist/types/panel/has.d.ts +14 -0
  44. package/dist/types/panel/hints.d.ts +45 -0
  45. package/dist/types/panel/icons.d.ts +30 -0
  46. package/dist/types/panel/index.d.ts +10 -0
  47. package/dist/types/panel/inspector.d.ts +20 -0
  48. package/dist/types/panel/measure.d.ts +6 -0
  49. package/dist/types/panel/menu.d.ts +38 -0
  50. package/dist/types/panel/morph.d.ts +38 -0
  51. package/dist/types/panel/motion.d.ts +77 -0
  52. package/dist/types/panel/page-hints.d.ts +82 -0
  53. package/dist/types/panel/page.d.ts +423 -0
  54. package/dist/types/panel/panel.d.ts +43 -0
  55. package/dist/types/panel/position.d.ts +5 -0
  56. package/dist/types/panel/prefs.d.ts +28 -0
  57. package/dist/types/panel/presets.d.ts +48 -0
  58. package/dist/types/panel/ramps.d.ts +14 -0
  59. package/dist/types/panel/readout-row.d.ts +21 -0
  60. package/dist/types/panel/reveal.d.ts +15 -0
  61. package/dist/types/panel/rolling-css.d.ts +2 -0
  62. package/dist/types/panel/search.d.ts +36 -0
  63. package/dist/types/panel/seg.d.ts +15 -0
  64. package/dist/types/panel/session.d.ts +21 -0
  65. package/dist/types/panel/slider.d.ts +92 -0
  66. package/dist/types/panel/smear.d.ts +7 -0
  67. package/dist/types/panel/spin.d.ts +13 -0
  68. package/dist/types/panel/styles.d.ts +11 -0
  69. package/dist/types/panel/swipe.d.ts +114 -0
  70. package/dist/types/panel/switcher.d.ts +20 -0
  71. package/dist/types/panel/tabs.d.ts +31 -0
  72. package/dist/types/panel/thumb.d.ts +36 -0
  73. package/dist/types/react/Knobs.d.ts +15 -0
  74. package/dist/types/react/VariantSwitcher.d.ts +10 -0
  75. package/dist/types/react/index.d.ts +3 -0
  76. package/dist/types/react/useControls.d.ts +11 -0
  77. package/dist/types/solid/index.d.ts +50 -0
  78. package/dist/types/themes/index.d.ts +1 -0
  79. package/dist/types/ui/bento-css.d.ts +1 -0
  80. package/dist/types/ui/bento-model.d.ts +96 -0
  81. package/dist/types/ui/bento.d.ts +77 -0
  82. package/dist/types/ui/commands.d.ts +11 -0
  83. package/dist/types/ui/confirm.d.ts +13 -0
  84. package/dist/types/ui/index.d.ts +20 -0
  85. package/dist/types/ui/layer.d.ts +70 -0
  86. package/dist/types/ui/look.d.ts +53 -0
  87. package/dist/types/ui/menu.d.ts +63 -0
  88. package/dist/types/ui/overlay-css.d.ts +1 -0
  89. package/dist/types/ui/overlay-model.d.ts +87 -0
  90. package/dist/types/ui/palette.d.ts +38 -0
  91. package/dist/types/ui/popover.d.ts +35 -0
  92. package/dist/types/ui/react.d.ts +45 -0
  93. package/dist/types/ui/readout-css.d.ts +1 -0
  94. package/dist/types/ui/readout-model.d.ts +137 -0
  95. package/dist/types/ui/readouts.d.ts +85 -0
  96. package/dist/types/ui/rgba.d.ts +6 -0
  97. package/dist/types/ui/solid.d.ts +40 -0
  98. package/dist/types/ui/split-model.d.ts +81 -0
  99. package/dist/types/ui/split.d.ts +75 -0
  100. package/dist/types/ui/timeline-model.d.ts +83 -0
  101. package/dist/types/ui/timeline.d.ts +76 -0
  102. package/dist/types/ui/toast.d.ts +19 -0
  103. package/dist/types/ui/tooltip.d.ts +19 -0
  104. package/dist/types/ui/tree-model.d.ts +125 -0
  105. package/dist/types/ui/tree.d.ts +95 -0
  106. package/dist/ui-react.js +6558 -0
  107. package/dist/ui-solid.js +6511 -0
  108. package/dist/ui.js +9238 -0
  109. package/package.json +99 -4
@@ -0,0 +1,1334 @@
1
+ import {
2
+ GRADIENT_SAMPLES,
3
+ Spring,
4
+ springEasing,
5
+ springCss2,
6
+ storageKey
7
+ } from "./chunk-qtt698hp.js";
8
+
9
+ // src/panel/icons.ts
10
+ var ICONS = {
11
+ undo: "M232,144a64.07,64.07,0,0,1-64,64H80a8,8,0,0,1,0-16h88a48,48,0,0,0,0-96H51.31l34.35,34.34a8,8,0,0,1-11.32,11.32l-48-48a8,8,0,0,1,0-11.32l48-48A8,8,0,0,1,85.66,45.66L51.31,80H168A64.07,64.07,0,0,1,232,144Z",
12
+ redo: "M170.34,130.34,204.69,96H88a48,48,0,0,0,0,96h88a8,8,0,0,1,0,16H88A64,64,0,0,1,88,80H204.69L170.34,45.66a8,8,0,0,1,11.32-11.32l48,48a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32-11.32Z",
13
+ help: "M140,180a12,12,0,1,1-12-12A12,12,0,0,1,140,180ZM128,72c-22.06,0-40,16.15-40,36v4a8,8,0,0,0,16,0v-4c0-11,10.77-20,24-20s24,9,24,20-10.77,20-24,20a8,8,0,0,0-8,8v8a8,8,0,0,0,16,0v-.72c18.24-3.35,32-17.9,32-35.28C168,88.15,150.06,72,128,72Zm104,56A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z",
14
+ close: "M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z",
15
+ random: "M192,32H64A32,32,0,0,0,32,64V192a32,32,0,0,0,32,32H192a32,32,0,0,0,32-32V64A32,32,0,0,0,192,32Zm16,160a16,16,0,0,1-16,16H64a16,16,0,0,1-16-16V64A16,16,0,0,1,64,48H192a16,16,0,0,1,16,16ZM104,92A12,12,0,1,1,92,80,12,12,0,0,1,104,92Zm72,0a12,12,0,1,1-12-12A12,12,0,0,1,176,92Zm-72,72a12,12,0,1,1-12-12A12,12,0,0,1,104,164Zm36-36a12,12,0,1,1-12-12A12,12,0,0,1,140,128Zm36,36a12,12,0,1,1-12-12A12,12,0,0,1,176,164Z",
16
+ reset: "M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z",
17
+ lock: "M208,80H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80ZM96,56a32,32,0,0,1,64,0V80H96ZM208,208H48V96H208V208Z",
18
+ copy: "M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z",
19
+ caret: "M181.66,170.34a8,8,0,0,1,0,11.32l-48,48a8,8,0,0,1-11.32,0l-48-48a8,8,0,0,1,11.32-11.32L128,212.69l42.34-42.35A8,8,0,0,1,181.66,170.34Zm-96-84.68L128,43.31l42.34,42.35a8,8,0,0,0,11.32-11.32l-48-48a8,8,0,0,0-11.32,0l-48,48A8,8,0,0,0,85.66,85.66Z",
20
+ gear: "M128,80a48,48,0,1,0,48,48A48.05,48.05,0,0,0,128,80Zm0,80a32,32,0,1,1,32-32A32,32,0,0,1,128,160Zm109.94-52.79a8,8,0,0,0-3.89-5.4l-29.83-17-.12-33.62a8,8,0,0,0-2.83-6.08,111.91,111.91,0,0,0-36.72-20.67,8,8,0,0,0-6.46.59L128,41.85,97.88,25a8,8,0,0,0-6.47-.6A112.1,112.1,0,0,0,54.73,45.15a8,8,0,0,0-2.83,6.07l-.15,33.65-29.83,17a8,8,0,0,0-3.89,5.4,106.47,106.47,0,0,0,0,41.56,8,8,0,0,0,3.89,5.4l29.83,17,.12,33.62a8,8,0,0,0,2.83,6.08,111.91,111.91,0,0,0,36.72,20.67,8,8,0,0,0,6.46-.59L128,214.15,158.12,231a7.91,7.91,0,0,0,3.9,1,8.09,8.09,0,0,0,2.57-.42,112.1,112.1,0,0,0,36.68-20.73,8,8,0,0,0,2.83-6.07l.15-33.65,29.83-17a8,8,0,0,0,3.89-5.4A106.47,106.47,0,0,0,237.94,107.21Zm-15,34.91-28.57,16.25a8,8,0,0,0-3,3c-.58,1-1.19,2.06-1.81,3.06a7.94,7.94,0,0,0-1.22,4.21l-.15,32.25a95.89,95.89,0,0,1-25.37,14.3L134,199.13a8,8,0,0,0-3.91-1h-.19c-1.21,0-2.43,0-3.64,0a8.08,8.08,0,0,0-4.1,1l-28.84,16.1A96,96,0,0,1,67.88,201l-.11-32.2a8,8,0,0,0-1.22-4.22c-.62-1-1.23-2-1.8-3.06a8.09,8.09,0,0,0-3-3.06l-28.6-16.29a90.49,90.49,0,0,1,0-28.26L61.67,97.63a8,8,0,0,0,3-3c.58-1,1.19-2.06,1.81-3.06a7.94,7.94,0,0,0,1.22-4.21l.15-32.25a95.89,95.89,0,0,1,25.37-14.3L122,56.87a8,8,0,0,0,4.1,1c1.21,0,2.43,0,3.64,0a8.08,8.08,0,0,0,4.1-1l28.84-16.1A96,96,0,0,1,188.12,55l.11,32.2a8,8,0,0,0,1.22,4.22c.62,1,1.23,2,1.8,3.06a8.09,8.09,0,0,0,3,3.06l28.6,16.29A90.49,90.49,0,0,1,222.9,142.12Z",
21
+ search: "M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z",
22
+ link: "M165.66,90.34a8,8,0,0,1,0,11.32l-64,64a8,8,0,0,1-11.32-11.32l64-64A8,8,0,0,1,165.66,90.34ZM215.6,40.4a56,56,0,0,0-79.2,0L106.34,70.45a8,8,0,0,0,11.32,11.32l30.06-30a40,40,0,0,1,56.57,56.56l-30.07,30.06a8,8,0,0,0,11.31,11.32L215.6,119.6a56,56,0,0,0,0-79.2ZM138.34,174.22l-30.06,30.06a40,40,0,1,1-56.56-56.57l30.05-30.05a8,8,0,0,0-11.32-11.32L40.4,136.4a56,56,0,0,0,79.2,79.2l30.06-30.07a8,8,0,0,0-11.32-11.31Z",
23
+ unlink: "M232,80a55.67,55.67,0,0,1-16.4,39.6l-30.07,30.06a8,8,0,0,1-11.31-11.32l30.07-30.06a40,40,0,1,0-56.57-56.56L117.66,81.77a8,8,0,0,1-11.32-11.32L136.4,40.4A56,56,0,0,1,232,80Zm-93.66,94.22-30.06,30.06a40,40,0,1,1-56.56-56.57l30.05-30.05a8,8,0,0,0-11.32-11.32L40.4,136.4a56,56,0,0,0,79.2,79.2l30.06-30.07a8,8,0,0,0-11.32-11.31Z",
24
+ play: "M232.4,114.49,88.32,26.35a16,16,0,0,0-16.2-.3A15.86,15.86,0,0,0,64,39.87V216.13A15.94,15.94,0,0,0,80,232a16.07,16.07,0,0,0,8.36-2.35L232.4,141.51a15.81,15.81,0,0,0,0-27ZM80,215.94V40l143.83,88Z",
25
+ pause: "M200,32H160a16,16,0,0,0-16,16V208a16,16,0,0,0,16,16h40a16,16,0,0,0,16-16V48A16,16,0,0,0,200,32Zm0,176H160V48h40ZM96,32H56A16,16,0,0,0,40,48V208a16,16,0,0,0,16,16H96a16,16,0,0,0,16-16V48A16,16,0,0,0,96,32Zm0,176H56V48H96Z",
26
+ frame: "M200,80v32a8,8,0,0,1-16,0V88H160a8,8,0,0,1,0-16h32A8,8,0,0,1,200,80ZM96,168H72V144a8,8,0,0,0-16,0v32a8,8,0,0,0,8,8H96a8,8,0,0,0,0-16ZM232,56V200a16,16,0,0,1-16,16H40a16,16,0,0,1-16-16V56A16,16,0,0,1,40,40H216A16,16,0,0,1,232,56ZM216,200V56H40V200H216Z",
27
+ retrigger: "M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16H211.4L184.81,71.64l-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,0,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60L224,85.8V56a8,8,0,1,1,16,0Z",
28
+ clear: "M225,80.4,183.6,39a24,24,0,0,0-33.94,0L31,157.66a24,24,0,0,0,0,33.94l30.06,30.06A8,8,0,0,0,66.74,224H216a8,8,0,0,0,0-16h-84.7L225,114.34A24,24,0,0,0,225,80.4ZM108.68,208H70.05L42.33,180.28a8,8,0,0,1,0-11.31L96,115.31,148.69,168Zm105-105L160,156.69,107.31,104,161,50.34a8,8,0,0,1,11.32,0l41.38,41.38a8,8,0,0,1,0,11.31Z",
29
+ target: "M232,120h-8.34A96.14,96.14,0,0,0,136,32.34V24a8,8,0,0,0-16,0v8.34A96.14,96.14,0,0,0,32.34,120H24a8,8,0,0,0,0,16h8.34A96.14,96.14,0,0,0,120,223.66V232a8,8,0,0,0,16,0v-8.34A96.14,96.14,0,0,0,223.66,136H232a8,8,0,0,0,0-16Zm-96,87.6V200a8,8,0,0,0-16,0v7.6A80.15,80.15,0,0,1,48.4,136H56a8,8,0,0,0,0-16H48.4A80.15,80.15,0,0,1,120,48.4V56a8,8,0,0,0,16,0V48.4A80.15,80.15,0,0,1,207.6,120H200a8,8,0,0,0,0,16h7.6A80.15,80.15,0,0,1,136,207.6ZM128,88a40,40,0,1,0,40,40A40,40,0,0,0,128,88Zm0,64a24,24,0,1,1,24-24A24,24,0,0,1,128,152Z",
30
+ camera: "M208,56H180.28L166.65,35.56A8,8,0,0,0,160,32H96a8,8,0,0,0-6.65,3.56L75.71,56H48A24,24,0,0,0,24,80V192a24,24,0,0,0,24,24H208a24,24,0,0,0,24-24V80A24,24,0,0,0,208,56Zm8,136a8,8,0,0,1-8,8H48a8,8,0,0,1-8-8V80a8,8,0,0,1,8-8H80a8,8,0,0,0,6.66-3.56L100.28,48h55.43l13.63,20.44A8,8,0,0,0,176,72h32a8,8,0,0,1,8,8ZM128,88a44,44,0,1,0,44,44A44.05,44.05,0,0,0,128,88Zm0,72a28,28,0,1,1,28-28A28,28,0,0,1,128,160Z",
31
+ sparkle: "M197.58,129.06,146,110l-19-51.62a15.92,15.92,0,0,0-29.88,0L78,110l-51.62,19a15.92,15.92,0,0,0,0,29.88L78,178l19,51.62a15.92,15.92,0,0,0,29.88,0L146,178l51.62-19a15.92,15.92,0,0,0,0-29.88ZM137,164.22a8,8,0,0,0-4.74,4.74L112,223.85,91.78,169A8,8,0,0,0,87,164.22L32.15,144,87,123.78A8,8,0,0,0,91.78,119L112,64.15,132.22,119a8,8,0,0,0,4.74,4.74L191.85,144ZM144,40a8,8,0,0,1,8-8h16V16a8,8,0,0,1,16,0V32h16a8,8,0,0,1,0,16H184V64a8,8,0,0,1-16,0V48H152A8,8,0,0,1,144,40ZM248,88a8,8,0,0,1-8,8h-8v8a8,8,0,0,1-16,0V96h-8a8,8,0,0,1,0-16h8V72a8,8,0,0,1,16,0v8h8A8,8,0,0,1,248,88Z"
32
+ }, CHECK_POINTS = [44, 132, 100, 188, 212, 76], CHECK_PATH = `M${CHECK_POINTS.slice(0, 2)}L${CHECK_POINTS.slice(2, 4)}L${CHECK_POINTS.slice(4)}`, iconPath = (icon) => Object.hasOwn(ICONS, icon) ? ICONS[icon] : icon;
33
+ function iconSvg(doc, name) {
34
+ let svg = doc.createElementNS("http://www.w3.org/2000/svg", "svg");
35
+ svg.setAttribute("viewBox", "0 0 256 256"), svg.setAttribute("aria-hidden", "true"), svg.setAttribute("class", "knobs-icon");
36
+ let path = doc.createElementNS("http://www.w3.org/2000/svg", "path");
37
+ return path.setAttribute("d", iconPath(name)), path.setAttribute("fill", "currentColor"), svg.append(path), svg;
38
+ }
39
+
40
+ // src/panel/session.ts
41
+ var tabStorage = () => {
42
+ try {
43
+ return typeof sessionStorage > "u" ? null : sessionStorage;
44
+ } catch {
45
+ return null;
46
+ }
47
+ };
48
+ function readSession(id) {
49
+ try {
50
+ return JSON.parse(tabStorage()?.getItem(storageKey(id, "session")) ?? "{}") ?? {};
51
+ } catch {
52
+ return {};
53
+ }
54
+ }
55
+ function writeSession(id, patch) {
56
+ let next = { ...readSession(id), ...patch };
57
+ for (let k of Object.keys(next))
58
+ if (next[k] === void 0)
59
+ delete next[k];
60
+ try {
61
+ tabStorage()?.setItem(storageKey(id, "session"), JSON.stringify(next));
62
+ } catch {}
63
+ }
64
+
65
+ // src/panel/motion.ts
66
+ var FILL = { omega: 30, zeta: 0.88 };
67
+ var LEAD = { omega: 34, zeta: 0.86 }, TRAIL = { omega: 25, zeta: 1 }, trailScale = (blur) => 0.6 + 0.4 * clamp(blur, 0, 2);
68
+
69
+ class Edges {
70
+ start;
71
+ end;
72
+ constructor(start = 0, end = 0) {
73
+ this.start = new Spring(start, LEAD.omega, LEAD.zeta, 0.05), this.end = new Spring(end, LEAD.omega, LEAD.zeta, 0.05);
74
+ }
75
+ to(start, end, delay = 0, trail = 1) {
76
+ if ((start !== this.start.target || end !== this.end.target) && delay <= 0) {
77
+ let forward = start + end > this.start.target + this.end.target, [lead, tail] = forward ? [this.end, this.start] : [this.start, this.end];
78
+ lead.omega = LEAD.omega, lead.zeta = LEAD.zeta, tail.omega = TRAIL.omega / trail, tail.zeta = TRAIL.zeta;
79
+ }
80
+ return this.start.set(start, delay), this.end.set(end, delay), this;
81
+ }
82
+ shift(ds, de) {
83
+ return this.start.x += ds, this.start.target += ds, this.end.x += de, this.end.target += de, this;
84
+ }
85
+ snap(start, end) {
86
+ return this.start.snap(start), this.end.snap(end), this;
87
+ }
88
+ step(dt) {
89
+ return this.start.step(dt), this.end.step(dt), this;
90
+ }
91
+ get resting() {
92
+ return this.start.resting && this.end.resting;
93
+ }
94
+ get velocity() {
95
+ return (this.start.v + this.end.v) / 2;
96
+ }
97
+ }
98
+ var POP_MS = 360;
99
+ function popScale(t, peak = 0.04) {
100
+ if (t <= 0 || t >= POP_MS)
101
+ return 1;
102
+ let u = t / 55;
103
+ return 1 + peak * u * Math.exp(1 - u);
104
+ }
105
+
106
+ class VelocityTracker {
107
+ samples = [];
108
+ add(x, y, t = performance.now()) {
109
+ this.samples.push({ t, x, y });
110
+ while (this.samples.length > 2 && t - this.samples[0].t > 100)
111
+ this.samples.shift();
112
+ }
113
+ reset() {
114
+ this.samples = [];
115
+ }
116
+ get velocity() {
117
+ let s = this.samples;
118
+ if (s.length < 2)
119
+ return [0, 0];
120
+ let a = s[0], b = s[s.length - 1], dt = (b.t - a.t) / 1000;
121
+ if (dt <= 0 || performance.now() - b.t > 60)
122
+ return [0, 0];
123
+ return [(b.x - a.x) / dt, (b.y - a.y) / dt];
124
+ }
125
+ }
126
+ var clamp = (x, a, b) => Math.min(b, Math.max(a, x));
127
+
128
+ class Roll {
129
+ from;
130
+ to = 0;
131
+ inherited = 0;
132
+ start = 0;
133
+ duration = 0;
134
+ constructor(position) {
135
+ this.from = this.to = position;
136
+ }
137
+ get target() {
138
+ return this.to;
139
+ }
140
+ sample(now) {
141
+ let t = now - this.start;
142
+ if (this.duration <= 0 || t >= this.duration)
143
+ return { position: this.to, velocity: 0 };
144
+ if (t <= 0)
145
+ return { position: this.from, velocity: 0 };
146
+ let seconds = this.duration / 1000, tau = t / this.duration, d = this.from - this.to, e = Math.exp(-10 * tau);
147
+ return {
148
+ position: this.to + (d + (this.inherited + 10 * d) * tau) * e,
149
+ velocity: e * (this.inherited - 10 * (this.inherited + 10 * d) * tau) / seconds
150
+ };
151
+ }
152
+ set(target, duration, now, delay = 0) {
153
+ let { position, velocity } = this.sample(now);
154
+ if (duration <= 0)
155
+ return this.snap(target);
156
+ let seconds = duration / 1000, distance = position - target, limit = Math.max(Math.abs(distance), 1) * 12 / seconds;
157
+ return this.inherited = clamp(delay > 0 ? 0 : velocity, -limit, limit) * seconds, this.from = position, this.to = target, this.start = now + delay, this.duration = duration, this;
158
+ }
159
+ snap(position) {
160
+ return this.from = this.to = position, this.duration = 0, this.inherited = 0, this;
161
+ }
162
+ resting(now) {
163
+ return this.duration <= 0 || now - this.start >= this.duration;
164
+ }
165
+ span(now) {
166
+ if (this.resting(now))
167
+ return [this.to, this.to];
168
+ return [Math.min(this.from, this.to), Math.max(this.from, this.to)];
169
+ }
170
+ }
171
+ function rollTarget(position, digit, trend) {
172
+ let target = Math.floor(position / 10) * 10 + digit;
173
+ if (trend > 0 && target < position - 0.001)
174
+ target += 10;
175
+ else if (trend < 0 && target > position + 0.001)
176
+ target -= 10;
177
+ else if (trend === 0)
178
+ target += Math.round((position - target) / 10) * 10;
179
+ return target;
180
+ }
181
+ var numeral = (position) => String((position % 10 + 10) % 10);
182
+ function entranceOffset(elapsed, duration, hold = 0.14) {
183
+ if (duration <= 0 || elapsed >= duration)
184
+ return 0;
185
+ let p = clamp((elapsed / duration - hold) / (1 - hold), 0, 1);
186
+ return (1 + 10 * p) * Math.exp(-10 * p);
187
+ }
188
+
189
+ // src/panel/rolling-css.ts
190
+ var rolling_css_default = `.rn-root {
191
+ display: inline-block;
192
+ position: relative;
193
+ white-space: pre;
194
+ unicode-bidi: isolate;
195
+ vertical-align: baseline;
196
+ }
197
+ .rn-root > .rn-measure,
198
+ .rn-root > .rn-visual { display: none; }
199
+ .rn-root[data-rn-measuring] > .rn-measure {
200
+ display: inline-flex;
201
+ position: relative;
202
+ visibility: hidden;
203
+ white-space: pre;
204
+ padding: 0;
205
+ border: 0;
206
+ }
207
+ .rn-token { display: inline-block; padding: 0; border: 0; }
208
+ .rn-root[data-rn-measuring] > .rn-value,
209
+ .rn-react[data-rn-hydrated] > .rn-semantic,
210
+ .rn-solid[data-rn-hydrated] > .rn-semantic {
211
+ position: absolute;
212
+ inset: 0;
213
+ padding: 0;
214
+ margin: 0;
215
+ color: transparent;
216
+ z-index: 1;
217
+ }
218
+ /* A single native text layer is selectable; decorative reels never enter a copy. */
219
+ .rn-value::selection, .rn-semantic::selection {
220
+ color: HighlightText;
221
+ background: Highlight;
222
+ }
223
+ .rn-root[data-rn-ready] > .rn-visual {
224
+ display: block;
225
+ position: absolute;
226
+ inset: 0;
227
+ pointer-events: none;
228
+ user-select: none;
229
+ }
230
+ .rn-slot {
231
+ position: absolute;
232
+ left: 0;
233
+ overflow: hidden;
234
+ /* Space for italic overhang without changing the measured advance width. */
235
+ box-sizing: content-box;
236
+ padding-inline: 0.15em;
237
+ margin-inline-start: -0.15em;
238
+ -webkit-mask-image: var(--rn-mask, linear-gradient(
239
+ to bottom,
240
+ transparent,
241
+ #000 var(--rn-edge-fade, 0.12em),
242
+ #000 calc(100% - var(--rn-edge-fade, 0.12em)),
243
+ transparent
244
+ ));
245
+ mask-image: var(--rn-mask, linear-gradient(
246
+ to bottom,
247
+ transparent,
248
+ #000 var(--rn-edge-fade, 0.12em),
249
+ #000 calc(100% - var(--rn-edge-fade, 0.12em)),
250
+ transparent
251
+ ));
252
+ -webkit-mask-repeat: no-repeat;
253
+ mask-repeat: no-repeat;
254
+ }
255
+ @supports (overflow: clip) {
256
+ .rn-slot { overflow-x: visible; overflow-y: clip; }
257
+ }
258
+ .rn-slot:not([data-rn-wheel]) {
259
+ overflow: visible;
260
+ -webkit-mask-image: none;
261
+ mask-image: none;
262
+ }
263
+ .rn-enter, .rn-reel, .rn-face { display: block; }
264
+ .rn-reel { position: relative; }
265
+ .rn-ink { display: block; position: absolute; inset: 0; will-change: transform; }
266
+ /* Safari's SVG filter must rasterize the smear's descendants into its input. */
267
+ .rn-smear .rn-ink { will-change: auto; }
268
+ /* Each turning half carries its own perspective transform, not a shared 3D scene. */
269
+ /* The slot acts as the bezel: the card stays vertically framed while it hinges. */
270
+ .rn-slot[data-rn-flap] { -webkit-mask-image: none; mask-image: none; }
271
+ /* Hinged faces must occlude the cards behind them, including with default CSS. */
272
+ :where(.rn-slot[data-rn-flap]) .rn-face { background: var(--rn-flap-background, Canvas); }
273
+ .rn-flap { position: absolute; inset: 0; transform-origin: 50% 50%; backface-visibility: hidden; }
274
+ /* --rn-crease is the visible hinge gap between the two halves. */
275
+ .rn-flap-top { clip-path: inset(0 0 calc(50% + var(--rn-crease, 1px) / 2) 0); }
276
+ .rn-flap-bottom { clip-path: inset(calc(50% + var(--rn-crease, 1px) / 2) 0 0 0); }
277
+ .rn-sharp, .rn-smear { display: block; }
278
+ .rn-smear { position: absolute; inset: 0; pointer-events: none; }
279
+ .rn-blur-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
280
+ .rn-face { text-align: center; white-space: pre; }
281
+ .rn-react, .rn-solid { display: inline-block; position: relative; white-space: pre; unicode-bidi: isolate; }
282
+ .rn-mount { display: inline-block; user-select: none; }
283
+ .rn-mount .rn-value { pointer-events: none; }
284
+ .rn-react:not([data-rn-hydrated]) > .rn-mount,
285
+ .rn-solid:not([data-rn-hydrated]) > .rn-mount { display: none; }
286
+ `;
287
+
288
+ // src/core/theme.ts
289
+ var block = (tokens) => Object.entries(tokens).map(([k, v]) => `${k.startsWith("--") || k === "color-scheme" ? k : `--k-${k}`}:${v}`).join(";");
290
+ function presetCss(preset) {
291
+ if (!/^[\w-]+$/.test(preset.name))
292
+ throw Error(`Invalid preset name: ${preset.name}`);
293
+ let at = `.knobs-panel[data-preset="${preset.name}"]`, light = preset.light ? `:where(.knobs-panel)[data-preset="${preset.name}"][data-theme="light"],:where([data-knobs-theme="light"]) ${at}:not([data-theme="dark"]),:where(:root[data-theme="light"]) ${at}[data-theme="auto"]{${block(preset.light)}}@media(prefers-color-scheme:light){:where(:root:not([data-theme="dark"])) ${at}[data-theme="auto"]{${block(preset.light)}}}` : "";
294
+ return `${at}{${block(preset.dark)}}${light}${(preset.css ?? "").replaceAll("&", at)}`;
295
+ }
296
+ var glide = /* @__PURE__ */ springCss2({ duration: 0.185, bounce: 0.14 });
297
+ var problemsPreset = {
298
+ name: "problems",
299
+ dark: {
300
+ bg: "#161618",
301
+ surface: "rgba(255,255,255,.055)",
302
+ "surface-hi": "rgba(255,255,255,.11)",
303
+ line: "rgba(255,255,255,.075)",
304
+ "line-hi": "rgba(255,255,255,.12)",
305
+ text: "#f5f5f7",
306
+ label: "rgba(235,235,245,.62)",
307
+ dim: "rgba(235,235,245,.36)",
308
+ accent: "#0091ff",
309
+ modified: "#0091ff",
310
+ "seg-bg": "rgba(120,120,128,.16)",
311
+ "seg-active": "rgba(120,120,128,.24)",
312
+ "toggle-track": "rgba(120,120,128,.32)",
313
+ "toggle-thumb": "#fff",
314
+ rim: "transparent",
315
+ font: 'system-ui,-apple-system,BlinkMacSystemFont,"Helvetica Neue",sans-serif',
316
+ mono: '"Kit SF Mono",ui-monospace,Menlo,monospace',
317
+ "font-size": "13px",
318
+ "label-weight": 500,
319
+ row: "34px",
320
+ radius: "8px",
321
+ "panel-radius": "12px",
322
+ pad: "0px",
323
+ inset: "10px",
324
+ gap: "4px",
325
+ "row-gap": "4px",
326
+ glass: 0,
327
+ glow: 0,
328
+ blur: 0.6,
329
+ "hover-in": 0,
330
+ "hover-out": 100,
331
+ "handle-rest": 0.55,
332
+ handle: "var(--k-text)",
333
+ "handle-inset": "7.5px",
334
+ "fill-base": "transparent",
335
+ "fill-rest-mix": "24%",
336
+ "fill-hover-mix": "36%",
337
+ "fill-active-mix": "36%",
338
+ chrome: 0,
339
+ "group-transform": "none",
340
+ "value-font": "var(--k-mono)",
341
+ "unit-gap": "0px",
342
+ "unit-color": "currentColor",
343
+ "readout-mark": 1,
344
+ "group-size": "12px",
345
+ "group-color": "rgba(235,235,245,.62)",
346
+ "group-inset": "0px",
347
+ "group-tracking": "-.01em",
348
+ "group-divider": "rgba(255,255,255,.075)",
349
+ "group-divider-gap": "8px",
350
+ "curve-inset": "0px",
351
+ "curve-guide": "dashed",
352
+ "curve-dot": 0,
353
+ spring: "0.185 0.14",
354
+ "fill-ease": glide.easing,
355
+ "fill-ms": glide.duration
356
+ },
357
+ light: {
358
+ bg: "#fff",
359
+ surface: "rgba(0,0,0,.045)",
360
+ "surface-hi": "rgba(0,0,0,.09)",
361
+ line: "rgba(0,0,0,.07)",
362
+ "line-hi": "rgba(0,0,0,.11)",
363
+ text: "#000",
364
+ label: "rgba(60,60,67,.66)",
365
+ dim: "rgba(60,60,67,.38)",
366
+ accent: "#0088ff",
367
+ modified: "#0088ff",
368
+ "seg-bg": "rgba(120,120,128,.11)",
369
+ "seg-active": "#fff",
370
+ "toggle-track": "rgba(120,120,128,.2)",
371
+ "toggle-thumb": "#fff",
372
+ rim: "transparent",
373
+ "group-color": "rgba(60,60,67,.66)",
374
+ "group-divider": "rgba(0,0,0,.07)",
375
+ "color-scheme": "light"
376
+ }
377
+ };
378
+
379
+ // src/panel/styles.ts
380
+ var lead = springEasing(LEAD.omega, LEAD.zeta), trail = springEasing(TRAIL.omega, TRAIL.zeta), fill = springEasing(FILL.omega, FILL.zeta), LEAD_T = `${lead.ms}ms var(--k-lead)`, TRAIL_T = `calc(${trail.ms}ms * (.6 + .4 * clamp(0, var(--k-blur), 2))) var(--k-trail)`, FILL_T = "calc(var(--k-fill-ms) * 1ms * clamp(var(--k-blur),.1,2)) var(--k-fill-ease)", SLIDE_T = "calc(var(--k-fill-ms) * 1ms) var(--k-fill-ease)", DELAY = "var(--k-delay,0ms)", POINTER_ROW = ".knobs-panel[data-k-row-hover]:not([data-keyboard])", DELAYED = ".knobs-fill,.knobs-handle,.knobs-seg-pill,.knobs-toggle,.knobs-toggle i,.knobs-arm,.knobs-curve,.knobs-swatch,.knobs-strip-thumb,.knobs-pad>i,.knobs-ease-handle,.knobs-range-fill,.knobs-range-thumb,.knobs-dial-hand,.knobs-grad,.knobs-grad-mini,.knobs-grad-mini>i,.knobs-grad-stop,.knobs-graph-pt", GRAD_N = GRADIENT_SAMPLES, gradStops = (at) => Array.from({ length: GRAD_N }, (_, i) => `var(--kgrad-${i}) ${at(i)}`).join(","), GRAD_STRIP = `linear-gradient(to right,${gradStops((i) => `calc(var(--kg-r) + (100% - var(--kg-r) * 2) * ${Number((i / (GRAD_N - 1)).toFixed(5))})`)})`, GRAD_MINI = `linear-gradient(to right,${gradStops((i) => `${Number((i / (GRAD_N - 1) * 100).toFixed(3))}%`)})`, GRAD_T = Array.from({ length: GRAD_N }, (_, i) => `--kgrad-${i} ${FILL_T} ${DELAY}`).join(","), GRAD_PROPS = Array.from({ length: GRAD_N }, (_, i) => `@property --kgrad-${i}{syntax:"<color>";inherits:false;initial-value:transparent}`).join(`
381
+ `), COLOR_TOKENS = [
382
+ "bg",
383
+ "surface",
384
+ "surface-hi",
385
+ "line",
386
+ "line-hi",
387
+ "text",
388
+ "label",
389
+ "dim",
390
+ "accent",
391
+ "modified",
392
+ "seg-bg",
393
+ "seg-active",
394
+ "toggle-track",
395
+ "toggle-thumb",
396
+ "rim",
397
+ "edge",
398
+ "page"
399
+ ], LENGTH_TOKENS = ["pad", "inset", "row", "gap", "radius", "panel-radius", "font-size"], NUMBER_TOKENS = ["label-weight", "blur", "glow", "glass", "glass-tone"], ANIMATED = [...COLOR_TOKENS, ...LENGTH_TOKENS, ...NUMBER_TOKENS, "width"], TOKEN_TRANSITIONS = ANIMATED.map((t) => `--kt-${t} var(--k-token-t)`).join(","), register = (names, syntax, initial) => names.map((n) => `@property --kt-${n}{syntax:"${syntax}";inherits:false;initial-value:${initial}}`).join(`
400
+ `), DRIVERS = `${register(COLOR_TOKENS, "<color>", "transparent")}
401
+ ${register(LENGTH_TOKENS, "<length>", "0px")}
402
+ ${register(NUMBER_TOKENS, "<number>", "0")}
403
+ ${register(["width"], "<length-percentage>", "288px")}
404
+ .knobs-panel,.knobs-chip,.knobs-toast{${ANIMATED.map((t) => `--kt-${t}:var(--k-${t});--kv-${t}:var(--kt-${t})`).join(";")}}`, aliased = (css) => css.replace(new RegExp(`var\\(--k-(${ANIMATED.join("|")})\\)`, "g"), "var(--kv-$1)"), lightVars = `
405
+ --k-bg:#f5f5f7;--k-surface:rgba(0,0,0,calc(.05 * var(--k-contrast)));--k-surface-hi:rgba(0,0,0,calc(.095 * var(--k-contrast)));--k-line:rgba(0,0,0,calc(.1 * var(--k-contrast)));--k-line-hi:rgba(0,0,0,calc(.2 * var(--k-contrast)));
406
+ --k-text:rgba(0,0,0,.88);--k-label:rgba(60,60,67,.68);--k-dim:rgba(60,60,67,.5);--k-accent:#1c1c1e;--k-modified:rgba(0,0,0,.42);
407
+ --k-seg-bg:rgba(0,0,0,.065);--k-seg-active:#fff;--k-toggle-track:rgba(0,0,0,.14);--k-toggle-thumb:#fff;--k-shadow:0 10px 32px rgba(0,0,0,.14),0 1px 3px rgba(0,0,0,.08);
408
+ --k-rim:rgba(255,255,255,.6);--k-edge:rgba(0,0,0,calc(.07 * var(--k-contrast)));--k-glass-tone:1.08;--k-page:#e6e6eb;--k-group-ink:var(--k-dim);
409
+ color-scheme:light;`, defaultsCss = `
410
+ @property --k-fill{syntax:"<percentage>";inherits:false;initial-value:0%}
411
+ @property --k-fill-mix{syntax:"<percentage>";inherits:false;initial-value:20%}
412
+ @property --k-readout{syntax:"<length>";inherits:true;initial-value:0px}
413
+ @property --k-copy{syntax:"<number>";inherits:true;initial-value:1}
414
+ @property --k-check{syntax:"<number>";inherits:true;initial-value:0}
415
+ @property --k-check-a{syntax:"<number>";inherits:true;initial-value:0}
416
+ @property --kc-value-size{syntax:"<length>";inherits:true;initial-value:11.5px}
417
+ @property --kr-lo{syntax:"<number>";inherits:true;initial-value:0}
418
+ @property --kr-hi{syntax:"<number>";inherits:true;initial-value:0}
419
+ @property --kr-show-lo{syntax:"<number>";inherits:true;initial-value:0}
420
+ @property --kr-show-hi{syntax:"<number>";inherits:true;initial-value:0}
421
+ ${GRAD_PROPS}
422
+ :where(:root,:host){
423
+ --k-bg:#1c1c1e;--k-contrast:1;--k-surface:rgba(255,255,255,calc(.055 * var(--k-contrast)));--k-surface-hi:rgba(255,255,255,calc(.11 * var(--k-contrast)));--k-line:rgba(255,255,255,calc(.1 * var(--k-contrast)));--k-line-hi:rgba(255,255,255,calc(.18 * var(--k-contrast)));
424
+ --k-text:rgba(255,255,255,.92);--k-label:rgba(255,255,255,.64);--k-dim:rgba(255,255,255,.42);--k-accent:#fff;--k-modified:rgba(255,255,255,.5);
425
+ --k-seg-bg:rgba(0,0,0,.26);--k-seg-active:var(--k-surface-hi);--k-toggle-track:rgba(255,255,255,.14);--k-toggle-thumb:var(--k-bg);--k-shadow:0 12px 36px rgba(0,0,0,.52),0 1px 2px rgba(0,0,0,.3);
426
+ --k-rim:rgba(255,255,255,.1);--k-edge:rgba(255,255,255,calc(.07 * var(--k-contrast)));--k-rim-width:1px;--k-glass-tone:.5;--k-page:#101012;
427
+ --k-group-ink:rgba(255,255,255,.48);
428
+ --k-unit:4px;--k-density:1;--k-width:288px;--k-row:round(calc(32px * var(--k-density)),2px);--k-pad:round(calc(10px * var(--k-density)),2px);--k-inset:var(--k-pad);--k-gap:round(calc(var(--k-unit) * var(--k-density)),1px);--k-radius:round(calc(8px * var(--k-density)),2px);--k-panel-radius:calc(var(--k-radius) + var(--k-unit));
429
+ --k-font-size:round(calc(12px * var(--k-density)),.5px);--k-label-weight:500;--k-blur:1;--k-glow:0.5;--k-roll:320;--k-drag-roll:0;--k-cascade:12;--k-glass:0.6;
430
+ --k-font:system-ui,-apple-system,"SF Pro Text",sans-serif;
431
+ --k-mono:"SF Mono",SFMono-Regular,ui-monospace,Menlo,monospace;
432
+ --k-spring:0.24 0.16;--k-ease:cubic-bezier(.2,.8,.2,1);--k-reveal-ease:var(--k-ease);
433
+ --k-font-weight:400;--k-title-weight:600;--k-thumb:#fff;--k-lift:1;--k-frame:card;
434
+ --k-row-gap:0px;--k-hover-in:150;--k-hover-out:150;--k-fill-base:var(--k-surface-hi);--k-fill-rest-mix:20%;--k-fill-hover-mix:var(--k-fill-rest-mix);--k-fill-active-mix:30%;--k-chrome:1;--k-handle:var(--k-accent);--k-handle-inset:0px;--k-handle-rest:0;--k-step-resist:0.25;--k-motion-blur:0;--k-range-blur:.5;--k-group-transform:uppercase;--k-value-font:var(--k-font);
435
+ --k-lead:${lead.easing};--k-trail:${trail.easing};--k-fill-ease:${fill.easing};--k-fill-ms:${fill.ms};
436
+ }
437
+ /* Glass edges are hairlines: --k-rim-width is one device pixel at common pixel ratios. */
438
+ @media(min-resolution:1.5dppx){:where(:root,:host){--k-rim-width:.67px}}
439
+ @media(min-resolution:2dppx){:where(:root,:host){--k-rim-width:.5px}}
440
+ @media(min-resolution:3dppx){:where(:root,:host){--k-rim-width:.34px}}
441
+ :where(.knobs-panel,.knobs-chip,.knobs-toast)[data-theme="light"],
442
+ :where([data-knobs-theme="light"]) :where(.knobs-panel,.knobs-chip,.knobs-toast):not([data-theme="dark"]),
443
+ :where(:root[data-theme="light"]) :where(.knobs-panel,.knobs-chip,.knobs-toast)[data-theme="auto"]{${lightVars}}
444
+ @media(prefers-color-scheme:light){
445
+ :where(:root:not([data-theme="dark"])) :where(.knobs-panel,.knobs-chip,.knobs-toast)[data-theme="auto"]{${lightVars}}
446
+ }
447
+ :where(.knobs-panel)[data-density="compact"]{--k-density:.875;--k-row:28px;--k-gap:3px;--k-radius:6px;--k-panel-radius:calc(var(--k-radius) + var(--k-unit));--k-pad:8px;--k-inset:8px;--k-font-size:11px}
448
+ :where(.knobs-panel)[data-density="comfortable"]{--k-density:1.1875;--k-row:38px;--k-gap:6px;--k-radius:10px;--k-panel-radius:calc(var(--k-radius) + var(--k-unit));--k-pad:12px;--k-inset:12px;--k-font-size:13px}
449
+ `, css = `
450
+ :where(.knobs-panel,.knobs-chip,.knobs-menu){
451
+ --k-tray-pad:calc(var(--k-unit) * .5);
452
+ --k-section-gap:calc(var(--k-gap) * 2);
453
+ --k-group-gap:calc(var(--k-gap) * 3);
454
+ /* Public sizes a host may set anywhere (:root, the panel, a preset); derived otherwise. */
455
+ --kc-control-h:var(--k-control-h,calc(var(--k-row) - var(--k-unit) * 2));
456
+ --kc-value-size:var(--k-value-size,calc(var(--k-font-size) - .5px));
457
+ --k-action-h:calc(var(--k-row) - var(--k-unit));
458
+ --k-track-h:calc(var(--k-row) - 14px);
459
+ --k-icon-btn:22px;
460
+ --k-icon-size:14px;
461
+ --k-icon-sm:13px;
462
+ --k-radius-md:max(0px,calc(var(--k-radius) - var(--k-tray-pad)));
463
+ --k-radius-sm:max(0px,calc(var(--k-radius) - var(--k-tray-pad) * 2));
464
+ /* Round things (switches, icon buttons, handles, thumbs): capsules, or square with --k-radius 0. */
465
+ --k-round:calc(var(--k-radius) * 999);
466
+ --k-lift-shadow:0 1px 2px rgba(0,0,0,calc(.16 * var(--k-lift)));
467
+ --k-text-title:calc(var(--k-font-size) + 1px);
468
+ --k-text-body:var(--k-font-size);
469
+ --k-text-control:calc(var(--k-font-size) - .5px);
470
+ --k-text-meta:calc(var(--k-font-size) - 1px);
471
+ --k-text-cap:calc(var(--k-font-size) - 2px);
472
+ --k-row-hover:color-mix(in srgb,var(--k-surface) 50%,transparent);
473
+ --k-pill-bg:color-mix(in srgb,var(--k-accent) 18%,var(--k-seg-active));
474
+ --k-pill-border:color-mix(in srgb,var(--k-accent) 18%,transparent);
475
+ --k-fill-rest:color-mix(in srgb,var(--k-accent) var(--k-fill-rest-mix),var(--k-fill-base));
476
+ --k-fill-active:color-mix(in srgb,var(--k-accent) var(--k-fill-active-mix),var(--k-fill-base));
477
+ --k-disabled-opacity:.32;
478
+ --k-unit-gap:.28em;--k-unit-color:var(--k-dim);--k-readout-mark:0;
479
+ --k-group-size:var(--k-text-cap);--k-group-color:var(--k-group-ink);--k-group-inset:var(--k-inset);--k-group-tracking:.04em;--k-group-divider:transparent;--k-group-divider-gap:0px;
480
+ --k-curve-inset:6px;--k-curve-guide:solid;--k-curve-dot:1;
481
+ --k-hint-typed-opacity:.42;
482
+ }
483
+ /* Inherited text properties that a host's element rules set on its own elements (span{letter-
484
+ spacing}, div{line-height}, *{box-sizing}) come from the panel instead. (0,1,0) and first, so
485
+ every knobs rule wins over it; the host's accessories and custom card contents are its own. */
486
+ .knobs-panel *:where(:not(.knobs-accessory,.knobs-accessory *,.knobs-live *)),.knobs-menu *{box-sizing:border-box;color:inherit;letter-spacing:inherit;word-spacing:inherit;line-height:inherit;text-transform:inherit;text-shadow:inherit;font-style:inherit}
487
+ /* Hover washes come in at --k-hover-in and leave at --k-hover-out (ms). Set per element, so a
488
+ hovered card doesn't hand its quick entrance to the rows inside it. */
489
+ :where(.knobs-panel,.knobs-menu) *{--k-hover-t:calc(var(--k-hover-out) * 1ms)}
490
+ :where(.knobs-panel,.knobs-menu) :is(:hover,.knobs-active){--k-hover-t:calc(var(--k-hover-in) * 1ms)}
491
+
492
+ .knobs-panel,.knobs-chip{
493
+ box-sizing:border-box;font:var(--k-font-weight) var(--k-font-size)/1.35 var(--k-font);color:var(--k-text);text-align:left;color-scheme:dark;
494
+ -webkit-font-smoothing:antialiased;
495
+ }
496
+ /* Text properties a host page sets on its own elements (letter-spacing, capitals, shadows) stop
497
+ at the panel: it inherits only its tokens. */
498
+ .knobs-panel,.knobs-chip,.knobs-menu{letter-spacing:normal;word-spacing:normal;text-transform:none;text-indent:0;text-shadow:none;text-decoration:none;font-style:normal;font-variant:normal;font-feature-settings:normal;font-kerning:auto;white-space:normal;direction:ltr;margin:0;float:none}
499
+ :where(.knobs-panel,.knobs-chip) :where(*,*::before,*::after){box-sizing:border-box}
500
+ .knobs-panel .rn-slot{box-sizing:content-box}
501
+ .knobs-panel [hidden],.knobs-chip[hidden]{display:none!important}
502
+ .knobs-mono{font-family:var(--k-mono);font-variant-numeric:tabular-nums}
503
+
504
+ /* The chip: a round cog button, or a capsule with a label beside the cog. */
505
+ .knobs-chip{position:fixed;z-index:2147480000;display:inline-flex;align-items:center;justify-content:center;gap:5px;width:26px;height:26px;padding:0;border-radius:999px;cursor:pointer;background:var(--k-bg);border:1px solid transparent;
506
+ color:var(--k-label);font-size:var(--k-text-control);line-height:1;letter-spacing:.01em;white-space:nowrap;--k-chip-edge:var(--k-edge);box-shadow:0 0 0 var(--k-rim-width) var(--k-chip-edge),0 4px 16px rgba(0,0,0,.35),inset 0 var(--k-rim-width) 0 var(--k-rim);transition:color .15s,border-color .15s,transform .2s var(--k-ease),opacity .2s,scale .12s var(--k-ease),${TOKEN_TRANSITIONS};}
507
+ .knobs-chip[data-label]{width:auto;padding:0 10px 0 7px}
508
+ .knobs-chip .knobs-icon{display:block;flex:none;width:15px;height:15px}
509
+ .knobs-chip:hover{color:var(--k-text);--k-chip-edge:var(--k-line-hi)}
510
+ .knobs-chip[data-shown="true"]{transition:color .15s,border-color .15s,opacity .16s var(--k-ease),transform .22s var(--k-ease),scale .12s var(--k-ease),visibility 0s,${TOKEN_TRANSITIONS}}
511
+ .knobs-chip[data-shown="false"]{opacity:0;visibility:hidden;pointer-events:none;transform:translateY(-2px) scale(.94);transition:opacity .12s ease-in,transform .12s ease-in,visibility 0s .12s,${TOKEN_TRANSITIONS}}
512
+ /* A press squeezes it, easing in (morph.ts carries the squeeze on into the glass). */
513
+ .knobs-chip.knobs-chip[data-pressed]{scale:.94;transition:color .15s,border-color .15s,scale 50ms ease-in-out,${TOKEN_TRANSITIONS}}
514
+ .knobs-chip:focus-visible{outline:none;color:var(--k-text);--k-chip-edge:var(--k-line-hi)}
515
+ @media(prefers-reduced-motion:reduce){.knobs-chip.knobs-chip{scale:none;transform:none}}
516
+ /* "knobs on" / "knobs off" after the reveal shortcut. */
517
+ .knobs-toast{position:fixed;left:50%;bottom:24px;z-index:2147480004;translate:-50% 0;padding:6px 12px;border-radius:999px;pointer-events:none;
518
+ background:var(--k-bg);border:1px solid var(--k-line);box-shadow:0 4px 16px rgba(0,0,0,.35);color:var(--k-text);font:500 12px/1.2 var(--k-font);letter-spacing:.01em;
519
+ transition:opacity .18s var(--k-ease),scale .18s var(--k-ease)}
520
+ .knobs-toast[data-shown="false"]{opacity:0;scale:.96;transition:opacity .16s ease-in,scale .16s ease-in}
521
+
522
+ /* Tokens glide on the panel spring. While a control is dragged (data-knobs-scrub) they follow it
523
+ step for step instead: the pointer already moves them continuously, and a declared transition
524
+ makes every step restyle the panel twice. */
525
+ .knobs-panel,.knobs-chip{--k-token-t:calc(var(--k-fill-ms) * 1ms) var(--k-fill-ease)}
526
+ :root[data-knobs-scrub] .knobs-chip{--k-token-t:0s}
527
+ :root[data-knobs-scrub] .knobs-panel{transition:none}
528
+ @media(prefers-reduced-motion:reduce){.knobs-chip{--k-token-t:0s}.knobs-panel.knobs-panel{transition:none}}
529
+ /* Panel material: --k-glass (0 opaque … 1 clearest) thins the surface over a blurred, saturated
530
+ backdrop, toned toward the theme (--k-glass-tone dims it under dark panels) so text keeps its
531
+ contrast. Its edge is a hairline (--k-edge, --k-rim-width wide) and a hairline of light (--k-rim)
532
+ catches its top. */
533
+ .knobs-panel{-webkit-user-select:none;user-select:none;transition:${TOKEN_TRANSITIONS};position:fixed;z-index:2147480001;width:var(--k-width);max-width:calc(100vw - 16px);max-height:calc(100dvh - 16px);overflow:auto;padding:var(--k-pad);
534
+ background:color-mix(in srgb,var(--k-bg) calc(100% - var(--k-glass) * 20%),transparent);border:1px solid transparent;border-radius:var(--k-panel-radius);box-shadow:var(--k-shadow),0 0 0 var(--k-rim-width) var(--k-edge),inset 0 var(--k-rim-width) 0 var(--k-rim);scrollbar-width:thin;
535
+ --k-backdrop:blur(calc(var(--k-glass) * 24px)) saturate(calc(1 + var(--k-glass) * .8)) brightness(calc(1 + (var(--k-glass-tone) - 1) * var(--k-glass)));
536
+ -webkit-backdrop-filter:var(--k-backdrop);backdrop-filter:var(--k-backdrop);
537
+ animation:knobs-in .16s var(--k-ease);}
538
+ .knobs-panel[data-restored]{animation:none}
539
+ /* Opening from its chip, the panel's chrome rides a separate shape (see morph.ts) while the
540
+ content, laid out at full size, is clipped to it and revealed top first. */
541
+ .knobs-panel[data-morphing]{background:transparent;border-color:transparent;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;animation:none}
542
+ .knobs-morph{position:fixed;left:0;top:0;z-index:2147480001;pointer-events:none;box-sizing:border-box;--p:0;--spec:0;
543
+ background:color-mix(in srgb,var(--k-bg) calc(100% - var(--k-glass) * 20% * var(--p)),transparent);border:1px solid transparent;
544
+ box-shadow:0 0 0 var(--k-rim-width) var(--k-edge),inset 0 0 0 var(--k-rim-width) rgb(255 255 255/var(--spec)),inset 0 var(--k-rim-width) 0 color-mix(in srgb,var(--k-rim) calc(var(--p) * 100%),transparent);
545
+ --k-backdrop:blur(calc(var(--k-glass) * 24px)) saturate(calc(1 + var(--k-glass) * .8)) brightness(calc(1 + (var(--k-glass-tone) - 1) * var(--k-glass)));
546
+ -webkit-backdrop-filter:var(--k-backdrop);backdrop-filter:var(--k-backdrop)}
547
+ .knobs-morph::before,.knobs-morph::after{content:"";position:absolute;inset:-1px;border-radius:inherit;pointer-events:none}
548
+ .knobs-morph::before{box-shadow:0 4px 16px rgba(0,0,0,.35);opacity:calc(1 - var(--p))}
549
+ .knobs-morph::after{box-shadow:var(--k-shadow);opacity:var(--p)}
550
+ /* Meanwhile the chip is just its label, fading on the shape. */
551
+ .knobs-chip.knobs-chip[data-morph]{visibility:visible;pointer-events:auto;transform:none;transition:none;background:transparent;border-color:transparent;box-shadow:none}
552
+ .knobs-panel.knobs-inline{position:relative;z-index:auto;left:auto!important;top:auto!important;max-width:100%;max-height:none;box-shadow:0 0 0 var(--k-rim-width) color-mix(in srgb,var(--k-edge) calc(var(--k-chrome) * 100%),transparent),inset 0 var(--k-rim-width) 0 color-mix(in srgb,var(--k-rim) calc(var(--k-chrome) * 100%),transparent);animation:none;
553
+ /* --k-chrome 0: an embedded panel sheds its card (background, border, rim) for the host's column,
554
+ border width too, so its rows line up with the column's edges. */
555
+ border-width:calc(var(--k-chrome) * 1px);
556
+ background:color-mix(in srgb,color-mix(in srgb,var(--k-bg) calc(100% - var(--k-glass) * 20%),transparent) calc(var(--k-chrome) * 100%),transparent);border-color:transparent;
557
+ --k-backdrop:blur(calc(var(--k-glass) * var(--k-chrome) * 24px)) saturate(calc(1 + var(--k-glass) * var(--k-chrome) * .8)) brightness(calc(1 + (var(--k-glass-tone) - 1) * var(--k-glass) * var(--k-chrome)))}
558
+ @keyframes knobs-in{from{opacity:0;transform:translateY(4px) scale(.985)}to{opacity:1;transform:none}}
559
+ @media(prefers-reduced-motion:reduce){.knobs-panel{animation:none}.knobs-panel *{transition:none!important}}
560
+
561
+ /* A scoped reset, (0,1,1): above a host's element rules (button{...}, button:hover{...},
562
+ input[type=text]{...}) and below every knobs rule that styles these elements, which are all
563
+ (0,1,1) or more and come later. */
564
+ :is(.knobs-panel,.knobs-menu) :is(button,input,select,textarea):where(:not(.knobs-accessory *)){all:revert;box-sizing:border-box;font:inherit;color:inherit;letter-spacing:inherit;text-transform:inherit;text-shadow:none;
565
+ background:var(--k-surface);border:0;border-radius:var(--k-radius);min-width:0;box-shadow:none;outline:none}
566
+ :is(.knobs-panel,.knobs-menu) :is(header,strong,p,kbd,aside,mark):where(:not(.knobs-accessory *)){all:revert;box-sizing:border-box;margin:0;padding:0;font:inherit;color:inherit;letter-spacing:inherit;text-transform:inherit}
567
+ .knobs-panel .knobs-icon>path{fill:currentColor}
568
+ :is(.knobs-panel,.knobs-menu) :is(:focus,:focus-visible):where(:not(.knobs-accessory *)){outline:none}
569
+
570
+ /* Header */
571
+ .knobs-panel header{display:flex;align-items:center;justify-content:space-between;gap:6px;cursor:grab;touch-action:none;padding:0 var(--k-inset) var(--k-section-gap);min-height:var(--k-icon-btn)}
572
+ .knobs-panel.knobs-inline header,.knobs-panel.knobs-inline header:active{cursor:default}
573
+ .knobs-panel header:active{cursor:grabbing}
574
+ .knobs-panel header strong{flex:1;min-width:0;font-weight:var(--k-title-weight);font-size:var(--k-text-title);letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:opacity .2s var(--k-ease)}
575
+ /* Holding \\ shows the values from before the last change; the title dims meanwhile. */
576
+ .knobs-panel[data-comparing] header strong{opacity:.4}
577
+ .knobs-head-actions{display:flex;align-items:center;margin-right:calc((var(--k-icon-size) - var(--k-icon-btn)) / 2)}
578
+ .knobs-head-split{margin-left:calc(var(--k-unit) * 1.5)}
579
+ .knobs-icon{width:var(--k-icon-size);height:var(--k-icon-size);display:block;flex:none}
580
+ .knobs-die-icon{position:relative;display:block;width:var(--k-icon-size);height:var(--k-icon-size);flex:none}
581
+ .knobs-die-icon>canvas{position:absolute;margin:0}
582
+ .knobs-panel[data-gpu-active="true"] .knobs-die-icon>canvas{visibility:hidden}
583
+ /* The tools sit quiet (--k-dim) until the panel has the pointer or keyboard focus, then read as
584
+ labels, and as text under the pointer. */
585
+ .knobs-panel header button{position:relative;width:var(--k-icon-btn);height:var(--k-icon-btn);padding:0;display:inline-flex;align-items:center;justify-content:center;color:var(--k-dim);background:transparent;border-radius:var(--k-round);cursor:pointer;font-size:12px;line-height:1;transition:background .15s,color .15s,opacity .15s}
586
+ .knobs-panel:is(:hover,:has(:focus-visible)) header button{color:var(--k-label)}
587
+ .knobs-panel header button:is(:hover:not([disabled]),:focus-visible),.knobs-panel header button[aria-expanded="true"]{background:var(--k-surface-hi);color:var(--k-text)}
588
+ .knobs-panel header button[disabled]{opacity:var(--k-disabled-opacity);cursor:default}
589
+ /* The close X's ink sits a fifth of its box in from each side, a digit's barely: nudged right, its
590
+ ink ends where the values' digits do. */
591
+ .knobs-panel header .knobs-close>.knobs-icon{translate:calc(var(--k-icon-size) * .1) 0}
592
+ /* Undo and redo fold in (room first, then the icons) once there's history, and away without it. */
593
+ .knobs-head-history{display:flex;flex:none;overflow:hidden;width:calc(var(--k-icon-btn) * 2);margin-left:calc(var(--k-unit) * 1.5);transition:width .26s var(--k-ease),margin .26s var(--k-ease)}
594
+ .knobs-head-history[data-single]{width:var(--k-icon-btn)}
595
+ .knobs-head-history[data-shown="false"]{width:0;margin-left:0;transition:width .24s var(--k-ease) .06s,margin .24s var(--k-ease) .06s}
596
+ .knobs-panel .knobs-head-history>button{transition:background .15s,color .15s,opacity .18s var(--k-ease) .08s,scale .3s cubic-bezier(.34,1.45,.64,1) .08s}
597
+ .knobs-panel .knobs-head-history[data-shown="false"]>button{opacity:0;scale:.6;transition:background .15s,color .15s,opacity .12s ease-in,scale .14s ease-in}
598
+ /* Copied: the glyph shrinks away and a check draws itself in its place, held, then they trade
599
+ back (the check fading). Driven by --k-copy (the glyph), --k-check (how much of the check is
600
+ drawn) and --k-check-a (its opacity), which the GPU renderer reads too. */
601
+ .knobs-panel header .knobs-copy{--k-copy:1;--k-check:0;--k-check-a:0;
602
+ transition:background .15s,color .15s,opacity .15s,--k-copy .32s cubic-bezier(.34,1.45,.64,1) .08s,--k-check 0s .18s,--k-check-a .16s ease-in}
603
+ .knobs-panel header .knobs-copy[data-copied]{--k-copy:0;--k-check:1;--k-check-a:1;color:var(--k-text);
604
+ transition:background .15s,color .15s,opacity .15s,--k-copy .14s ease-in,--k-check .28s cubic-bezier(.3,.7,.2,1) .06s,--k-check-a .05s linear .06s}
605
+ .knobs-copy>.knobs-icon:not(.knobs-check){opacity:var(--k-copy);scale:calc(.5 + .5 * var(--k-copy))}
606
+ .knobs-copy>.knobs-check{position:absolute;inset:0;margin:auto;opacity:var(--k-check-a)}
607
+ /* (Over .knobs-icon>path's fill: the check is a stroke, 16 of 256 wide like Phosphor's regular icons.) */
608
+ .knobs-panel .knobs-icon.knobs-check>path{fill:none;stroke:currentColor;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1 2;stroke-dashoffset:calc(1 - var(--k-check))}
609
+ .knobs-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
610
+
611
+ /* Shortcuts Popover */
612
+ .knobs-popover{margin:0 0 var(--k-section-gap);padding:var(--k-section-gap) var(--k-inset);background:var(--k-surface-hi);border:1px solid var(--k-line);border-radius:var(--k-radius);font-size:var(--k-text-meta)}
613
+ .knobs-popover-grid{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;align-items:baseline}
614
+ .knobs-popover-grid kbd{font:var(--k-text-cap)/1 var(--k-mono);font-variant-numeric:tabular-nums;color:var(--k-text);background:var(--k-seg-bg);padding:2px 5px;border-radius:var(--k-radius-sm);justify-self:start;white-space:nowrap}
615
+ .knobs-popover-grid span{color:var(--k-label)}
616
+
617
+ /* Custom Preset Strip */
618
+ .knobs-presets{position:relative;display:flex;align-items:flex-start;gap:var(--k-tray-pad);margin:0 0 var(--k-section-gap);padding:var(--k-tray-pad);background:var(--k-seg-bg);border-radius:var(--k-radius);user-select:none;touch-action:none}
619
+ .knobs-presets-track{position:relative;flex:1;min-width:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,var(--k-preset-min,58px)),1fr));align-items:stretch;gap:var(--k-tray-pad)}
620
+ /* The selected pill is placed by its edges: the edge facing the move leads, the other trails. */
621
+ .knobs-presets-pill{position:absolute;top:0;left:0;background:var(--k-pill-bg);border:0;border-radius:var(--k-button-radius,var(--k-radius-md));box-shadow:inset 0 0 0 var(--k-rim-width) var(--k-pill-border),inset 0 var(--k-rim-width) 0 var(--k-rim),var(--k-lift-shadow),0 0 calc(var(--k-glow) * 10px) color-mix(in srgb,var(--k-accent) 24%,transparent);pointer-events:none;
622
+ transition:left ${TRAIL_T},right ${LEAD_T},top ${LEAD_T},opacity .15s,scale .15s}
623
+ .knobs-presets-pill[data-dir="left"]{transition:left ${LEAD_T},right ${TRAIL_T},top ${LEAD_T},opacity .15s,scale .15s}
624
+ .knobs-panel .knobs-preset-chip{position:relative;z-index:1;height:var(--k-button-h,var(--kc-control-h));min-height:20px;padding:0 6px;font-size:var(--k-button-font-size,var(--k-text-control));font-weight:var(--k-label-weight);color:var(--k-button-color,var(--k-label));background:transparent!important;border-radius:var(--k-button-radius,var(--k-radius-md));cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .15s,background .15s,box-shadow .15s}
625
+ .knobs-panel[data-buttons] .knobs-presets{background:transparent;padding:0}
626
+ .knobs-panel[data-buttons] .knobs-preset-chip{background:var(--k-button-bg,transparent)!important;box-shadow:inset 0 0 0 1px var(--k-button-line,transparent)}
627
+ .knobs-panel[data-buttons] .knobs-preset-chip:hover{background:var(--k-button-hover-bg,var(--k-surface-hi))!important;box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent))}
628
+ .knobs-panel .knobs-preset-chip:hover{color:var(--k-text)}
629
+ .knobs-panel .knobs-preset-chip[aria-checked="true"]{color:var(--k-text);font-weight:var(--k-title-weight)}
630
+ .knobs-panel .knobs-preset-save{flex:none;width:calc((var(--k-inset) - var(--k-tray-pad)) * 2 + 8px);padding:0!important;color:var(--k-dim)!important;font-weight:400!important;font-size:var(--k-text-title)!important}
631
+ .knobs-panel .knobs-preset-save:hover{color:var(--k-text)!important}
632
+
633
+ /* Group headers */
634
+ .knobs-group-head{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:20px;margin:var(--k-group-gap) 0 var(--k-gap);padding:0 var(--k-group-inset);color:var(--k-group-color);font-size:var(--k-group-size);font-weight:var(--k-title-weight);letter-spacing:var(--k-group-tracking);text-transform:var(--k-group-transform)}
635
+ .knobs-panel:not(.knobs-page) .knobs-group-head:not(:first-child){border-top:1px solid var(--k-group-divider);padding-top:var(--k-group-divider-gap)}
636
+ .knobs-group-head:first-child{margin-top:0}
637
+ .knobs-group-head>span:last-child{display:flex;align-items:center;gap:var(--k-tray-pad);margin-right:calc((var(--k-icon-sm) - 20px) / 2)}
638
+ .knobs-group-head button{height:20px;padding:0 6px;font-size:var(--k-text-meta);font-weight:500;letter-spacing:0;text-transform:none;color:var(--k-label);background:transparent;border-radius:var(--k-radius-sm);cursor:pointer}
639
+ .knobs-group-head button:is(:hover:not([disabled]),:focus-visible){background:var(--k-surface-hi);color:var(--k-text)}
640
+ .knobs-group-head .knobs-group-reset{width:20px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--k-round);
641
+ transition:opacity .18s var(--k-ease),transform .3s cubic-bezier(.34,1.45,.64,1),background .15s,color .15s,visibility 0s}
642
+ .knobs-group-head :is(.knobs-icon,.knobs-die-icon){width:var(--k-icon-sm);height:var(--k-icon-sm)}
643
+ .knobs-group-reset[data-shown="false"]{opacity:0;visibility:hidden;transform:scale(.55);transition:opacity .14s ease-in,transform .14s ease-in,visibility 0s .14s}
644
+ .knobs-group-head .knobs-group-die{width:20px;padding:0;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--k-round);color:var(--k-dim)}
645
+ .knobs-group-head .knobs-group-die[disabled]{opacity:var(--k-disabled-opacity);cursor:default}
646
+ .knobs-panel .knobs-group-head button:where(:not(.knobs-group-reset)){transition:background .15s,color .15s,opacity .2s,transform .12s}
647
+
648
+ /* Grouped cards: rows share one surface, split by hairlines */
649
+ .knobs-card{position:relative;margin-bottom:var(--k-section-gap);border-radius:var(--k-radius);background:var(--k-surface);overflow:hidden}
650
+ .knobs-card:last-child{margin-bottom:0}
651
+ .knobs-card>*{position:relative;min-height:var(--k-row);transition:background var(--k-hover-t),opacity .2s}
652
+ .knobs-card>:hover,.knobs-card>.knobs-active{background:var(--k-row-hover)}
653
+ .knobs-card>*+*::before{content:"";position:absolute;z-index:1;left:0;right:0;top:0;height:1px;transform:scaleY(.5);transform-origin:top;background:var(--k-line);pointer-events:none;transition:opacity .15s}
654
+ .knobs-card>:is(:hover:not(.knobs-x),.knobs-x:has(>.knobs-x-head:is(:hover,:focus-visible)),:has(:focus-visible):not(.knobs-x),.knobs-active)::before,.knobs-card>:is(:hover:not(.knobs-x),.knobs-x:has(>.knobs-x-head:is(:hover,:focus-visible)),:has(:focus-visible):not(.knobs-x),.knobs-active)+*::before{opacity:0}
655
+ .knobs-card>::after{content:"";position:absolute;z-index:2;inset:0;background:var(--k-surface);opacity:0;pointer-events:none;transition:opacity .15s,box-shadow .15s}
656
+ .knobs-card>:has(:focus-visible)::after{opacity:1}
657
+ /* One wash at a time: while the pointer has a row (and keys haven't taken over since), a focus
658
+ wash elsewhere steps aside, and the hairlines beside that row come back. */
659
+ ${POINTER_ROW} :is(.knobs-card>*,.knobs-sub,.knobs-x-head):not(:hover)::after{opacity:0}
660
+ ${POINTER_ROW} .knobs-card>:not(:hover,.knobs-active,:hover+*,.knobs-active+*)::before{opacity:1}
661
+ .knobs-panel .knobs-slider{height:var(--k-row);contain:layout style}
662
+ .knobs-panel .knobs-row:where(:not(.knobs-slider,.knobs-x,.knobs-spring)){display:flex;align-items:center;justify-content:space-between;gap:8px;height:var(--k-row);padding:0 var(--k-inset);contain:layout style}
663
+ .knobs-panel .knobs-row>span:first-child{color:var(--k-label);font-weight:var(--k-label-weight);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
664
+ .knobs-row>span:first-child::after{content:"";display:inline-block;width:4px;height:4px;margin-left:5px;border-radius:50%;background:var(--k-modified);vertical-align:middle;opacity:0;transform:scale(.4);transition:opacity .16s ease-out,transform .28s cubic-bezier(.34,1.5,.64,1)}
665
+ .knobs-modified.knobs-row>span:first-child::after{opacity:.95;transform:none}
666
+ /* A locked row's lock sits just left of its readout (or its control), where the eye reads the value.
667
+ Its room opens at once (it's right-aligned, so nothing beside it moves); the icon fades and
668
+ scales in place. */
669
+ .knobs-lock{position:relative;flex:none;order:-1;display:inline-block;width:0;height:10px;color:var(--k-dim)}
670
+ .knobs-lock>svg{position:absolute;right:0;top:0;width:10px;height:10px;opacity:0;transform:scale(.5);transition:opacity .14s ease-in,transform .14s ease-in}
671
+ .knobs-locked .knobs-lock{width:10px}
672
+ .knobs-value>.knobs-lock>svg{right:6px}
673
+ .knobs-locked .knobs-value>.knobs-lock{width:16px}
674
+ .knobs-row>.knobs-lock{order:0;margin-left:auto}
675
+ .knobs-locked .knobs-lock>svg{opacity:1;transform:none;transition:opacity .18s var(--k-ease),transform .3s cubic-bezier(.34,1.45,.64,1)}
676
+ /* On iPhones a switch's tap lands on a label for a hidden native switch: iOS's system tick. */
677
+ .knobs-tap-tick{position:absolute;inset:0;border-radius:inherit;-webkit-tap-highlight-color:transparent}
678
+
679
+ /* Slider: one flat accent-tinted fill, a hairline handle on its edge and centerline scale ticks.
680
+ The ticks and handle fade where the label and readout sit (--k-text-mask). The fill and handle
681
+ are moved by transforms, never layout or background sizes, which snap to whole pixels: the
682
+ edge and the handle's centre both land on the value's exact sub-pixel position, as on the GPU. */
683
+ .knobs-track{position:absolute;left:0;right:0;top:0;height:var(--k-row);overflow:hidden;contain:layout style paint;cursor:ew-resize;user-select:none;touch-action:none;transition:--k-readout .25s var(--k-ease);
684
+ --k-text-mask:linear-gradient(to right,transparent calc(var(--k-label-end,0px) + 4px),#000 calc(var(--k-label-end,0px) + 12px),#000 calc(100% - var(--k-inset) - var(--k-readout) - 12px),transparent calc(100% - var(--k-inset) - var(--k-readout) - 4px))}
685
+ .knobs-panel .knobs-track:focus-visible{outline:none;box-shadow:none}
686
+ .knobs-marks,.knobs-handle-zone{position:absolute;inset:0;pointer-events:none;-webkit-mask:var(--k-text-mask);mask:var(--k-text-mask)}
687
+ .knobs-marks>i{position:absolute;top:50%;width:1px;height:7px;border-radius:999px;transform:translate(-50%,-50%);background:transparent;transition:background .2s}
688
+ .knobs-fill{position:absolute;inset:0;pointer-events:none;--k-fill-mix:var(--k-fill-rest-mix);--k-fill-tint:color-mix(in srgb,var(--k-accent) var(--k-fill-mix),var(--k-fill-base));
689
+ background:var(--k-fill-tint);transform:translateX(calc(var(--k-fill) - 100%));transition:--k-fill-mix .15s}
690
+ .knobs-slider:hover .knobs-fill{--k-fill-mix:var(--k-fill-hover-mix)}
691
+ .knobs-active .knobs-fill,.knobs-active:hover .knobs-fill{--k-fill-mix:var(--k-fill-active-mix)}
692
+ /* --k-motion-blur: a moving edge smears into a ramp as wide as its speed (--k-smear, px), as a
693
+ horizontal box blur would; the handle widens and thins to match. */
694
+ .knobs-smear .knobs-fill{background:linear-gradient(to left,transparent,var(--k-fill-tint) calc(var(--k-smear) * 1px));transform:translateX(calc(var(--k-fill) - 100% + var(--k-smear) * .5px))}
695
+ .knobs-smear .knobs-handle::before{scale:calc(1 + var(--k-smear) / 3) 1;opacity:calc(3 / (3 + var(--k-smear)))}
696
+ .knobs-animate .knobs-fill,.knobs-animate .knobs-handle{transition:--k-fill ${SLIDE_T} ${DELAY},--k-fill-mix .15s,opacity .15s}
697
+ .knobs-settle .knobs-fill,.knobs-settle .knobs-handle{transition:--k-fill .1s cubic-bezier(.25,1,.5,1),--k-fill-mix .12s,opacity .15s}
698
+ /* The default: a short notch rising from the bottom edge, only while the row is in hand. */
699
+ .knobs-marks>.knobs-notch{top:auto;bottom:0;width:1.5px;height:4px;border-radius:999px 999px 0 0;transform:translateX(-50%);background:var(--k-accent);opacity:0;transition:opacity .2s,height .15s var(--k-ease)}
700
+ .knobs-slider:is(:hover,.knobs-active,:has(:focus-visible)) .knobs-notch{opacity:.38}
701
+ .knobs-slider.knobs-modified:is(:hover,.knobs-active,:has(:focus-visible)) .knobs-notch{opacity:.55}
702
+ .knobs-magnet .knobs-notch{opacity:.95;height:6px}
703
+ /* The handle is a full-width layer moved by the fill (translate's % is its own width, the track's). */
704
+ .knobs-handle{position:absolute;inset:0;pointer-events:none;transform:translateX(var(--k-fill));opacity:var(--k-handle-rest);transition:opacity .15s}
705
+ .knobs-handle::before{content:"";position:absolute;left:0;top:50%;width:3px;height:calc(var(--k-row) - 12px);margin-top:calc(6px - var(--k-row) / 2);translate:calc(-50% - var(--k-handle-inset)) 0;border-radius:var(--k-round);background:var(--k-handle);
706
+ box-shadow:0 0 calc(var(--k-glow) * 8px) color-mix(in srgb,var(--k-accent) 60%,transparent);transform:scaleX(calc(.25 + .75 * min(1, var(--k-handle-rest) * 4)));transition:transform .22s var(--k-ease)}
707
+ .knobs-slider:hover .knobs-handle,.knobs-track:focus-visible .knobs-handle{opacity:max(.65,var(--k-handle-rest))}
708
+ .knobs-active .knobs-handle{opacity:.95}
709
+ .knobs-slider:is(:hover,.knobs-active) .knobs-handle::before,.knobs-track:focus-visible .knobs-handle::before{transform:scaleX(1)}
710
+ .knobs-slider:is(:hover,:has(:focus-visible)) .knobs-marks>i:not(.knobs-notch){background:color-mix(in srgb,var(--k-accent) 15%,transparent)}
711
+ .knobs-active .knobs-marks>i:not(.knobs-notch){background:color-mix(in srgb,var(--k-accent) 22%,transparent)}
712
+ /* A focused slider the pointer has left for another row rests meanwhile (one row lit at a time). */
713
+ ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-marks>i:not(.knobs-notch){background:transparent}
714
+ ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-notch{opacity:0}
715
+ ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-handle{opacity:var(--k-handle-rest)}
716
+ ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-handle::before{transform:scaleX(calc(.25 + .75 * min(1, var(--k-handle-rest) * 4)))}
717
+ ${POINTER_ROW} .knobs-slider:not(:hover,.knobs-active) .knobs-value{color:var(--k-label)}
718
+ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-value{color:color-mix(in srgb,var(--k-modified) calc(var(--k-readout-mark) * 100%),var(--k-label))}
719
+ .knobs-digits{display:inline-flex;align-items:center;line-height:2.1;margin-block:-.375em;--rn-edge-fade:.5em}
720
+ .knobs-unit{color:var(--k-unit-color);margin-left:var(--k-unit-gap)}
721
+ /* --k-readout-mark (0 or 1): a modified value takes the modified colour behind a small dot. */
722
+ .knobs-value::before{content:"";flex:none;width:calc(5px * var(--k-readout-mark));height:5px;margin-right:calc(6px * var(--k-readout-mark));border-radius:50%;background:var(--k-modified);opacity:0;transform:scale(0);transition:opacity .16s ease,transform .3s cubic-bezier(.34,1.56,.64,1)}
723
+ :is(.knobs-slider,.knobs-sub).knobs-modified .knobs-value{color:color-mix(in srgb,var(--k-modified) calc(var(--k-readout-mark) * 100%),var(--k-label))}
724
+ :is(.knobs-slider,.knobs-sub).knobs-modified:is(.knobs-active,:has(.knobs-track:focus-visible)) .knobs-value{color:color-mix(in srgb,var(--k-modified) calc(var(--k-readout-mark) * 100%),var(--k-text))}
725
+ :is(.knobs-slider,.knobs-sub).knobs-modified .knobs-value::before{opacity:var(--k-readout-mark);transform:none}
726
+ .knobs-label{position:absolute;left:var(--k-inset);top:50%;transform:translateY(-50%);max-width:calc(100% - var(--k-inset) * 2 - var(--k-readout,48px) - 8px - var(--k-accessory-w,0px));overflow:hidden;text-overflow:ellipsis;color:var(--k-label);font-weight:var(--k-label-weight);pointer-events:none;white-space:nowrap}
727
+ .knobs-panel .knobs-value{position:absolute;right:var(--k-inset);top:50%;transform:translateY(-50%);transform-origin:100% 0;display:inline-flex;align-items:center;justify-content:flex-end;gap:0;padding:4px 0 4px 8px;background:transparent!important;border-radius:0!important;line-height:1.35;overflow:visible;white-space:nowrap;
728
+ color:var(--k-label);font-family:var(--k-value-font);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";font-size:var(--kc-value-size);
729
+ cursor:text;transition:color .15s}
730
+ .knobs-active .knobs-value,.knobs-track:focus-visible .knobs-value{color:var(--k-text)}
731
+ /* Editing: the digits' own text, in place (edit() gives it their right edge and width), with no
732
+ box: a soft accent selection, an accent caret, and the unit still after it. */
733
+ .knobs-panel :is(.knobs-number,.knobs-number-fit){position:absolute;top:50%;z-index:2;margin:0;padding:0 1px 0 0;border:0;border-radius:0;background:transparent;box-shadow:none;outline:none;
734
+ font-family:var(--k-value-font);font-size:var(--kc-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";letter-spacing:normal;line-height:1.35;text-align:right;white-space:pre}
735
+ .knobs-panel .knobs-number{transform:translateY(-50%);color:var(--k-text);caret-color:var(--k-accent)}
736
+ .knobs-number::selection{background:color-mix(in srgb,var(--k-accent) 24%,transparent);color:var(--k-text)}
737
+ .knobs-panel .knobs-number-fit{left:0;visibility:hidden;pointer-events:none}
738
+ .knobs-editing .knobs-digits{visibility:hidden}
739
+ .knobs-editing .knobs-value{pointer-events:none}
740
+
741
+ /* Segmented choice */
742
+ .knobs-seg{position:relative;display:flex;flex-wrap:nowrap;align-items:center;justify-content:flex-end;gap:var(--k-tray-pad);height:var(--kc-control-h);padding:var(--k-tray-pad);max-width:76%;background:var(--k-seg-bg);border-radius:var(--k-radius-md)}
743
+ .knobs-seg-pill{position:absolute;top:var(--k-tray-pad);bottom:var(--k-tray-pad);left:0;right:100%;border-radius:var(--k-radius-sm);background:var(--k-pill-bg);box-shadow:var(--k-lift-shadow);pointer-events:none;
744
+ transition:left ${TRAIL_T} ${DELAY},right ${LEAD_T} ${DELAY},opacity .15s}
745
+ .knobs-seg-pill[data-dir="left"]{transition:left ${LEAD_T} ${DELAY},right ${TRAIL_T} ${DELAY},opacity .15s}
746
+ .knobs-seg-pill[data-off]{opacity:0}
747
+ /* --k-motion-blur: a gliding pill widens by its smear and fades over it at each end (see smear.ts). */
748
+ .knobs-smear-pill{margin-inline:calc(var(--k-smear) * -.5px);
749
+ -webkit-mask:linear-gradient(to right,transparent,#000 calc(var(--k-smear) * 1px),#000 calc(100% - var(--k-smear) * 1px),transparent);
750
+ mask:linear-gradient(to right,transparent,#000 calc(var(--k-smear) * 1px),#000 calc(100% - var(--k-smear) * 1px),transparent)}
751
+ .knobs-seg button{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;height:100%;padding:0 7px;font-size:var(--k-text-control);font-weight:var(--k-label-weight);white-space:nowrap;color:var(--k-label);background:transparent;cursor:pointer;border-radius:var(--k-radius-sm);transition:background .15s,color .15s}
752
+ .knobs-seg button:is(:hover,:focus-visible){color:var(--k-text)}
753
+ .knobs-seg button[aria-checked=true]{color:var(--k-text)}
754
+
755
+ /* Long choices: a compact button that drops down a menu */
756
+ .knobs-panel .knobs-select{position:relative;display:inline-flex;align-items:center;gap:6px;min-width:0;max-width:62%;height:var(--kc-control-h);padding:0 6px 0 10px;background:var(--k-seg-bg);border-radius:var(--k-radius-md);color:var(--k-label);font-size:var(--k-text-control);font-weight:var(--k-label-weight);cursor:pointer;transition:background var(--k-hover-t),color var(--k-hover-t)}
757
+ .knobs-panel .knobs-select:is(:hover,:focus-visible,[aria-expanded="true"]),.knobs-panel .knobs-active>.knobs-select{background:var(--k-surface-hi);color:var(--k-text)}
758
+ .knobs-select-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
759
+ .knobs-panel .knobs-row-full .knobs-select{flex:1;max-width:none;justify-content:space-between}
760
+ .knobs-select .knobs-icon{width:calc(var(--k-icon-sm) - 2px);height:calc(var(--k-icon-sm) - 2px);color:var(--k-dim)}
761
+ .knobs-menu[data-checks] .knobs-menu-item{padding-left:24px}
762
+ .knobs-menu-item[aria-checked="true"]::before{content:"";position:absolute;left:9px;top:50%;width:7px;height:4px;margin-top:-3.5px;border:solid currentColor;border-width:0 0 1.5px 1.5px;transform:rotate(-45deg)}
763
+
764
+ /* Action rows: a button the width of the row */
765
+ .knobs-panel .knobs-action-row{padding:0}
766
+ .knobs-panel .knobs-action{width:100%;height:100%;padding:0 var(--k-inset);text-align:left;background:transparent;border-radius:0;color:var(--k-button-color,var(--k-text));font-size:var(--k-button-font-size,calc(var(--k-text-control) + .5px));font-weight:var(--k-label-weight);cursor:pointer;transition:color var(--k-hover-t),background var(--k-hover-t),box-shadow var(--k-hover-t)}
767
+ .knobs-panel .knobs-action:is(:hover,:focus-visible){color:var(--k-accent)}
768
+ .knobs-panel .knobs-action:active{opacity:.7}
769
+ /* With a button fill or outline (--k-button-bg, --k-button-line), an action is a sized button in
770
+ its row, and the presets strip a row of them, as toolbar buttons are. */
771
+ .knobs-panel[data-buttons] .knobs-action-row{padding:0 var(--k-inset)}
772
+ .knobs-panel[data-buttons] .knobs-action{width:auto;max-width:100%;height:var(--k-button-h,var(--kc-control-h));padding:0 10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
773
+ background:var(--k-button-bg,transparent);box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);border-radius:var(--k-button-radius,var(--k-radius-md))}
774
+ .knobs-panel[data-buttons] .knobs-action:is(:hover,:focus-visible){color:var(--k-text);background:var(--k-button-hover-bg,var(--k-surface-hi));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent))}
775
+
776
+ /* Switch */
777
+ /* The thumb spans two edges: the leading one springs ahead and the other follows, so it stretches
778
+ into a capsule as it travels; a press widens it toward where it will go. */
779
+ .knobs-panel .knobs-toggle{position:relative;flex:none;width:32px;height:18px;padding:0;background:var(--k-toggle-track);border-radius:var(--k-round);cursor:pointer;transition:background .2s ${DELAY},box-shadow .2s ${DELAY}}
780
+ .knobs-panel .knobs-toggle[aria-checked=true]{background:var(--k-accent);box-shadow:0 0 calc(var(--k-glow) * 10px) color-mix(in srgb,var(--k-accent) 42%,transparent)}
781
+ .knobs-toggle i{position:absolute;top:var(--k-tray-pad);bottom:var(--k-tray-pad);left:var(--k-tray-pad);right:16px;border-radius:var(--k-round);background:var(--k-thumb);box-shadow:0 1px 2px rgba(0,0,0,calc(.25 * var(--k-lift)));transition:left ${LEAD_T} ${DELAY},right ${TRAIL_T} ${DELAY},background .2s ${DELAY}}
782
+ .knobs-toggle[aria-checked=true] i{left:16px;right:var(--k-tray-pad);background:var(--k-toggle-thumb);transition:left ${TRAIL_T} ${DELAY},right ${LEAD_T} ${DELAY},background .2s ${DELAY}}
783
+ .knobs-toggle:active i{right:12px;transition:right ${LEAD_T},background .2s}
784
+ .knobs-toggle[aria-checked=true]:active i{left:12px;right:var(--k-tray-pad);transition:left ${LEAD_T},background .2s}
785
+
786
+ /* Compound rows: a spring's two sliders beside its curve; disclosure rows with an editor body */
787
+ .knobs-card>:is(.knobs-spring,.knobs-x):hover{background:transparent}
788
+ .knobs-card>:is(.knobs-spring,.knobs-x):has(:focus-visible)::after{opacity:0}
789
+ /* Selected rows: one accent-tinted wash, joined across neighbours. */
790
+ .knobs-panel .knobs-card>.knobs-selected{background:color-mix(in srgb,var(--k-accent) 10%,transparent)}
791
+ .knobs-card>.knobs-selected+.knobs-selected::before{opacity:0}
792
+ .knobs-spring{display:flex}
793
+ .knobs-spring-tracks{position:relative;flex:1;min-width:0;overflow:hidden}
794
+ .knobs-sub{position:relative;transition:background var(--k-hover-t)}
795
+ .knobs-sub:hover,.knobs-sub.knobs-active,.knobs-x-head:hover,.knobs-x-head[data-panned]{background:var(--k-row-hover)}
796
+ .knobs-sub+.knobs-sub::before{content:"";position:absolute;z-index:1;left:0;right:0;top:0;height:1px;transform:scaleY(.5);transform-origin:top;background:var(--k-line);pointer-events:none;transition:opacity .15s}
797
+ .knobs-sub:is(:hover,:has(:focus-visible),.knobs-active)::before,.knobs-sub:is(:hover,:has(:focus-visible),.knobs-active)+.knobs-sub::before{opacity:0}
798
+ :is(.knobs-sub,.knobs-x-head)::after{content:"";position:absolute;z-index:2;inset:0;background:var(--k-surface);opacity:0;pointer-events:none;transition:opacity .15s}
799
+ :is(.knobs-sub:has(:focus-visible),.knobs-x-head:focus-visible)::after{opacity:1}
800
+ .knobs-spring-curve{position:relative;flex:none;width:calc(var(--k-row) * 2.5);margin:var(--k-gap) var(--k-inset) var(--k-gap) 0;border-radius:var(--k-radius-sm);background:var(--k-seg-bg);pointer-events:none}
801
+ .knobs-panel :is(.knobs-spring-curve,.knobs-ease)>svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
802
+ .knobs-guide{fill:none;stroke:var(--k-line);stroke-width:1}
803
+ .knobs-arm{fill:none;stroke:var(--k-dim);stroke-width:1;transition:d ${FILL_T} ${DELAY}}
804
+ .knobs-curve{fill:none;stroke:var(--k-accent);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;transition:d ${FILL_T} ${DELAY}}
805
+ .knobs-spring-dot{position:absolute;left:0;top:0;width:5px;height:5px;margin:-2.5px;border-radius:50%;background:var(--k-accent);box-shadow:0 0 calc(var(--k-glow) * 8px) var(--k-accent);opacity:0;scale:var(--k-curve-dot)}
806
+ .knobs-guide-dashed{stroke:var(--k-line-hi)}
807
+ .knobs-spring:has(.knobs-active) .knobs-curve{transition:none}
808
+
809
+ .knobs-panel :is(input,textarea,[contenteditable]){-webkit-user-select:text;user-select:text}
810
+ .knobs-x-head{position:relative;display:flex;align-items:center;justify-content:space-between;gap:8px;height:var(--k-row);padding:0 var(--k-inset);cursor:pointer;user-select:none;transition:background var(--k-hover-t)}
811
+ .knobs-panel .knobs-x-head:focus-visible{outline:none;box-shadow:none}
812
+ .knobs-x-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--k-label);font-weight:var(--k-label-weight)}
813
+ .knobs-x-label::after{content:"";display:inline-block;width:4px;height:4px;margin-left:5px;border-radius:50%;background:var(--k-modified);vertical-align:middle;opacity:0;transform:scale(.4);transition:opacity .16s ease-out,transform .28s cubic-bezier(.34,1.5,.64,1)}
814
+ .knobs-modified .knobs-x-label::after{opacity:.95;transform:none}
815
+ .knobs-x-sum{display:flex;align-items:center;gap:8px;min-width:0}
816
+ .knobs-x-read,.knobs-strip-read{color:var(--k-label);font-size:var(--kc-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap}
817
+ .knobs-caret{width:10px;height:10px;flex:none;margin-right:-2.5px;color:var(--k-dim);transition:transform ${LEAD_T},color .15s}
818
+ .knobs-caret path{fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
819
+ .knobs-x-head:hover .knobs-caret{color:var(--k-label)}
820
+ .knobs-x-head[aria-expanded="true"] .knobs-caret{transform:rotate(90deg)}
821
+ .knobs-swatch{flex:none;width:var(--k-track-h);height:var(--k-track-h);border-radius:var(--k-radius-sm);box-shadow:inset 0 0 0 1px var(--k-line);transition:background-color .2s ${DELAY}}
822
+ .knobs-x-body{padding:0 var(--k-inset) var(--k-inset)}
823
+ .knobs-strips{display:grid}
824
+ .knobs-strip{display:grid;grid-template-columns:10px 1fr 36px;align-items:center;gap:8px;height:var(--k-action-h)}
825
+ .knobs-strip-label{color:var(--k-dim);font-size:var(--k-text-cap);font-weight:var(--k-title-weight);text-align:left}
826
+ .knobs-strip-read{text-align:right}
827
+ .knobs-strip-track{position:relative;height:var(--k-track-h);border-radius:var(--k-round);box-shadow:inset 0 0 0 1px var(--k-line);cursor:ew-resize;touch-action:none}
828
+ .knobs-strip-thumb{position:absolute;top:50%;left:0;width:calc(var(--k-row) - 12px);height:calc(var(--k-row) - 12px);margin:calc(6px - var(--k-row) / 2);border-radius:var(--k-round);box-shadow:0 0 0 2px var(--k-thumb),0 1px 4px rgba(0,0,0,calc(.4 * var(--k-lift)));pointer-events:none;transition:left ${FILL_T} ${DELAY},background-color .2s ${DELAY},scale .2s var(--k-ease)}
829
+ .knobs-strip.knobs-active .knobs-strip-thumb{transition:background-color .2s,scale .2s var(--k-ease)}
830
+ .knobs-strip:is(.knobs-active,:has(:focus-visible)) .knobs-strip-thumb{scale:1.1}
831
+ .knobs-pad,.knobs-ease{position:relative;border-radius:var(--k-radius-md);background:var(--k-seg-bg);touch-action:none}
832
+ .knobs-pad{height:calc(var(--k-row) * 4);cursor:crosshair;overflow:hidden}
833
+ .knobs-pad>i{position:absolute;left:0;top:0;pointer-events:none;transition:translate ${FILL_T} ${DELAY},scale .2s var(--k-ease)}
834
+ .knobs-pad-v{bottom:0;width:1px;margin-left:-.5px;background:var(--k-line)}
835
+ .knobs-pad-h{right:0;height:1px;margin-top:-.5px;background:var(--k-line)}
836
+ .knobs-pad .knobs-pad-home{width:7px;height:7px;margin:-3.5px;border-radius:50%;box-shadow:inset 0 0 0 1px var(--k-dim);transition:none}
837
+ .knobs-pad-puck{width:12px;height:12px;margin:-6px;border-radius:var(--k-round);background:var(--k-accent);box-shadow:0 0 0 1.5px var(--k-bg),0 0 calc(var(--k-glow) * 10px) color-mix(in srgb,var(--k-accent) 50%,transparent)}
838
+ .knobs-pad.knobs-active>i{transition:scale .2s var(--k-ease)}
839
+ .knobs-pad:is(.knobs-active,:focus-visible) .knobs-pad-puck{scale:1.2}
840
+ .knobs-ease{height:calc(var(--k-row) * 4.5)}
841
+ .knobs-panel .knobs-ease-handle{position:absolute;left:0;top:0;width:12px;height:12px;margin:-6px;padding:0;border-radius:var(--k-round);background:var(--k-bg);box-shadow:inset 0 0 0 2px var(--k-accent),0 1px 3px rgba(0,0,0,calc(.3 * var(--k-lift)));cursor:grab;touch-action:none;transition:translate ${FILL_T} ${DELAY},scale .2s var(--k-ease)}
842
+ .knobs-ease-handle::before{content:"";position:absolute;inset:-8px;border-radius:50%}
843
+ .knobs-ease.knobs-active :is(.knobs-curve,.knobs-arm){transition:none}
844
+ .knobs-ease.knobs-active .knobs-ease-handle{transition:scale .2s var(--k-ease)}
845
+ .knobs-ease-handle:active{scale:1.2;cursor:grabbing}
846
+ .knobs-ease-handle:focus-visible{scale:1.2}
847
+ .knobs-ease-mini{flex:none;width:30px;height:var(--k-track-h);overflow:visible}
848
+ .knobs-ease-chips{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--k-tray-pad);margin-top:6px;padding:var(--k-tray-pad);border-radius:var(--k-radius-md);background:var(--k-seg-bg)}
849
+ .knobs-panel .knobs-ease-chip{min-width:0;height:calc(var(--k-row) - 10px);padding:0 6px;font-size:var(--k-text-control);font-weight:var(--k-label-weight);color:var(--k-label);background:transparent;border-radius:var(--k-radius-sm);cursor:pointer;white-space:nowrap;transition:background .15s,color .15s,box-shadow .15s}
850
+ .knobs-panel .knobs-ease-chip:is(:hover,:focus-visible){color:var(--k-text)}
851
+ .knobs-panel .knobs-ease-chip[aria-checked="true"]{color:var(--k-text);background:var(--k-pill-bg);box-shadow:var(--k-lift-shadow)}
852
+
853
+ /* Gradients: a swatch strip with stop ticks in the head; a wide strip with a handle per stop (the
854
+ selected one full size), then that stop's colour strips. The ramp runs a handle's radius in from
855
+ each end, as the colour strips' do. */
856
+ .knobs-grad-mini{position:relative;flex:none;width:calc(var(--k-row) * 2.5);height:var(--k-track-h);border-radius:var(--k-radius-sm);box-shadow:inset 0 0 0 1px var(--k-line);background:${GRAD_MINI};transition:${GRAD_T}}
857
+ .knobs-grad-mini>i{position:absolute;top:calc(100% + 2px);left:0;width:1px;height:3px;margin-left:-.5px;background:var(--k-dim);transition:left ${FILL_T} ${DELAY},opacity .15s}
858
+ .knobs-grad{--kg-h:calc(var(--k-row) - 6px);--kg-r:calc(var(--kg-h) / 2);--kg-pin:round(calc(var(--kg-h) * .42),1px);position:relative;height:var(--kg-h);margin:2px 0 var(--k-gap);border-radius:var(--k-round);box-shadow:inset 0 0 0 1px var(--k-line);background:${GRAD_STRIP};cursor:pointer;touch-action:none;user-select:none;outline:none;transition:${GRAD_T}}
859
+ .knobs-grad-stop{position:absolute;top:50%;left:0;width:var(--kg-pin);height:calc(var(--kg-h) - 4px);margin:calc(2px - var(--kg-h) / 2) 0 0 calc(var(--kg-pin) / -2);border-radius:var(--k-round);box-shadow:0 0 0 2px var(--k-thumb),0 1px 4px rgba(0,0,0,calc(.4 * var(--k-lift)));pointer-events:none;scale:.78;
860
+ transition:left ${FILL_T} ${DELAY},background-color .2s ${DELAY},scale .2s var(--k-ease),opacity .15s}
861
+ .knobs-grad-stop[data-selected]{scale:1}
862
+ .knobs-grad:is(:focus-visible,.knobs-active) .knobs-grad-stop[data-selected]{scale:1.12}
863
+ .knobs-grad-stop[data-leaving]{opacity:.35;scale:.6}
864
+ .knobs-x[data-k-active] :is(.knobs-grad,.knobs-grad-mini,.knobs-grad-mini>i){transition:none}
865
+ .knobs-x[data-k-active] .knobs-grad-stop{transition:scale .2s var(--k-ease),opacity .15s}
866
+ :is(.knobs-grad-stop,.knobs-graph-pt)[data-born]{animation:knobs-born .24s var(--k-ease)}
867
+ @keyframes knobs-born{from{opacity:0;scale:.4}}
868
+ .knobs-mixed :is(.knobs-grad,.knobs-grad-mini){background:transparent}
869
+ /* A ramp's shapes and presets share one row: each chip gives up padding before its words, and only
870
+ a very narrow column ellipsizes them (the GPU overlay does the same). */
871
+ .knobs-panel .knobs-ramp-chips{display:flex;flex-wrap:nowrap}
872
+ .knobs-panel .knobs-ramp-chips>.knobs-ease-chip{flex:1 1 auto;min-width:0;padding:0 clamp(2px,1.2cqi,6px);overflow:hidden;text-overflow:ellipsis}
873
+ .knobs-panel .knobs-ramp-chips{container-type:inline-size}
874
+ .knobs-mixed :is(.knobs-grad-stop,.knobs-grad-mini>i){opacity:0}
875
+
876
+ /* Curves: a mini curve in the head; a graph with a grid, points (the selected one filled) and a
877
+ hover crosshair whose readout sits in the corner. */
878
+ .knobs-curve-mini{flex:none;width:36px;height:var(--k-track-h);overflow:visible}
879
+ .knobs-graph{position:relative;height:calc(var(--k-row) * 4.5);border-radius:var(--k-radius-md);background:var(--k-seg-bg);cursor:crosshair;touch-action:none;user-select:none;outline:none;overflow:hidden}
880
+ .knobs-panel .knobs-graph>svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
881
+ .knobs-graph>i{position:absolute;left:0;top:0;pointer-events:none}
882
+ .knobs-graph-pt{width:10px;height:10px;margin:-5px;border-radius:var(--k-round);background:var(--k-bg);box-shadow:inset 0 0 0 2px var(--k-accent),0 1px 3px rgba(0,0,0,calc(.3 * var(--k-lift)));
883
+ transition:translate ${FILL_T} ${DELAY},background-color .15s,scale .2s var(--k-ease),opacity .15s}
884
+ .knobs-graph-pt[data-selected]{background:var(--k-accent)}
885
+ .knobs-graph:is(:focus-visible,.knobs-active) .knobs-graph-pt[data-selected]{scale:1.2}
886
+ .knobs-graph-pt[data-leaving]{opacity:.35;scale:.7}
887
+ .knobs-graph.knobs-active .knobs-graph-pt{transition:background-color .15s,scale .2s var(--k-ease),opacity .15s}
888
+ .knobs-graph.knobs-active .knobs-curve,.knobs-x[data-k-active] .knobs-curve-mini .knobs-curve{transition:none}
889
+ .knobs-graph :is(.knobs-graph-v,.knobs-graph-h,.knobs-graph-dot,.knobs-graph-read){opacity:0;transition:opacity .15s}
890
+ .knobs-graph[data-hover] :is(.knobs-graph-v,.knobs-graph-h,.knobs-graph-dot,.knobs-graph-read){opacity:1}
891
+ .knobs-graph-v{bottom:0;width:1px;margin-left:-.5px;background:var(--k-line-hi)}
892
+ .knobs-graph-h{right:0;height:1px;margin-top:-.5px;background:var(--k-line-hi)}
893
+ .knobs-graph-dot{width:5px;height:5px;margin:-2.5px;border-radius:50%;background:var(--k-accent)}
894
+ .knobs-graph-read{position:absolute;top:4px;right:4px;padding:1px 5px;border-radius:var(--k-radius-sm);background:var(--k-bg);color:var(--k-label);font-family:var(--k-value-font);font-size:var(--kc-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap;pointer-events:none}
895
+ .knobs-mixed :is(.knobs-curve-mini,.knobs-graph .knobs-curve,.knobs-graph-pt){opacity:0}
896
+
897
+ /* Rows as separate bars (--k-row-gap above 0): each row carries its own surface, no hairlines.
898
+ A spring stacks its curve over its two sliders. */
899
+ .knobs-panel[data-rows] .knobs-card{display:flex;flex-direction:column;gap:var(--k-row-gap);background:transparent;overflow:visible}
900
+ .knobs-panel[data-rows] .knobs-card>*{background:var(--k-surface);border-radius:var(--k-radius);overflow:hidden}
901
+ .knobs-panel[data-rows] .knobs-card>:is(:hover,.knobs-active){background:color-mix(in srgb,var(--k-surface-hi) 50%,var(--k-surface))}
902
+ .knobs-panel[data-rows] :is(.knobs-card>*,.knobs-sub)::before{display:none}
903
+ .knobs-panel[data-rows] .knobs-card>.knobs-subhead{background:transparent}
904
+ .knobs-panel[data-rows] .knobs-card>.knobs-spring{flex-direction:column-reverse;gap:var(--k-row-gap);background:transparent;overflow:visible}
905
+ .knobs-panel[data-rows] .knobs-spring-tracks{display:flex;flex-direction:column;gap:var(--k-row-gap);overflow:visible}
906
+ .knobs-panel[data-rows] .knobs-sub{background:var(--k-surface);border-radius:var(--k-radius);overflow:hidden}
907
+ .knobs-panel[data-rows] .knobs-sub:is(:hover,.knobs-active){background:color-mix(in srgb,var(--k-surface-hi) 50%,var(--k-surface))}
908
+ .knobs-panel[data-rows] .knobs-spring-curve{width:auto;height:calc(var(--k-row) * 2.8);margin:0;border-radius:var(--k-radius);background:var(--k-surface)}
909
+ /* --k-frame: flat. Groups are plain sections: no card surfaces, rows split by hairlines and a
910
+ hairline over every group's label but the first. An inline panel sheds its own card and
911
+ padding too, for a host's column or card, so nothing draws a card inside a card. */
912
+ :where(.knobs-panel)[data-frame="flat"]{--k-group-divider:var(--k-line);--k-group-divider-gap:var(--k-gap)}
913
+ :where(.knobs-panel.knobs-inline:not(.knobs-page))[data-frame="flat"]{--k-chrome:0;--k-pad:0px}
914
+ .knobs-panel[data-frame="flat"] .knobs-card{background:transparent;border-radius:0}
915
+ .knobs-panel[data-frame="flat"][data-rows] .knobs-card>*,.knobs-panel[data-frame="flat"][data-rows] .knobs-sub{background:transparent;border-radius:0}
916
+
917
+ /* Disabled rows dim and take no edits (focus still reaches them, to read); read-only rows keep
918
+ full strength. Neither shows a hover wash or an edit cursor. */
919
+ .knobs-panel :is(.knobs-card>[data-disabled],.knobs-sub[data-disabled]){opacity:var(--k-disabled-opacity)}
920
+ .knobs-panel .knobs-card>:is([data-disabled],[data-readonly]):hover{background:transparent}
921
+ .knobs-panel :is([data-disabled],[data-readonly]) :is(.knobs-track,.knobs-value,.knobs-seg,.knobs-seg button,.knobs-select,.knobs-toggle,.knobs-action,.knobs-strip-track,.knobs-pad,.knobs-ease-handle,.knobs-ease-chip,.knobs-grad,.knobs-graph){cursor:default}
922
+ .knobs-slider:is([data-disabled],[data-readonly]):hover .knobs-fill{--k-fill-mix:var(--k-fill-rest-mix)}
923
+ .knobs-slider:is([data-disabled],[data-readonly]):hover:not(:has(:focus-visible)) :is(.knobs-handle,.knobs-marks>i){opacity:var(--k-handle-rest);background-color:transparent}
924
+ .knobs-slider:is([data-disabled],[data-readonly]):hover:not(:has(:focus-visible)) .knobs-handle::before{transform:scaleX(calc(.25 + .75 * min(1, var(--k-handle-rest) * 4)))}
925
+ .knobs-panel :is([data-disabled],[data-readonly]) .knobs-value:hover{border-bottom-color:transparent}
926
+ .knobs-panel :is([data-disabled],[data-readonly]) .knobs-seg button:not([aria-checked=true]):hover{color:var(--k-label)}
927
+ .knobs-panel :is([data-disabled],[data-readonly]) .knobs-action:hover:not(:focus-visible){color:var(--k-text)}
928
+ .knobs-panel :is([data-disabled],[data-readonly]) .knobs-select:hover:not(:focus-visible){background:var(--k-seg-bg);color:var(--k-label)}
929
+ /* A mixed value (a multi-selection whose items differ) reads "—" until it's edited. */
930
+ .knobs-mixed :is(.knobs-fill,.knobs-handle-zone,.knobs-marks){opacity:0}
931
+ .knobs-panel .knobs-mixed .knobs-value>:is(.knobs-digits,.knobs-unit,.knobs-lock){display:none}
932
+ .knobs-mixed .knobs-value::after{content:"—"}
933
+ .knobs-mixed :is(.knobs-range-fill,.knobs-range-smear,.knobs-range-thumb,.knobs-dial-hand,.knobs-strip-thumb,.knobs-pad-puck,.knobs-pad-v,.knobs-pad-h,.knobs-ease-mini,.knobs-ease .knobs-curve,.knobs-arm,.knobs-ease-handle){opacity:0}
934
+ .knobs-panel .knobs-toggle[aria-checked="mixed"] i{left:calc(50% - 7px);right:calc(50% - 7px)}
935
+
936
+ /* Tabs: text over a hairline; the chosen one's underline slides to it, its leading edge first. */
937
+ .knobs-tabs{position:relative;display:flex;align-items:stretch;gap:calc(var(--k-unit) * 4);margin:0 0 var(--k-section-gap);padding:0 var(--k-inset);overflow:hidden;transition:opacity .2s var(--k-ease)}
938
+ .knobs-tabs::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;transform:scaleY(.5);transform-origin:bottom;background:var(--k-line);pointer-events:none}
939
+ .knobs-panel .knobs-tab{flex:none;height:calc(var(--k-row) - var(--k-unit));padding:0;background:transparent;border-radius:0;font-size:var(--k-text-control);font-weight:var(--k-label-weight);color:var(--k-label);white-space:nowrap;cursor:pointer;transition:color .15s}
940
+ .knobs-panel .knobs-tab:is(:hover,:focus-visible),.knobs-panel .knobs-tab[aria-selected="true"]{color:var(--k-text)}
941
+ .knobs-tabs-bar{position:absolute;bottom:0;left:0;right:100%;height:1.5px;border-radius:1px;background:var(--k-accent);pointer-events:none;transition:left ${TRAIL_T},right ${LEAD_T}}
942
+ .knobs-tabs-bar[data-dir="left"]{transition:left ${LEAD_T},right ${TRAIL_T}}
943
+ /* A search spans every tab, so the strip steps back while it's on. */
944
+ .knobs-panel[data-searching] .knobs-tabs{opacity:.4}
945
+
946
+ /* Search: a field and its filter chips. Matches show in labels by colour alone. */
947
+ .knobs-search{display:flex;align-items:center;gap:var(--k-tray-pad);margin:0 0 var(--k-section-gap)}
948
+ .knobs-search-field{flex:1;min-width:0;display:flex;align-items:center;gap:6px;height:var(--kc-control-h);padding:0 8px;background:var(--k-seg-bg);border-radius:var(--k-radius-md);color:var(--k-dim);cursor:text}
949
+ .knobs-search-field>.knobs-icon{width:calc(var(--k-icon-sm) - 2px);height:calc(var(--k-icon-sm) - 2px)}
950
+ .knobs-panel .knobs-search input{flex:1;min-width:0;height:100%;padding:0;background:transparent;border-radius:0;color:var(--k-text);font-size:var(--k-text-control);-webkit-appearance:none;appearance:none}
951
+ .knobs-panel .knobs-search input::placeholder{color:var(--k-dim)}
952
+ .knobs-panel .knobs-search input::-webkit-search-cancel-button{display:none}
953
+ .knobs-panel .knobs-search-chip{flex:none;display:inline-flex;align-items:center;gap:5px;height:var(--kc-control-h);padding:0 8px;background:transparent;border-radius:var(--k-radius-md);box-shadow:inset 0 0 0 1px var(--k-line);color:var(--k-label);font-size:var(--k-text-meta);font-weight:var(--k-label-weight);white-space:nowrap;cursor:pointer;transition:background .15s,color .15s,box-shadow .15s,opacity .15s}
954
+ .knobs-panel .knobs-search-chip:is(:hover,:focus-visible){color:var(--k-text);box-shadow:inset 0 0 0 1px var(--k-line-hi)}
955
+ .knobs-panel .knobs-search-chip[aria-pressed="true"]{background:var(--k-pill-bg);box-shadow:inset 0 0 0 1px var(--k-pill-border);color:var(--k-text)}
956
+ .knobs-panel .knobs-search-chip[data-none]{opacity:.5}
957
+ .knobs-search-count{color:var(--k-dim);font-variant-numeric:tabular-nums}
958
+ .knobs-search-chip[aria-pressed="true"] .knobs-search-count{color:var(--k-label)}
959
+ .knobs-panel mark.knobs-match{background:none;color:var(--k-accent)}
960
+ .knobs-panel[data-gpu-active="true"] .knobs-search{position:relative;z-index:2147480003}
961
+
962
+ /* Sub-headings: a flat heading inside the group's card, split off by the card's hairline. */
963
+ .knobs-panel .knobs-card>.knobs-subhead{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:0;height:calc(var(--k-row) - var(--k-unit) * 2);padding:0 var(--k-inset);color:var(--k-label);font-size:var(--k-text-meta);font-weight:var(--k-title-weight);cursor:pointer;user-select:none}
964
+ .knobs-subhead-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
965
+ .knobs-subhead[aria-expanded="true"] .knobs-caret{transform:rotate(90deg)}
966
+ .knobs-subhead:hover .knobs-caret{color:var(--k-label)}
967
+ .knobs-card>.knobs-subhead:focus-visible::after{opacity:1}
968
+
969
+ /* Inspector rows: number cells, ranges, dials, seeds and key combinations. */
970
+ .knobs-panel .knobs-insp{gap:8px}
971
+ .knobs-panel .knobs-insp[data-kind="vec"]>span:first-child{flex-shrink:0;max-width:34%}
972
+ .knobs-cells{flex:0 1 auto;display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:var(--k-tray-pad);width:calc(var(--k-row) * 5);max-width:64%}
973
+ .knobs-cells[data-wide]{width:calc(var(--k-row) * 7.5);max-width:72%}
974
+ .knobs-cell{position:relative;display:flex;align-items:center;justify-content:space-between;gap:3px;min-width:0;height:var(--kc-control-h);padding:0 5px;border-radius:var(--k-radius-md);background:var(--k-seg-bg);cursor:ew-resize;user-select:none;touch-action:none;outline:none;transition:background var(--k-hover-t)}
975
+ .knobs-cell:hover,.knobs-cell:focus-visible{background:color-mix(in srgb,var(--k-surface-hi) 70%,var(--k-seg-bg))}
976
+ .knobs-active .knobs-cell:focus,.knobs-cell[data-panned]{background:var(--k-surface-hi)}
977
+ .knobs-cell-axis{flex:none;font-style:normal;font-size:var(--k-text-cap);font-weight:var(--k-title-weight);color:var(--k-dim)}
978
+ .knobs-cell-read,.knobs-range-read,.knobs-angle-read,.knobs-seed-read{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--k-label);font-family:var(--k-value-font);font-size:var(--kc-value-size);font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
979
+ .knobs-cell:focus-visible .knobs-cell-read,.knobs-active .knobs-cell:focus .knobs-cell-read,.knobs-cell[data-panned] .knobs-cell-read{color:var(--k-text)}
980
+ .knobs-panel .knobs-link{flex:none;width:20px;height:20px;margin:0 -4px 0 auto;padding:0;display:inline-flex;align-items:center;justify-content:center;background:transparent;border-radius:var(--k-round);color:var(--k-dim);cursor:pointer;transition:background .15s,color .15s}
981
+ .knobs-panel .knobs-link:hover{background:var(--k-surface-hi);color:var(--k-text)}
982
+ .knobs-panel .knobs-link[aria-pressed="true"]{color:var(--k-text)}
983
+ .knobs-link .knobs-icon{width:var(--k-icon-sm);height:var(--k-icon-sm)}
984
+ /* The inline editor over a readout: above the GPU canvas, which leaves that readout to it. */
985
+ .knobs-panel .knobs-cell-edit{position:absolute;z-index:3;right:var(--k-inset);top:50%;transform:translateY(-50%);width:7ch;height:auto;padding:1px 4px;text-align:right;background:var(--k-bg);border-radius:var(--k-radius-sm);border-bottom:1px solid var(--k-text);color:var(--k-text);font-family:var(--k-value-font);font-variant-numeric:tabular-nums;font-size:var(--kc-value-size)}
986
+ .knobs-cell.knobs-editing>:not(.knobs-cell-edit){visibility:hidden}
987
+ .knobs-panel .knobs-cell>.knobs-cell-edit{inset:0;width:auto;transform:none;padding:0 6px;border-radius:var(--k-radius-md)}
988
+ .knobs-panel[data-gpu-active="true"] .knobs-cell-edit{z-index:2147480003}
989
+
990
+ .knobs-panel .knobs-row.knobs-range{display:block;height:var(--k-row);padding:0}
991
+ .knobs-range-track{position:absolute;inset:0;overflow:hidden;cursor:ew-resize;user-select:none;touch-action:none;transition:--kr-lo ${FILL_T} ${DELAY},--kr-hi ${FILL_T} ${DELAY};--kr-tint:var(--k-fill-rest)}
992
+ .knobs-range-fill{position:absolute;inset:0;transform-origin:0 0;transform:scaleX(0);background:var(--kr-tint);pointer-events:none;transition:transform ${FILL_T} ${DELAY},background .15s}
993
+ .knobs-range:hover .knobs-range-track{--kr-tint:color-mix(in srgb,var(--k-accent) var(--k-fill-hover-mix),var(--k-fill-base))}
994
+ .knobs-range.knobs-active .knobs-range-track{--kr-tint:var(--k-fill-active)}
995
+ /* --k-range-blur: while the ends glide, the band is a gradient in the track's space whose ends ramp
996
+ over their smears (--kr-smear-lo/hi, px; see inspector.ts), standing in for the scaled fill. */
997
+ .knobs-range-smear{position:absolute;inset:0;display:none;pointer-events:none;--ks-a:calc(var(--kr-lo) * 100%);--ks-b:calc(var(--kr-hi) * 100%);
998
+ background:linear-gradient(to right,transparent calc(var(--ks-a) - var(--kr-smear-lo,0) * .5px),var(--kr-tint) calc(var(--ks-a) + var(--kr-smear-lo,0) * .5px),var(--kr-tint) calc(var(--ks-b) - var(--kr-smear-hi,0) * .5px),transparent calc(var(--ks-b) + var(--kr-smear-hi,0) * .5px))}
999
+ .knobs-range-smearing .knobs-range-smear{display:block}
1000
+ .knobs-range-smearing .knobs-range-fill{opacity:0}
1001
+ .knobs-range-thumb{position:absolute;top:0;bottom:0;left:calc(var(--kr-lo) * 100%);width:0;outline:none}
1002
+ .knobs-range-thumb[data-end="hi"]{left:calc(var(--kr-hi) * 100%)}
1003
+ /* Where a thumb shows, the label and readout fade around it (2.5px either side of its hairline). */
1004
+ .knobs-range-text{position:absolute;inset:0;pointer-events:none;transition:--kr-show-lo .15s,--kr-show-hi .15s;
1005
+ --kg-lo:calc(var(--kr-lo) * 100% + 1.5px);--kg-hi:calc(var(--kr-hi) * 100% - 1.5px);--kg-in-lo:rgb(0 0 0/calc(1 - var(--kr-show-lo)));--kg-in-hi:rgb(0 0 0/calc(1 - var(--kr-show-hi)));
1006
+ --kg-mask:linear-gradient(to right,#000 calc(var(--kg-lo) - 6.5px),var(--kg-in-lo) calc(var(--kg-lo) - 2.5px),var(--kg-in-lo) calc(var(--kg-lo) + 2.5px),#000 calc(var(--kg-lo) + 6.5px)),linear-gradient(to right,#000 calc(var(--kg-hi) - 6.5px),var(--kg-in-hi) calc(var(--kg-hi) - 2.5px),var(--kg-in-hi) calc(var(--kg-hi) + 2.5px),#000 calc(var(--kg-hi) + 6.5px));
1007
+ -webkit-mask:var(--kg-mask);mask:var(--kg-mask);-webkit-mask-composite:source-in;mask-composite:intersect}
1008
+ .knobs-range:not(.knobs-mixed):hover .knobs-range-text{--kr-show-lo:1;--kr-show-hi:1}
1009
+ .knobs-range:not(.knobs-mixed)[data-end-focus="lo"]:is([data-k-fv],.knobs-active) .knobs-range-text{--kr-show-lo:1}
1010
+ .knobs-range:not(.knobs-mixed)[data-end-focus="hi"]:is([data-k-fv],.knobs-active) .knobs-range-text{--kr-show-hi:1}
1011
+ .knobs-range-thumb::before{content:"";position:absolute;left:0;top:50%;width:3px;height:calc(var(--k-row) - 12px);margin-top:calc(6px - var(--k-row) / 2);translate:-50% 0;border-radius:var(--k-round);background:var(--k-handle);opacity:0;scale:.25 1;transition:opacity .15s,scale .22s var(--k-ease)}
1012
+ .knobs-range-thumb[data-end="lo"]::before{translate:0 0}
1013
+ .knobs-range-thumb[data-end="hi"]::before{translate:-100% 0}
1014
+ .knobs-range:hover .knobs-range-thumb::before{opacity:.5}
1015
+ .knobs-range-thumb:focus-visible::before,.knobs-range.knobs-active .knobs-range-thumb:focus::before{opacity:.95;scale:1}
1016
+ .knobs-range .knobs-label{max-width:calc(55% - var(--k-inset))}
1017
+ .knobs-range-read{position:absolute;right:var(--k-inset);top:50%;transform:translateY(-50%);pointer-events:none}
1018
+ .knobs-range.knobs-active .knobs-range-read,.knobs-range:has(:focus-visible) .knobs-range-read{color:var(--k-text)}
1019
+ .knobs-range.knobs-modified .knobs-range-read{color:color-mix(in srgb,var(--k-modified) calc(var(--k-readout-mark) * 100%),var(--k-label))}
1020
+ .knobs-range.knobs-editing .knobs-range-read{opacity:0}
1021
+
1022
+ .knobs-angle{display:inline-flex;align-items:center;gap:8px;height:var(--kc-control-h);margin-left:auto;cursor:ew-resize;user-select:none;touch-action:none;outline:none}
1023
+ .knobs-angle:focus-visible .knobs-angle-read,.knobs-active .knobs-angle-read{color:var(--k-text)}
1024
+ .knobs-dial{position:relative;flex:none;width:var(--kc-control-h);height:var(--kc-control-h);border-radius:50%;background:var(--k-seg-bg);box-shadow:inset 0 0 0 1px var(--k-line);cursor:grab;transition:box-shadow .15s}
1025
+ .knobs-angle:is(:hover,:focus-visible) .knobs-dial,.knobs-active .knobs-dial{box-shadow:inset 0 0 0 1px var(--k-line-hi)}
1026
+ .knobs-active .knobs-dial{cursor:grabbing}
1027
+ .knobs-dial::after{content:"";position:absolute;left:50%;top:50%;width:3px;height:3px;margin:-1.5px;border-radius:50%;background:var(--k-accent)}
1028
+ .knobs-dial-hand{position:absolute;left:50%;top:18%;bottom:50%;width:1.5px;margin-left:-.75px;border-radius:1px;background:var(--k-accent);transform-origin:50% 100%;transition:rotate ${FILL_T} ${DELAY}}
1029
+ .knobs-active .knobs-dial-hand{transition:none}
1030
+ .knobs-insp.knobs-editing .knobs-angle-read,.knobs-insp.knobs-editing .knobs-seed-read{opacity:0}
1031
+
1032
+ .knobs-panel .knobs-insp[data-kind="seed"]{gap:2px}
1033
+ .knobs-seed{display:inline-flex;align-items:center;height:var(--kc-control-h);margin-left:auto;padding:0 4px;border-radius:var(--k-radius-sm);cursor:text;outline:none}
1034
+ .knobs-seed:focus-visible .knobs-seed-read,.knobs-active>.knobs-seed .knobs-seed-read{color:var(--k-text)}
1035
+ .knobs-seed-digits{display:inline-flex;align-items:center;line-height:2.1;margin-block:-.375em;--rn-edge-fade:.5em}
1036
+ .knobs-seed-read{display:inline-flex;align-items:center}
1037
+ .knobs-seed-read[data-mixed]::before{content:"—"}
1038
+ .knobs-seed-read[data-mixed]>.knobs-seed-digits{display:none}
1039
+ .knobs-panel .knobs-seed-roll{flex:none;width:var(--k-icon-btn);height:var(--k-icon-btn);padding:0;display:inline-flex;align-items:center;justify-content:center;background:transparent;border-radius:var(--k-round);color:var(--k-dim);cursor:pointer;transition:background .15s,color .15s}
1040
+ .knobs-panel .knobs-seed-roll:hover{background:var(--k-surface-hi);color:var(--k-text)}
1041
+ .knobs-seed-roll .knobs-die-icon{width:var(--k-icon-sm);height:var(--k-icon-sm)}
1042
+
1043
+ .knobs-panel .knobs-keys{flex:none;display:inline-flex;align-items:center;max-width:62%;height:var(--kc-control-h);padding:0 8px;background:var(--k-seg-bg);border-radius:var(--k-radius-md);color:var(--k-text);font-size:var(--kc-value-size);letter-spacing:.08em;white-space:nowrap;cursor:pointer;transition:background .15s,color .15s,box-shadow .15s}
1044
+ .knobs-panel .knobs-keys:is(:hover,:focus-visible){background:color-mix(in srgb,var(--k-surface-hi) 70%,var(--k-seg-bg))}
1045
+ .knobs-panel .knobs-keys[data-empty]{color:var(--k-dim);letter-spacing:0}
1046
+ .knobs-panel .knobs-keys[aria-pressed="true"]{background:var(--k-pill-bg);box-shadow:inset 0 0 0 1px var(--k-pill-border);color:var(--k-label);letter-spacing:.08em}
1047
+ .knobs-keys-text{min-width:0;overflow:hidden;text-overflow:ellipsis}
1048
+
1049
+ /* Toolbars: icon, label and shortcut per button; they wrap. Buttons take the button tokens. */
1050
+ .knobs-panel .knobs-row.knobs-toolbar{flex-wrap:wrap;justify-content:flex-start;gap:var(--k-tray-pad);height:auto;min-height:var(--k-row);padding:calc((var(--k-row) - var(--k-button-h,var(--kc-control-h))) / 2) var(--k-inset)}
1051
+ .knobs-card>.knobs-toolbar:hover{background:transparent}
1052
+ .knobs-card>.knobs-toolbar:has(:focus-visible)::after{opacity:0}
1053
+ .knobs-panel .knobs-tool{display:inline-flex;align-items:center;gap:6px;height:var(--k-button-h,var(--kc-control-h));padding:0 8px;background:var(--k-button-bg,var(--k-seg-bg));border-radius:var(--k-button-radius,var(--k-radius-md));box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);
1054
+ color:var(--k-button-color,var(--k-label));font-size:var(--k-button-font-size,var(--k-text-control));font-weight:var(--k-label-weight);white-space:nowrap;cursor:pointer;transition:background var(--k-hover-t),color .15s,box-shadow .15s,scale .12s var(--k-ease),opacity .15s}
1055
+ .knobs-panel .knobs-tool:is(:hover:not([disabled]),:focus-visible){background:var(--k-button-hover-bg,var(--k-surface-hi));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent));color:var(--k-text)}
1056
+ .knobs-panel .knobs-tool:is(:active:not([disabled]),.knobs-pressed){scale:.96}
1057
+ .knobs-panel .knobs-tool[disabled]{opacity:var(--k-disabled-opacity);cursor:default}
1058
+ .knobs-tool .knobs-icon{width:var(--k-icon-sm);height:var(--k-icon-sm)}
1059
+ .knobs-panel .knobs-tool-key{font:inherit;font-size:var(--k-text-cap);color:var(--k-dim);letter-spacing:.06em}
1060
+ .knobs-panel :is([data-disabled],[data-readonly]) :is(.knobs-cell,.knobs-range-track,.knobs-angle,.knobs-dial,.knobs-seed,.knobs-keys,.knobs-tool){cursor:default}
1061
+
1062
+ /* Row accessories (rowAccessory): the host's node, just after the label. */
1063
+ .knobs-accessory{display:inline-flex;align-items:center;gap:var(--k-tray-pad);flex:none;min-width:0;color:var(--k-label)}
1064
+ .knobs-accessory:empty{display:none}
1065
+ .knobs-panel .knobs-row:where(:not(.knobs-slider,.knobs-x,.knobs-spring))>.knobs-accessory{margin:0 auto 0 -4px}
1066
+ .knobs-track>.knobs-accessory{position:absolute;top:0;bottom:0;left:calc(var(--k-label-right,0px) + 4px);z-index:1}
1067
+ .knobs-x-head>.knobs-accessory{margin:0 auto 0 -4px}
1068
+ .knobs-action-row>.knobs-accessory{position:absolute;top:0;bottom:0;right:var(--k-inset)}
1069
+
1070
+ /* Foldable groups (folded / groupFolded): the header toggles its card. */
1071
+ .knobs-panel .knobs-group-head[data-foldable]{cursor:pointer;user-select:none;transition:background var(--k-hover-t)}
1072
+ .knobs-panel .knobs-group-head[data-foldable]:focus-visible{background:var(--k-surface)}
1073
+ .knobs-group-head>span:last-child>.knobs-caret{margin:0 5px 0 3px}
1074
+ .knobs-group-head[aria-expanded="true"] .knobs-caret{transform:rotate(90deg)}
1075
+ .knobs-group-head[data-foldable]:hover .knobs-caret{color:var(--k-label)}
1076
+
1077
+ /* A choice row: the label keeps its words and the value takes the rest, truncating at its end
1078
+ (the whole value is in the menu and the button's tooltip); choice.ts sets how far the label may
1079
+ go (--k-label-cap, at least half the row) and how far an accessory lies over its end. */
1080
+ .knobs-panel .knobs-row:is([data-display="menu"],[data-display="segmented"])>span:first-child{flex:0 0 auto;max-width:var(--k-label-cap,50%)}
1081
+ .knobs-panel .knobs-row:is([data-display="menu"],[data-display="segmented"])>.knobs-accessory{margin-left:calc(-4px - var(--k-acc-over,0px))}
1082
+ .knobs-panel .knobs-row[data-acc-over]>span:first-child{mask:linear-gradient(to left,transparent var(--k-acc-over),#000 calc(var(--k-acc-over) + 6px)) 0 0/calc(100% + var(--k-acc-over) + 6px) 100% no-repeat;transition:mask-position var(--k-hover-t)}
1083
+ .knobs-panel .knobs-row[data-acc-over]:is(:hover,:focus-within)>span:first-child{mask-position:100% 0}
1084
+ .knobs-panel .knobs-row[data-display="segmented"]>.knobs-seg{flex:0 1 auto;min-width:0}
1085
+ .knobs-panel .knobs-row[data-display="menu"]>.knobs-select{flex:0 1 auto;max-width:none}
1086
+
1087
+ /* A different item landing: values are placed, nothing glides. */
1088
+ .knobs-panel[data-landing] :is(*,*::before,*::after){transition:none!important}
1089
+
1090
+ /* Hint mode: stable short codes, zero layout shift */
1091
+ .knobs-hinting .knobs-hint-miss{opacity:var(--k-disabled-opacity);transition:opacity .1s}
1092
+ .knobs-hint-layer{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;z-index:5;animation:knobs-in .1s var(--k-ease)}
1093
+ .knobs-hint{position:absolute;transform:translateY(-50%);display:inline-flex;align-items:center;height:15px;padding:0 4px;border-radius:var(--k-radius-sm);background:var(--k-accent);color:var(--k-bg);box-shadow:0 1px 3px rgba(0,0,0,calc(.35 * var(--k-lift)));
1094
+ font:700 var(--k-text-cap)/1 var(--k-mono);letter-spacing:.04em;text-transform:uppercase;pointer-events:none}
1095
+ .knobs-hint-typed{opacity:var(--k-hint-typed-opacity)}
1096
+ .knobs-hint-rest{opacity:1}
1097
+
1098
+ /* Custom actions */
1099
+ .knobs-panel .knobs-custom-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:var(--k-gap);margin-top:var(--k-section-gap)}
1100
+ .knobs-panel .knobs-custom-actions button{height:var(--k-button-h,var(--k-action-h));min-height:24px;padding:0 8px;font-size:var(--k-button-font-size,var(--k-text-control));font-weight:var(--k-label-weight);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--k-button-color,var(--k-label));cursor:pointer;
1101
+ background:var(--k-button-bg,var(--k-surface));border-radius:var(--k-button-radius,var(--k-radius));box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);transition:background .15s,color .15s,opacity .15s,transform .12s,box-shadow .15s}
1102
+ .knobs-panel .knobs-custom-actions button:is(:hover:not([disabled]),:focus-visible){background:var(--k-button-hover-bg,var(--k-surface-hi));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent));color:var(--k-text)}
1103
+ .knobs-panel .knobs-custom-actions button:active:not([disabled]){transform:scale(.97)}
1104
+ .knobs-panel .knobs-tile-body>.knobs-custom-actions button[disabled]{opacity:var(--k-disabled-opacity);cursor:default}
1105
+
1106
+ /* Variants Disclosure Drawer */
1107
+ .knobs-transfer{display:grid;grid-template-columns:1fr 1fr;gap:var(--k-gap);margin-top:8px;padding-top:8px;border-top:1px solid var(--k-line)}
1108
+ .knobs-transfer button{height:var(--k-button-h,24px);padding:0 8px;background:var(--k-button-bg,var(--k-surface));border-radius:var(--k-button-radius,var(--k-radius));box-shadow:inset 0 0 0 1px var(--k-button-line,transparent);font-size:var(--k-button-font-size,var(--k-text-meta));color:var(--k-button-color,var(--k-label));cursor:pointer;transition:background .15s,color .15s,box-shadow .15s}
1109
+ .knobs-transfer button:is(:hover,:focus-visible){background:var(--k-button-hover-bg,var(--k-surface-hi));box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent));color:var(--k-text)}
1110
+
1111
+ /* Context menu: borrows its panel's tokens (see menu.ts) and floats above everything. */
1112
+ .knobs-menu{position:fixed;z-index:2147480004;min-width:176px;padding:var(--k-unit);box-sizing:border-box;font:var(--k-font-weight) var(--k-text-control)/1.35 var(--k-font);color:var(--k-text);text-align:left;-webkit-font-smoothing:antialiased;
1113
+ background:linear-gradient(var(--k-surface-hi),var(--k-surface-hi)),color-mix(in srgb,var(--k-bg) 90%,transparent);border:1px solid var(--k-line);border-radius:var(--k-radius);
1114
+ box-shadow:var(--k-shadow),inset 0 1px 0 var(--k-rim);-webkit-backdrop-filter:blur(20px) saturate(1.6);backdrop-filter:blur(20px) saturate(1.6);outline:none;user-select:none}
1115
+ .knobs-menu{max-width:min(480px,calc(100vw - 12px))}
1116
+ .knobs-menu-list{max-height:min(360px,calc(100dvh - 120px));overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin}
1117
+ .knobs-menu-item{position:relative;display:flex;align-items:center;justify-content:space-between;gap:24px;height:var(--kc-control-h);min-height:20px;padding:0 8px;border-radius:var(--k-radius-sm);cursor:default;white-space:nowrap;transition:background .08s}
1118
+ .knobs-menu-item>span{min-width:0;overflow:hidden;text-overflow:ellipsis}
1119
+ .knobs-menu-item[hidden]{display:none}
1120
+ /* The match shows by colour, not weight, so a filtered label keeps the width the menu measured. */
1121
+ .knobs-menu-item>span[data-marked]{color:var(--k-label)}
1122
+ .knobs-menu-item mark{background:none;color:var(--k-text)}
1123
+ .knobs-menu .knobs-menu-search{display:block;width:100%;height:var(--kc-control-h);min-height:22px;margin:0 0 var(--k-unit);padding:0 8px;border:0;border-radius:var(--k-radius-sm);background:var(--k-seg-bg);color:var(--k-text);font:inherit;outline:none;-webkit-appearance:none;appearance:none}
1124
+ .knobs-menu .knobs-menu-search::placeholder{color:var(--k-dim)}
1125
+ .knobs-menu .knobs-menu-search::-webkit-search-cancel-button{display:none}
1126
+ .knobs-menu [hidden]{display:none!important}
1127
+ .knobs-menu-empty{padding:0 8px;height:var(--kc-control-h);display:flex;align-items:center;color:var(--k-dim)}
1128
+ .knobs-menu-item[data-active]{background:color-mix(in srgb,var(--k-accent) 14%,transparent)}
1129
+ .knobs-menu-item[aria-disabled]{opacity:var(--k-disabled-opacity);color:var(--k-label)}
1130
+ .knobs-menu-item kbd{font:var(--k-text-cap)/1 var(--k-mono);font-variant-numeric:tabular-nums;color:var(--k-dim);letter-spacing:0}
1131
+ .knobs-menu-item[data-separated]{margin-top:calc(var(--k-unit) * 2 + 1px)}
1132
+ .knobs-menu-item[data-separated]::before{content:"";position:absolute;left:8px;right:8px;top:calc(var(--k-unit) * -1 - 1px);height:1px;transform:scaleY(.5);background:var(--k-line)}
1133
+
1134
+ /* Status & Transfer Textarea */
1135
+ .knobs-panel .knobs-status{margin:6px 0 0;padding:0 var(--k-inset);color:var(--k-label);font-size:var(--k-text-meta);overflow-wrap:anywhere}
1136
+
1137
+ .knobs-panel textarea{width:100%;min-height:84px;margin-top:6px;padding:6px var(--k-inset);resize:vertical;font:var(--k-text-meta)/1.4 var(--k-mono)}
1138
+ .knobs-panel .knobs-apply-btn{width:100%;height:26px;margin-top:var(--k-gap);font-size:var(--k-text-control);font-weight:500;color:var(--k-text);background:var(--k-surface-hi);cursor:pointer}
1139
+
1140
+ /* WebGPU Overlay Active Mirror State */
1141
+ .knobs-panel[data-gpu-active="true"]{background:transparent!important;border-color:transparent!important;box-shadow:none!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important}
1142
+ .knobs-panel[data-gpu-active="true"],.knobs-panel[data-gpu-active="true"] :where(*,:focus-visible):not(.knobs-live *,.knobs-search *){outline-color:transparent!important;box-shadow:none!important}
1143
+ .knobs-panel[data-gpu-active="true"] :where(header strong,header button,.knobs-tile,.knobs-section-head,.knobs-group-label,.knobs-peek,.knobs-card>*,.knobs-presets,.knobs-preset-chip,.knobs-group-head,.knobs-group-head button,.knobs-card,.knobs-row,.knobs-row>span:first-child,.knobs-slider,.knobs-track,.knobs-label,.knobs-value,.knobs-digits,.knobs-digits *,.knobs-unit,.knobs-seg,.knobs-seg button,.knobs-custom-actions button,.knobs-action,.knobs-select,.knobs-select-value,
1144
+ .knobs-sub,.knobs-x-head,.knobs-x-label,.knobs-x-read,.knobs-strip-label,.knobs-strip-read,.knobs-pad,.knobs-ease,.knobs-spring-curve,.knobs-ease-chips,.knobs-ease-chip,.knobs-graph,.knobs-graph-read,
1145
+ .knobs-tabs,.knobs-tab,.knobs-subhead,.knobs-subhead-label,.knobs-match,.knobs-cell,.knobs-cell-axis,.knobs-cell-read,.knobs-link,.knobs-range-read,.knobs-angle,.knobs-angle-read,.knobs-dial,
1146
+ .knobs-seed,.knobs-seed-read,.knobs-seed-digits,.knobs-seed-digits *,.knobs-seed-roll,.knobs-keys,.knobs-keys-text,.knobs-tool,.knobs-tool-label,.knobs-tool-key,
1147
+ .knobs-section-name,.knobs-section-summary,.knobs-section-desc,.knobs-group-desc,.knobs-group-summary,.knobs-tab-count):not(.knobs-live,.knobs-live *){
1148
+ background:transparent!important;color:transparent!important;border-color:transparent!important;box-shadow:none!important;
1149
+ }
1150
+ .knobs-panel[data-gpu-active="true"] :where(.knobs-seg-pill,.knobs-presets-pill,.knobs-fill,.knobs-notch,.knobs-handle,.knobs-marks i,.knobs-toggle,.knobs-toggle i,.knobs-hint,.knobs-icon,
1151
+ .knobs-swatch,.knobs-caret,.knobs-strip-track,.knobs-pad>i,.knobs-ease>svg,.knobs-ease-handle,.knobs-ease-mini,.knobs-spring-curve>*,
1152
+ .knobs-grad,.knobs-grad-mini,.knobs-graph>svg,.knobs-graph>i,.knobs-curve-mini,
1153
+ .knobs-tabs-bar,.knobs-range-fill,.knobs-range-smear,.knobs-range-thumb,.knobs-dial-hand):not(.knobs-live *,.knobs-search *),
1154
+ .knobs-panel[data-gpu-active="true"] :is(.knobs-tabs,.knobs-dial)::after,
1155
+ .knobs-panel[data-gpu-active="true"] .knobs-section-head::before,
1156
+ .knobs-panel[data-gpu-active="true"] :is(.knobs-sub,.knobs-x-head,.knobs-x-label)::before,
1157
+ .knobs-panel[data-gpu-active="true"] :is(.knobs-sub,.knobs-x-head,.knobs-x-label)::after,
1158
+ .knobs-panel[data-gpu-active="true"] .knobs-card:not(.knobs-live *)>::before,
1159
+ .knobs-panel[data-gpu-active="true"] .knobs-card:not(.knobs-live *)>::after,
1160
+ .knobs-panel[data-gpu-active="true"] .knobs-row:not(.knobs-live *)>span:first-child::after,
1161
+ .knobs-panel[data-gpu-active="true"] :is(.knobs-tile:not(.knobs-live)>.knobs-veil,.knobs-tile:not(.knobs-live)>.knobs-mark,.knobs-section-head>.knobs-mark){opacity:0!important}
1162
+ /* Parts the canvas doesn't draw (shortcuts, status, editors) sit above it. */
1163
+ .knobs-panel[data-gpu-active="true"] :where(.knobs-popover,.knobs-status,textarea,.knobs-apply-btn){position:relative;z-index:2147480003}
1164
+ .knobs-panel[data-gpu-active="true"] .knobs-number{z-index:2147480003}
1165
+ /* A row accessory is the host's own DOM, so it sits above the canvas too (its row then can't
1166
+ contain its layout, which would trap it in a stacking context under the canvas). */
1167
+ .knobs-panel[data-gpu-active="true"] .knobs-row[data-accessory]{contain:style}
1168
+ :where(.knobs-panel[data-gpu-active="true"] .knobs-row>.knobs-accessory){position:relative}
1169
+ .knobs-panel[data-gpu-active="true"] .knobs-row>.knobs-accessory{z-index:2147480003}
1170
+
1171
+ /* Page: sections of cards in balanced columns, under a sticky glass header. The page scrolls the
1172
+ window, so nothing here may become a scroll container or a containing block for the fixed
1173
+ popover and status. Custom cards (.knobs-live) are drawn by the DOM in both renderers. */
1174
+ .knobs-panel.knobs-page{width:auto;max-width:none;min-height:100dvh;padding:0 0 calc(var(--k-unit) * 16);border:0;border-radius:0;box-shadow:none;overflow:visible;background:var(--k-page);-webkit-backdrop-filter:none;backdrop-filter:none;
1175
+ --k-page-pad:calc(var(--k-unit) * 8);--k-page-gap:calc(var(--k-unit) * 4)}
1176
+ .knobs-panel.knobs-page[data-gpu-active="true"]{background:var(--k-page)!important}
1177
+ .knobs-panel.knobs-page>header{position:sticky;top:0;z-index:3;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(max-content,1fr);align-items:center;gap:var(--k-page-gap);min-height:calc(var(--k-row) + var(--k-unit) * 6);padding:calc(var(--k-unit) * 2.5) var(--k-page-pad);
1178
+ background:color-mix(in srgb,var(--k-page) 84%,transparent);-webkit-backdrop-filter:blur(24px) saturate(1.6);backdrop-filter:blur(24px) saturate(1.6);border-bottom:1px solid transparent;transition:border-color .2s}
1179
+ .knobs-panel.knobs-page>header[data-scrolled]{border-bottom-color:var(--k-line)}
1180
+ .knobs-panel.knobs-page>header strong{font-size:calc(var(--k-font-size) + 3px);letter-spacing:-.015em;padding-left:calc(var(--k-pad) + var(--k-inset) + 1px)}
1181
+ .knobs-page>header .knobs-presets{margin:0;min-width:0;max-width:min(640px,46vw)}
1182
+ .knobs-page>header .knobs-presets-track{display:flex;flex-wrap:wrap}
1183
+ .knobs-page>header .knobs-preset-chip{flex:0 0 var(--k-preset-min,58px)}
1184
+ .knobs-page-tools{display:flex;align-items:center;justify-content:flex-end;min-width:0}
1185
+ .knobs-page-tools .knobs-head-actions{margin-right:calc((var(--k-icon-size) - var(--k-icon-btn)) / 2 + var(--k-pad) + var(--k-inset) - var(--k-unit))}
1186
+ .knobs-panel.knobs-page>header[data-narrow]{grid-template-columns:minmax(0,1fr) auto;row-gap:calc(var(--k-unit) * 2)}
1187
+ .knobs-panel.knobs-page>header[data-narrow]>strong{grid-area:1/1}
1188
+ .knobs-panel.knobs-page>header[data-narrow] .knobs-page-tools{grid-area:1/2}
1189
+ .knobs-panel.knobs-page>header[data-narrow] .knobs-presets{grid-area:2/1/3/3;max-width:none}
1190
+ .knobs-page>header[data-narrow] .knobs-preset-chip{flex:1 0 var(--k-preset-min,58px)}
1191
+ @media(max-width:640px){
1192
+ .knobs-panel.knobs-page{--k-page-pad:calc(var(--k-unit) * 4)}
1193
+ .knobs-panel.knobs-page>header{grid-template-columns:minmax(0,1fr) auto;row-gap:calc(var(--k-unit) * 2)}
1194
+ .knobs-panel.knobs-page>header>strong{grid-area:1/1}
1195
+ .knobs-panel.knobs-page>header .knobs-page-tools{grid-area:1/2}
1196
+ .knobs-panel.knobs-page>header .knobs-presets{grid-area:2/1/3/3;max-width:none}
1197
+ .knobs-page>header .knobs-preset-chip{flex:1 0 var(--k-preset-min,58px)}
1198
+ }
1199
+ /* The jump strip (nav: true): a chip per section along the header's foot, the one in view
1200
+ underlined; it scrolls sideways when the chips don't fit. */
1201
+ .knobs-page>header>.knobs-nav{grid-column:1/-1;margin:0 calc(var(--k-page-pad) * -1) calc(var(--k-unit) * -2.5);padding:0 calc(var(--k-page-pad) + var(--k-pad) + var(--k-inset) + 1px);gap:calc(var(--k-unit) * 5);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain}
1202
+ .knobs-page>header>.knobs-nav::-webkit-scrollbar{display:none}
1203
+ .knobs-page>header>.knobs-nav::after{display:none}
1204
+ .knobs-panel.knobs-page>header>.knobs-nav .knobs-tab{display:inline-flex;align-items:center;width:auto;height:calc(var(--k-row) + var(--k-unit));padding:0;border-radius:0;font-size:var(--k-text-control);line-height:1.25;color:var(--k-label);background:transparent}
1205
+ .knobs-panel.knobs-page>header>.knobs-nav .knobs-tab:is(:hover,:focus-visible,[aria-selected="true"]){color:var(--k-text);background:transparent}
1206
+ .knobs-tab-count{margin-left:5px;font-size:var(--k-text-meta);font-weight:500;font-variant-numeric:tabular-nums;color:var(--k-modified)}
1207
+ .knobs-panel.knobs-page .knobs-page-tools .knobs-custom-actions{display:flex;gap:var(--k-tray-pad);margin:0 calc(var(--k-unit) * 2) 0 0}
1208
+ .knobs-panel.knobs-page .knobs-page-tools .knobs-custom-actions button{height:var(--k-icon-btn);min-height:0;padding:0 8px;background:transparent;border-radius:var(--k-round)}
1209
+ .knobs-panel .knobs-filter{width:0;height:var(--kc-control-h);padding:0;margin:0;opacity:0;pointer-events:none;background:var(--k-seg-bg);border-radius:var(--k-radius-md);font-size:var(--k-text-control);color:var(--k-text);-webkit-appearance:none;appearance:none;
1210
+ transition:width ${LEAD_T},padding ${LEAD_T},margin ${LEAD_T},opacity .18s}
1211
+ .knobs-panel .knobs-filter::-webkit-search-cancel-button{display:none}
1212
+ .knobs-panel .knobs-filter::placeholder{color:var(--k-dim)}
1213
+ .knobs-panel .knobs-filter[data-open]{width:min(200px,22vw);padding:0 10px;margin-right:calc(var(--k-unit) * 2);opacity:1;pointer-events:auto}
1214
+ .knobs-panel.knobs-page>.knobs-popover{position:fixed;z-index:2147480003;top:calc(var(--k-head-h,56px) + var(--k-unit) * 2);right:var(--k-page-pad);width:min(360px,calc(100vw - 32px));max-height:calc(100dvh - var(--k-head-h,56px) - 32px);overflow:auto;margin:0;padding:var(--k-pad) var(--k-inset);
1215
+ background:color-mix(in srgb,var(--k-bg) 94%,transparent);border-radius:var(--k-panel-radius);box-shadow:var(--k-shadow),inset 0 1px 0 var(--k-rim);-webkit-backdrop-filter:blur(24px) saturate(1.6);backdrop-filter:blur(24px) saturate(1.6)}
1216
+ .knobs-panel.knobs-page>.knobs-status{position:fixed;z-index:2147480003;left:50%;bottom:calc(var(--k-unit) * 6);translate:-50% 0;max-width:min(480px,80vw);margin:0;padding:calc(var(--k-unit) * 2) calc(var(--k-unit) * 3.5);
1217
+ background:var(--k-bg);border:1px solid var(--k-line);border-radius:var(--k-round);box-shadow:var(--k-shadow);color:var(--k-text)}
1218
+ .knobs-sections{padding:0 var(--k-page-pad);overflow-x:clip;overflow-anchor:none}
1219
+ .knobs-columns{display:grid;grid-template-columns:repeat(var(--k-cols,1),minmax(0,1fr));gap:var(--k-page-gap);align-items:start;padding-top:calc(var(--k-unit) * 3)}
1220
+ .knobs-column{display:flex;flex-direction:column;gap:var(--k-page-gap);min-width:0}
1221
+ .knobs-section-head{margin:0 0 calc(var(--k-page-gap) * -.25);padding:0 calc(var(--k-pad) + var(--k-inset) + 1px);font:var(--k-title-weight) calc(var(--k-font-size) + 3px)/1.25 var(--k-font);letter-spacing:-.015em;color:var(--k-text);white-space:nowrap;
1222
+ display:grid;grid-template-columns:minmax(0,max-content) minmax(0,1fr) auto;align-items:center;column-gap:8px;isolation:isolate}
1223
+ .knobs-column>:not([hidden],[data-away])~.knobs-section-head{margin-top:calc(var(--k-page-gap) * .75)}
1224
+ .knobs-section-name{grid-area:1/1;min-width:0;overflow:hidden;text-overflow:ellipsis}
1225
+ /* A section that folds: its heading toggles it, its caret showing while it's hovered, focused or
1226
+ folded. Folded, the heading says what's in it and its cards wait out of the flow. */
1227
+ .knobs-tile[data-away]{display:none}
1228
+ .knobs-section-head[data-foldable]{cursor:pointer;user-select:none}
1229
+ .knobs-section-head[data-folded]{margin-bottom:0}
1230
+ .knobs-section-head[data-foldable]::before{content:"";position:absolute;z-index:-1;inset:-4px 0;border-radius:var(--k-radius-md);background:var(--k-surface);opacity:0;transition:opacity var(--k-hover-t)}
1231
+ .knobs-section-head[data-foldable]:focus-visible{outline:none}
1232
+ .knobs-section-head[data-foldable]:focus-visible::before{opacity:1}
1233
+ .knobs-section-head>.knobs-caret{grid-area:1/3;margin:0 calc((var(--k-icon-sm) - 20px) / 2 + 5px) 0 0;opacity:0;transition:transform ${LEAD_T},opacity .15s,color .15s}
1234
+ .knobs-section-head:is(:hover,:focus-visible,[data-folded])>.knobs-caret{opacity:1}
1235
+ .knobs-section-head:hover>.knobs-caret{color:var(--k-label)}
1236
+ .knobs-section-head[aria-expanded="true"]>.knobs-caret{transform:rotate(90deg)}
1237
+ .knobs-section-summary{display:none;grid-area:1/2;justify-self:end;min-width:0;overflow:hidden;text-overflow:ellipsis;font:500 var(--k-text-control)/1.25 var(--k-font);letter-spacing:0;color:var(--k-dim);font-variant-numeric:tabular-nums}
1238
+ .knobs-section-head[data-folded]>.knobs-section-summary{display:block;animation:knobs-fade .2s var(--k-ease) both}
1239
+ .knobs-section-desc,.knobs-group-desc{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--k-label-weight) var(--k-text-meta)/1.35 var(--k-font);letter-spacing:0;color:var(--k-dim);text-transform:none}
1240
+ .knobs-section-desc{grid-area:2/1/3/4;margin-top:1px}
1241
+ .knobs-group-desc{padding:0 var(--k-group-inset)}
1242
+ .knobs-tile>.knobs-group-desc{margin:calc(2px - var(--k-head-gap)) 0 var(--k-head-gap)}
1243
+ .knobs-tile:is([data-foldable],[data-collapsible])>.knobs-group-desc{margin:2px 0 0}
1244
+ @keyframes knobs-fade{from{opacity:0}}
1245
+ .knobs-tile{position:relative;min-width:0;padding:var(--k-pad);background:var(--k-bg);border:1px solid var(--k-line);border-radius:var(--k-panel-radius);box-shadow:inset 0 1px 0 var(--k-rim)}
1246
+ .knobs-tile>.knobs-card{margin:0}
1247
+ .knobs-tile[data-foldable]>.knobs-group-head{margin-bottom:0}
1248
+ .knobs-tile[data-foldable]>.knobs-card{margin-top:var(--k-head-gap)}
1249
+ /* A card's header is compact: as tall as its 20px controls, then a gap and a half before its rows. */
1250
+ .knobs-tile>.knobs-group-head{position:relative;margin:0 0 var(--k-head-gap);min-height:20px;color:var(--k-text);font-size:var(--k-text-title);font-weight:var(--k-title-weight);letter-spacing:-.01em;text-transform:none}
1251
+ .knobs-panel.knobs-page{--k-head-gap:calc(var(--k-gap) * 1.5)}
1252
+ /* The title wins the header's room: what's on the right (presets, a summary) gives way first. */
1253
+ .knobs-tile>.knobs-group-head>.knobs-group-title{flex:1 1 auto}
1254
+ .knobs-tile>.knobs-group-head>span:last-child{flex:0 1000 auto;min-width:0}
1255
+ .knobs-tile>.knobs-group-head :is(.knobs-group-reset,.knobs-group-die){flex:none}
1256
+ /* A folded card's header trades its controls (presets, reset, die) for a summary of the card. */
1257
+ .knobs-group-ctl{display:flex;align-items:center;gap:var(--k-tray-pad);min-width:0}
1258
+ .knobs-group-summary{display:none;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--k-dim);font-size:var(--k-text-control);font-weight:500;letter-spacing:0;font-variant-numeric:tabular-nums}
1259
+ .knobs-tile[data-folded]>.knobs-group-head .knobs-group-summary:not(:empty){display:block}
1260
+ .knobs-tile[data-folded]>.knobs-group-head .knobs-group-ctl{display:none}
1261
+ .knobs-tile[data-fold-motion]>.knobs-group-head :is(.knobs-group-summary,.knobs-group-ctl){animation:knobs-fade .2s var(--k-ease) both}
1262
+ /* A highlight (page.highlight): the rest dims under a veil of the page's colour (--k-page-dim at
1263
+ full), and what's highlighted on its own gets a dot in the gutter by its title. The veil and
1264
+ dot are written each frame on the panel spring (see page.ts). */
1265
+ .knobs-panel.knobs-page{--k-page-dim:.4}
1266
+ .knobs-veil{position:absolute;inset:-1px;z-index:1;border-radius:inherit;background:var(--k-page);pointer-events:none}
1267
+ .knobs-mark{position:absolute;top:50%;width:6px;height:6px;margin:-3px 0 0 -3px;border-radius:50%;background:var(--k-accent);pointer-events:none}
1268
+ .knobs-tile>.knobs-mark{z-index:2;top:calc(var(--k-pad) + 10px);left:calc((var(--k-pad) + var(--k-inset) + 1px) / 2 - 1px)}
1269
+ .knobs-section-head{position:relative}
1270
+ .knobs-section-head>.knobs-mark{left:calc((var(--k-pad) + var(--k-inset) + 1px) / 2)}
1271
+ .knobs-group-title{display:grid;flex:1;min-width:0}
1272
+ .knobs-group-title>*{grid-area:1/1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:opacity .15s}
1273
+ .knobs-peek{opacity:0;pointer-events:none}
1274
+ .knobs-group-head[data-peek] .knobs-group-label{opacity:0}
1275
+ .knobs-group-head[data-peek] .knobs-peek{opacity:1}
1276
+ .knobs-group-head .knobs-chips.knobs-seg{flex:none;height:20px;max-width:none;gap:0;margin-right:var(--k-unit)}
1277
+ .knobs-group-head .knobs-chips button{width:18px;height:100%;padding:0;font-size:var(--k-text-meta);font-weight:500;font-variant-numeric:tabular-nums;border-radius:var(--k-radius-sm);background:transparent}
1278
+ .knobs-group-head .knobs-chips button[aria-checked="true"]{color:var(--k-text)}
1279
+ /* Named presets: their names as segments beside the title, or a compact menu of them. */
1280
+ .knobs-group-presets{display:flex;align-items:center;flex:0 1 auto;min-width:0;margin-right:var(--k-unit)}
1281
+ .knobs-group-presets .knobs-seg{flex:none;height:20px;max-width:none;padding:var(--k-tray-pad)}
1282
+ .knobs-group-presets .knobs-seg button{height:100%;padding:0 6px;font-size:var(--k-text-meta);font-weight:500;background:transparent}
1283
+ .knobs-panel .knobs-group-presets .knobs-select{height:20px;max-width:11em;gap:3px;padding:0 3px 0 7px;font-size:var(--k-text-meta);font-weight:500;letter-spacing:0;text-transform:none}
1284
+ .knobs-group-presets .knobs-select[data-none]{color:var(--k-dim)}
1285
+ .knobs-group-presets .knobs-select .knobs-icon{width:calc(var(--k-icon-sm) - 3px);height:calc(var(--k-icon-sm) - 3px)}
1286
+ .knobs-tile-body{display:flex;flex-direction:column}
1287
+ .knobs-tile-body>.knobs-card{margin:0}
1288
+ .knobs-panel .knobs-tile-body>.knobs-custom-actions{position:relative;margin:0}
1289
+ .knobs-panel .knobs-tile-body>:not([hidden])~*{margin-top:var(--k-section-gap)}
1290
+ .knobs-row-full .knobs-seg{flex:1;max-width:none}
1291
+ .knobs-row-full .knobs-seg button{flex:1}
1292
+ .knobs-item[role="button"]{cursor:pointer}
1293
+ .knobs-card>.knobs-item:focus-visible{outline:none}
1294
+ .knobs-card>.knobs-item:focus-visible::after{opacity:1}
1295
+ /* A collapsible custom card: its header toggles it, with a caret and, while folded, a summary. */
1296
+ .knobs-live[data-collapsible]>.knobs-group-head{margin-bottom:0;cursor:pointer;border-radius:var(--k-radius-sm);transition:background var(--k-hover-t)}
1297
+ .knobs-live[data-collapsible]>.knobs-group-head:focus-visible{background:var(--k-surface)}
1298
+ .knobs-live[data-collapsible]>.knobs-tile-body{margin-top:var(--k-head-gap);transition:opacity var(--k-token-t)}
1299
+ .knobs-live[data-collapsed]>.knobs-tile-body{opacity:0}
1300
+ .knobs-live>.knobs-tile-body[data-folding]{position:absolute;left:var(--k-pad);right:var(--k-pad);margin-top:0}
1301
+ .knobs-card-right{display:flex;align-items:center;gap:6px;min-width:0}
1302
+ .knobs-card-side{display:grid;justify-items:end;min-width:0}
1303
+ .knobs-card-side>*{grid-area:1/1;min-width:0;max-width:100%;transition:opacity var(--k-token-t)}
1304
+ .knobs-card-summary{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--k-dim);font-size:var(--k-text-control);font-weight:500;letter-spacing:0;opacity:0;pointer-events:none}
1305
+ .knobs-live[data-collapsed] .knobs-card-summary{opacity:1;pointer-events:auto}
1306
+ .knobs-live[data-collapsed] .knobs-card-summary:not(:empty)~*{opacity:0;pointer-events:none}
1307
+ .knobs-card-right>.knobs-caret{margin-right:calc((var(--k-icon-sm) - 20px) / 2 + 5px)}
1308
+ .knobs-live>.knobs-group-head:hover .knobs-caret{color:var(--k-label)}
1309
+ .knobs-live>.knobs-group-head[aria-expanded="true"] .knobs-caret{transform:rotate(90deg)}
1310
+ .knobs-item-detail{flex:none;color:var(--k-dim);font-size:var(--k-text-control);font-variant-numeric:tabular-nums;white-space:nowrap}
1311
+ `;
1312
+ function injectPreset(doc, preset) {
1313
+ let content = presetCss(preset), existing = doc.querySelector(`style[data-knobs-preset="${preset.name}"]`);
1314
+ if (existing) {
1315
+ if (existing.textContent !== content)
1316
+ existing.textContent = content;
1317
+ return;
1318
+ }
1319
+ let style = doc.createElement("style");
1320
+ style.dataset.knobsPreset = preset.name, style.textContent = content, doc.head.append(style);
1321
+ }
1322
+ var keyboardQuietsHover = (css) => css.replaceAll(":hover", ":hover:where(:not([data-k-quiet]))"), withoutHas = (css) => css.replaceAll(".knobs-x:has(>.knobs-x-head:is(:hover,:focus-visible))", '.knobs-x:is([data-k-head-hover]:where(:not([data-k-quiet])),[data-k-fv="head"])').replaceAll(":has(:focus-visible)", "[data-k-fv]").replaceAll(":has(.knobs-track:focus-visible)", '[data-k-fv="track"]').replaceAll(":has(.knobs-active)", "[data-k-active]");
1323
+ function injectStyles(doc) {
1324
+ let content = rolling_css_default + DRIVERS + defaultsCss + keyboardQuietsHover(withoutHas(aliased(css))), existing = doc.querySelector("style[data-knobs-style]");
1325
+ if (existing) {
1326
+ if (existing.textContent !== content)
1327
+ existing.textContent = content;
1328
+ return;
1329
+ }
1330
+ let style = doc.createElement("style");
1331
+ style.dataset.knobsStyle = "", style.textContent = content, doc.head.append(style);
1332
+ }
1333
+
1334
+ export { CHECK_POINTS, CHECK_PATH, iconPath, iconSvg, readSession, writeSession, presetCss, FILL, LEAD, trailScale, Edges, POP_MS, popScale, VelocityTracker, clamp, Roll, rollTarget, numeral, entranceOffset, DELAYED, injectPreset, injectStyles };